Few days ago I went into searching for a good way to make a simple computer vision system. OpenCV library is something I need but it proved hard to learn with Python especially after OpenCV 2.4.3 update which have very slim Python related documentation. So I now understand that there was a bunch of changes in OpenCV, for exaxmple
import cv
is now
import cv2
And there is bunch of modules that is missing. I mean, yes there are examples of the new python-opencv syntax but it's very narrow and proven to be hard to understand.
For example:
Example in official documentation for Python code
cv2.cvtColor(src, code[, dst[, dstCn]])
I know what this code means and how to use it, at least I think i know. But writing source and color code does nothing just give me :
Traceback (most recent call last):
File "C:\FILEFOLDER\tut.py", line 11, in <module>
cv.cvtColor('proba.jpg', 'CV_RGB2GRAY')
TypeError: an integer is required
Or if i try to write code like variable:
Traceback (most recent call last):
File "C:\FILEFOLDER\tut.py", line 11, in <module>
cv.cvtColor('proba.jpg', CV_RGB2GRAY)
NameError: name 'CV_RGB2GRAY' is not defined
So is there any Python related reference document/tutorial/book/guide for newest OpenCV with the ground up explanations that does not confuse newbie like me with unwanted code examples for C++ or Java?
I think you are taking it in the reverse path.
Actually, with the new cv2 module, OpenCV has become far more simple compared to old cv interface. Not just simple, but very fast and highly productive, due to the Numpy support. Only thing is that, we should know how to use it appropriately.
Here, you should use the function as follows :
img = cv2.imread('pic.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
I would like you to visit one SOF which shows some comparison between both the modules : What is different between all these OpenCV Python interfaces?
Another one SOF is here, which is a simple demonstration on how you can speed up the code with Numpy support : Performance comparison of OpenCV-Python interfaces, cv and cv2
You need not learn C++ or C to use OpenCV, although C++ is the official language. Still, Python-OpenCV has good support. Once you get a grip on how to use OpenCV, you will be able to convert C++ codes into Python yourself. Then you can learn OpenCV from C++ tutorials also. For example, I started learning OpenCV from "Learning OpenCV" by Gary Bradsky which is completely in C++. At that time, there was only cv interface.
As you mentioned in your comments, opencvpython.blogspot.com has some introductory tutorials. I started it focussing newbies in OpenCV.
Also, check this SOF for more tutorials : Books for OpenCV and Python?
To take it from another angle and allow you to run older code with new OpenCV installation versions...
First off the move from cv to cv2 has to do with the library using different data structures for a lot of functions. The easiest way to tell if a function has changed between cv2 and cv is that cv functions start with a capital. Reworked cv2 functions seem to always have the first letter in lowercase. So if you are using an old book or old examples, you can still use the legacy cv. cv is now simply embedded in cv2. Simply use the following at the top of your scripts
import cv2
import cv2.cv as cv #required for old code not to be changed
This allows you to simply run older code without changing it. I will demonstrate with your function call here. You had...
cv.cvtColor('proba.jpg', 'CV_RGB2GRAY')
The first thing I notice is that your function may be called wrong. (Given first letter of function is lower case it should start with cv2 not cv). Second is the 'code' you are passing the function. 'Codes' are members (coding noob here, forgive me if some of my vocab is inaccurate) of cv2 and cv but not always the same. You have 'CV_RGB2GRAY'. First off, no quotes. This is a cv 'code' not cv2. Also you are missing the 'cv.' in front. To demonstrate here is how I believe your function should be called for old cv version:
cv.CvtColor('proba.jpg', cv.CV_RGB2GRAY) #Assuming you used listed imports
cv2.cv.CvtColor('proba.jpg', cv2.cv.CV_RGB2GRAY) #Assuming you skipped second import
And now cv2...
cv2.cvtColor('proba.jpg', cv2.COLOR_RGB2GRAY)
There you go, I hope this helps. Remember that given python runs off of scripts you can type anything you are unsure of directly into command line. This does wonders for helping me build my understanding (I first used python 5 days ago). For example if you were wondering why it wanted an integer in your function, when you type
cv.CV_RGB2GRAY
directly into the python command line, it spits '7' (handy that it is an int) back at you. The cv2 version spits out '7L'. Just remember to use the WaitKey() function now and again in some form otherwise highgui may not have the required time to process some commands, in some situations. Well that wraps it up. Sorry if I covered some things that were already covered or referenced to. If I did feel free to delete it, admins.
Related
I inherited an application with opencv, shiboken and pyside and my first task was to update to qt6, pyside6 and opencv 4.5.5. This has gone well so far, I can import the module and make class instances etc. However I have a crash when passing numpy arrays:
I am passing images in the form of numpy arrays through python to opencv and I am using pyopencv_to to convert from the array to cv::Mat. This worked in a previous version of opencv (4.5.3), but with 4.5.5 it seems to be broken.
When I try to pass an array through pyopencv_to, I get the exception opencv_ARRAY_API was nullptr. My predecessor solved this by directly calling PyInit_cv2(), which was apparently previously included via a header. But I cannot find any header in the git under the tag 4.5.3 that defines this function. Is this a file that is generated? I can see there is a pycompat.hpp, but that does not include the function either.
Is there a canonical way to initialize everything so that numpy arrays can be passed properly? Or a tutorial anyone can point me to? My searches have so far not produced any useful hints.
Thanks a lot in advance! :)
I finally found a solution. I dont know if this is the correct way of doing it, but it works.
I made a header file that contains
PyMODINIT_FUNC PyInit_cv2();
as a forward declaration and then copied over everything in the modules/python/src2 directory. I assumed this was already happening in the cv2.cpp file, because there is already exactly that line (in cv2.cpp).
But just adding that include works perfectly fine, apparently. Now I can call the init function when my own module is initialized and it seems to properly set all the needed state.
OK, prerequisites:
It's my first ever Python project. I used to do some scripting but never anything bigger
So I'm at the very beginning of a learning curve. It's like when you can't kill an ant in Fallout 2 Temple level. On later levels, I was really good in Fall 2:)
Problem:
I can't figure out how to import a module written by me and placed in a different folder
Context:
The project I'm intended to create is meant to do a lot of measures conversions. So I decided to store in DB all data in the same unit system & keep all conversions upon user preferences on a codebase level
In a different folder I decided to store tests. To write the very first one (testing the abovementioned module) I need to import the module, but here is the story begins. I know it's classic, but I'm completely messed with import
Toolkit:
PyCharm Pro (PyCharm 2021.3.1)
Python 3.7 interpreter
macOS 10.15, Intell
Set up:
Settings screenshot provided
Project structure. Folders are marked as Source & Test
I need to import from conversions.py to test_conversions.py
PYTHONPATH settings like this
What do I, for the sake of God, need:
with all the abovementioned, how do I import conversions.py to test_conversions.py or any other place of my project? I read a number of articles and it's getting me anywhere (contradictory, 2.x related, etc). I feel like I need a piece of more foundational info but as well I need a clear walkthrough, a code snippet to import bloody file, I really appreciate any kind of advice
imports are a bit tricky. The issue you have is where your python is looking for packages. I would discourage you to add to your PYTHONPATH a specific project but you could do that locally in your file.
A much easier way is just to launch your test file from the top directory.
In this case your import will just be import conversion.conversion
And then you can launch your test from the root folder with python -m tests.conversion.
In Pycharm you can use the interface to deal with that, see this link. But I like the python -m because it works from anywhere, not only inside Pycharm.
make a class inside a conversion.py, then you can import it from test_conversion.py.
conversion.py
class convert():
def km_to_mm(input):
output = input * 1000000
return output
then import it in test_conversion.py
input = 0.001 # specify your input value
from conversion import convert
converted = convert().a_to_b(input)
converted will have value 1000
make sure you use the same folder. otherwise should use folder name to import. like
import foldername.conversion
from foldername.conversion import convert
I really appreciate all of you who tried to help. I got the problem solved in a very ridiculous manner, below is to someone who might face the same issue in the future.
So, in case you see the next:
You use PyCharm (no idea how other IDEs behave)
You created a module & want to import it into other files of your project
You type import module_name
While you type it, the string looks active and autocomplete even proposes you your module name but as only you finished typing, the import string turns grey, PyCharm throws you a warning saying Unused import statement, yellow bulb next to the import string suggests you delete the import string
--> This does not mean you are not able to import your module, it means you've done it and now can call anything from your module in the code below.
This taught me to pay some more time to read docs before jumping to using anything new and think better about UX in anything I do.
What is the underlying python code of numpy.correlate?
I am trying to understand the logic of cross correlation. the underlying python code will be of great help.
All the code is somewhere on your system, you just need to find where.
If you're using ipython, the help command (numpy.correlate?) includes the filepath (on the second line from the end).
On my system it's "/usr/local/lib/python3.5/dist-packages/numpy/core/numeric.py
"
If you're not using ipython, numpy.__file__ will give you a path to the installation directory for the module, and you'll have to look around a bit.
The module name given by help(numpy.correlate) will give some hints.
However, once you find the file you will see that numpy.correlate only does the following:
mode = _mode_from_name(mode)
return multiarray.correlate2(a, v, mode)
That is a compiled function, so it's a little harder to find.
You can view the file here, the main function is defined beginning on line 1353, and the actual algorithm begins on line 1190.
This is fairly optimized code, so it's doing quite a bit more than what is necessary for simple correlation: handling datatypes, multi-threading, and error handling.
If you just want to understand the general principles rather than specifics of what python is doing, I would recommend starting with a more basic explanation. Numeric operations such as correlation are very well defined, and numpy rarely does anything different from the standard definitions.
I have been using SimpleCV for find blobs to be used with a self-driving robot. The problem is when I call the findBlobs command in SimpleCV. When I completely block the lens of the Kinect Camera, PyGame crashes giving me this error:
Fatal Python error: (pygame parachute) Segmentation Fault
Sometimes it works and other times it just crashes, even when the lens is unblocked. It will almost always crash when i run it for longer than about thirty seconds.
I have re-installed and fixed many problems in SimpleCV and tried re-installing Pygame and it doesn't seem to help at all. Also, I am using the X-Box kinect as my camera source. I'm using Ubuntu 11.04.
Here is my exact code:
from SimpleCV import *
from SimpleCV.Display import *
from time import sleep
k = Kinect()
dis = Display()
while 1:
depth = k.getDepth()
depth = depth.invert()
depth = depth.erode()
blobs = depth.findBlobs(threshval=127, minsize=10, maxsize=0)
if blobs:
blobs.draw()
depth.save(dis)
sleep(0)
Kat here, I wrote the SimpleCV blob library.
There were a couple issues with the blob library that we found after we shipped the 1.1 release. The two big ones were that the blob library would hit the python max recursion depth and bail out. The second one stems from the actual underlying OpenCV wrapper and causes the pygame error when there are no blobs are detected by the blob maker.
The solution right now is to use the version that is in the master branch of our github repo. The patched version will also be available in the new SimpleCV 1.2 release which is slated for later this month. If you want to manually fix the code I have pasted the fixed snippet below:
In BlobMaker.py around line 55
def extractFromBinary(self,binaryImg,colorImg, minsize = 5, maxsize = -1):
#fix recursion limit bug
sys.setrecursionlimit(1000000)
if (maxsize <= 0):
maxsize = colorImg.width * colorImg.height
retVal = []
#fix all black image bug
test = binaryImg.meanColor()
if( test[0]==0.00 and test[1]==0.00 and test[2]==0.00):
return FeatureSet(retVal)
seq = cv.FindContours( binaryImg._getGrayscaleBitmap(), self.mMemStorage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
retVal = self._extractFromBinary(seq,False,colorImg,minsize,maxsize)
del seq
return FeatureSet(retVal)
Anthony one of the SimpleCV developers here:
Can you try changing the last line:
sleep(0.01)
Just to see if there is some type of issue going on where it can't process fast enough. I recently upgraded to Ubuntu 11.04 and I think there are a couple of python bugs I need to squash that popped up since 10.10.
Also if you could post this to our issue queue I would appreciate it:
http://github.com/ingenuitas/SimpleCV/issues
Fatal Python error: (pygame parachute) Segmentation Fault
This means that some code crashed, and now you need to debug it to find the problem. I assume you are learning something; might as well learn how to debug ;-)
Sometimes it works and other times it just crashes, even when the lens is unblocked. It will almost always crash when i run it for longer than about thirty seconds.
These are classic symptoms of heap corruption, or a data race.
I have re-installed and fixed many problems in SimpleCV and tried re-installing Pygame and it doesn't seem to help.
Why did you think it would? Your problem does not at all look like an installation problem.
So here is what you do: the tool for debugging heap corruption problems on Linux is valgrind. Run it like this:
valgrind python your-code.py
Unfortunately, default Python installation is not Valgrind-friendly, and above command will likely produce a lot of "uninitialized memory read" errors. You'll want to suppress most of them using this suppression file.
It may be possible to concentrate on errors that contain non-Python parts (and SimpleCV in particular). You are looking for invalid {read,write} ... N bytes after block ....
If you find such an error, you can try to debug it further with GDB, or report it to SimpleCV developers and hope for the best.
If you don't find the error, you can build a Valgrind-friendly version of Python (instructions), and try again.
If above run is Valgrind-clean, then you may have a race rather than heap corruption. Repeat with ThreadSanitizer.
Just replace your blob threshold with "-1"; I had the same problem and this fixed it.
I'm using Python 2.6 against OpenCV 2.0. I've started a file capture and pulled frames. I've displayed the image to make sure it's valid. When I call this routine, python crashes:
def SmoothImage(self,SmoothingMaskSize=3):
temp=cv.CreateImage(cv.GetSize(self._lpImage),self._lpImage.depth,self._lpImage.nChannels)
cv.Smooth(self._lpImage,temp)
self._lpImage=temp
I've also tried smoothing it in-place, using cv.Smooth(self._lpImage, self._lpImage)
I'm new to Python- am I missing something obvious?
Thanks!
The bindings that come with the OpenCV 2.0 installer are buggy; I had similar problem where some very simple operations triggered crashes. Compiling from the source should fix it.
If you don't need access to the object-oriented parts of OpenCV, you should take a look at ctypes-opencv, which is a better set of python bindings. It is lovingly hand-crafted, in contrast to the SWIG-generated bindings that come with OpenCV, and I have never found any bugs in it.
http://code.google.com/p/ctypes-opencv/
Can you isolate the problem by removing the class definition? I get this working:
planes = [cv.CreateImage(cv.GetSize(image), cv.IPL_DEPTH_32F, 1) for i in range(3)]
cv.Split(image, planes[0], planes[1], planes[2], None)
for plane in planes:
cv.Smooth(plane, plane, smoothtype=cv.CV_GAUSSIAN, param1=9, param2=0, param3=0, param4=0)