I'm working with OpenCV for the first time and I'm a little bit confused with data types. I am working with Python.
I see that I can store an image as:
Numpy array
CvMat
Iplimage
The problem I'm having is that different parts of OpenCV seem to require different types and I keep having to try and convert back and forth- it's very confusing, and I'm certain it can't have been designed this way on purpose. I'm also a bit confused about when something should be in the cv module vs cv2.cv:
import cv
import cv2.cv
Can someone explain the logic? It would really help.
Thanks!
cv (or, cv2.cv)
is the old opencv python api, using IplImage and CvMat.
you should not use that anymore. it's being phased out, and won't be available in the next version.
cv2 is the new python api, using numpy arrays for almost anything instead,
so easy to combine with scipy, matplotlib and what not. (and , btw, much closer the the current c++ api)
Related
I'm trying to estimate transform for some images and stitch them using stitcher.estimateTransform() and stitcher.composePanorama() in python. After estimating transform, composePanorama gives the error as below:
pano is not a numpy array, neither a scalar
I tried to convert NumPy Array into a Mat object using cv2.fromarray(left), but it only works for cv, not cv2. Therefore how can I convert this numpy to MAT array in cv2. I don't find any examples of using composePanorama with python bindings. Any solution for this error or example of using stitcher.estimateTransform() with OpenCV-Python bindings would be appreciated.
Note: Although Stitching class in OpenCV-Python bindings is not complete (beacuse of auto-generated bindings), help(cv2.createStitcher()) demonstrates that it contains composePanorama() and estimateTransform().
Note: I can use stitcher.stitch() without any problems, but using stitcher.stitch() does not help me, because I'm trying to not calculate the transform for each iteration in the main loop.
My simple code :
leftStream = cv2.VideoCapture(0)
rightStream = cv2.VideoCapture(1)
left = leftStream.read()[1]
right = rightStream.read()[1]
st = cv2.createStitcher(False)
st.estimateTransform([left, right])
st.composePanorama([left, right])
To use stitcher.estimateTransform() and stitcher.composePanorama() you will need to
Download opencv https://github.com/opencv/opencv
navigate to opencv-master/modules/stitching/include/opencv2/stitching.hpp
add CV_WRAP in front of any methods you want to be able to call in Python. In this case those would be estimateTransform and composePanorama
Then to build the python module:
cd ~/opencv
mkdir build
cd build
cmake ../
make
sudo make install
Then move the module to your virtual environment from wherever it was installed to. In my case that was /usr/local/lib/python3.7/site-packages/cv2.
See https://www.pyimagesearch.com/2018/08/17/install-opencv-4-on-macos/ and https://docs.opencv.org/4.1.0/da/d49/tutorial_py_bindings_basics.html and https://docs.opencv.org/4.1.1/da/df6/tutorial_py_table_of_contents_setup.html for more info.
I have the same problem. From what I can see, composePanorama has two overloads.
CV_WRAP Status composePanorama(OutputArray pano);
Status composePanorama(InputArrayOfArrays images, OutputArray pano);
It's the second overload that we need, as the pano is an output parameter, which in Python is given as a return value. Unfortunately, the second overload is not marked by CV_WRAP which would make it available to the Python bindings. So the only solutions I can see are:
Use an alternative stitching implementation
Go through the C++ code of the missing composePanorama implementation and reimplement it yourself in Python
Register an issue on the Open CV Github and wait for an update
Build Open CV yourself from source and mark the function as CV_WRAP (I'm not sure it is actually as simple as that)
Work in C++ instead of Python
Although I'll be very happy if someone else can post an answer showing how to achieve this in Python without going through the complex tasks above.
Does anyone know of a method to make images picklable? I am trying to pass OpenCV images between processes to separate display from real-time processing of an OpenCV video. I have tried PIL Image.tostring(), but to no avail. Is there a standard technique?
This is what you are looking for: pickleable image object
Making it a dict and then using the information in the dict to recreate the image again. Hopefully this helps
OpenCV's newer cv2 module uses NumPy arrays, which are inherently pickleable. See my answer here: https://stackoverflow.com/a/17054961/1510289
Hello all,
I am working on a program which determines the average colony size of yeast from a photograph, and it is working fine with the .bmp images I tested it on. The program uses pygame, and might use PIL later.
However, the camera/software combo we use in my lab will only save 16-bit grayscale tiff's, and pygame does not seem to be able to recognize 16-bit tiff's, only 8-bit. I have been reading up for the last few hours on easy ways around this, but even the Python Imaging Library does not seem to be able to work with 16-bit .tiff's, I've tried and I get "IOError: cannot identify image file".
import Image
img = Image.open("01 WT mm.tif")
My ultimate goal is to have this program be user-friendly and easy to install, so I'm trying to avoid adding additional modules or requiring people to install ImageMagick or something.
Does anyone know a simple workaround to this problem using freeware or pure python? I don't know too much about images: bit-depth manipulation is out of my scope. But I am fairly sure that I don't need all 16 bits, and that probably only around 8 actually have real data anyway. In fact, I once used ImageMagick to try to convert them, and this resulted in an all-white image: I've since read that I should use the command "-auto-levels" because the data does not actually encompass the 16-bit range.
I greatly appreciate your help, and apologize for my lack of knowledge.
P.S.: Does anyone have any tips on how to make my Python program easy for non-programmers to install? Is there a way, for example, to somehow bundle it with Python and pygame so it's only one install? Can this be done for both Windows and Mac? Thank you.
EDIT: I tried to open it in GIMP, and got 3 errors:
1) Incorrect count for field "DateTime" (27, expecting 20); tag trimmed
2) Sorry, can not handle images with 12-bit samples
3) Unsupported layout, no RGBA loader
What does this mean and how do I fit it?
py2exe is the way to go for packaging up your application if you are on a windows system.
Regarding the 16bit tiff issue:
This example http://ubuntuforums.org/showthread.php?t=1483265 shows how to convert for display using PIL.
Now for the unasked portion question: When doing image analysis, you want to maintain the highest dynamic range possible for as long as possible in your image manipulations - you lose less information that way. As you may or may not be aware, PIL provides you with many filters/transforms that would allow you enhance the contrast of an image, even out light levels, or perform edge detection. A future direction you might want to consider is displaying the original image (scaled to 8 bit of course) along side a scaled image that has been processed for edge detection.
Check out http://code.google.com/p/pyimp/wiki/screenshots for some more examples and sample code.
I would look at pylibtiff, which has a pure python tiff reader.
For bundling, your best bet is probably py2exe and py2app.
This is actually a 2 part question:
1) 16 bit image data mangling for Python - I usually use GDAL + Numpy. This might be a bit too much for your requirements, you can use PIL + Numpy instead.
2) Release engineering Python apps can get messy. Depending on how complex your app is you can get away with py2deb, py2app and py2exe. Learning distutils will help too.
Me and a friend are working on an openGL game written in python, using the pyglet library.
Now we finished the map drawing code, and have come to a point where we need to import some models that will be displayed on the map. Pyglet doesn't seem to support it, apart from some old SVN code, apparently (I googled a bit around with not much luck). Does anyone know a good python script/library that can import 3D models?
Open Asset Import Library (Assimp) supports ~35 different 3D file formats.
It has python bindings in its repository, but I don't know for sure if they're up-to-date and feature-complete. Still, assimp might be worth a try (even though I am not unbiased since i'm one of its founders).
There are 3D models and 3D models. The ease of import will depend on the complexity of the model and which format you have the model data in. Blender includes several python scripts to import model data into blender specific mesh, and export to other formats. You can look there for inspiration.
I'm working on a Python tool to convert image data into these color formats:
RGB565
RGBA5551
RGBA4444.
What's the simplest way to achieve this?
I've used the Python Imaging Library (PIL) frequently. So I know how to load an image and obtain each pixel value in RGBA8888 format. And I know how to write all the conversion code manually from that point.
Is there an easier way? Perhaps some type of 'formatter' plugin for PIL?
Does PIL already support some of the formats I'm targeting? I can't ever figure out which formats PIL really supports without digging though all of the source code.
Or is there a better library than PIL to accomplish this in Python?
Any tips would be appreciated. Thanks!
Changing something from 8 to 5 bits is trivial. In 8 bits the value is between 0 and 255, in 5 bits it's between 0 and 31, so all you need to do is divide the value with 8. Or 4 in the case for green in RGB565 mode. Or 16 in RGBA4444 mode as it uses 4 bits per channel, etc.
Edit: Reading through your question again, I think there is a confusion (either with me or you). RGB555 and RGBA4444 etc are not really formats, like GIF or JPG, they are color spaces. That conversion is trivial (see above). What file format you want to save it in later is another question. Most file formats have limited support for color spaces. I think for example that JPEG always saves it in YCbCr (but I could be mistaken), GIF uses a palette (which in turn always is RGB888, I think) etc.
There's a module called Python Colormath which provides a lot of different conversions. Highly recommended.
Numpy is powerful indeed, but to get there and back to PIL requires two memory copies. Have you tried something along the following lines?
im = Image.open('yourimage.png')
im.putdata([yourfunction(r,g,b) for (r,g,b) in im.getdata()])
This is quite fast (especially when you can use a lookup table). I am not familiar with the colour spaces you mention, but as I understand you know the conversion so implementation of yourfunction(r,g,b) should be straight forward.
Also im.convert('RGBA', matrix) might be very powerful as it is super fast in applying a colour transformation through the supplied matrix. However I have never gotten that to do what I wanted it to do... :-/
There is also a module named Grapefruit that let you do conversions between quite a lot of color formats.
I ended up doing the conversions manually as Lennart Regebro suggested.
However, pure Python (iterating over each pixel) turned out to be too slow.
My final solution used PIL to load the image and numpy to operate on (convert) an array of pixels.