OpenCV numpy to cv::Mat conversion - python

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.

Related

Access different module versions

Imagine I use a pretty standard module, like numpy, and that I have a custom version locally.
Currently, I would store my custom numpy in a folder, say
.../MyPackages/
which I added to sys.path in second position (after ''). This way, any package that I use and which calls numpy, will use my numpy by default. When I don't want to use my numpy as default, I rename .../MyPackages/numpy to .../MyPackages/_numpy. This way, I can still call it manually with
import _numpy
if I want to, but it's not the default behaviour anymore.
This way of storing custom packages works pretty well for me so far, but doesn't allow me to call the usual numpy (not my custom version) without renaming the folder first, which is a bit heavy...
Is there a cleaner/better way to organize my packages to add this flexibility?
Thanks in advance.
_ I described above what I tried._

The location of source code for torch.mean()

I'm trying to find the source code for torch.mean and am unable to find it in the pytorch github. It is under math operations but I can't find it at all.
I've looked everywhere and inspected most pages under pytorch/torch and am still unable to find it.
I even did ?? in a jupyter notebook but it just returned a useless docstring
Since operations components are written in C++, they are not callable with operations such as ?? or "__file__" or "getsourcefile" type of operations.
The files appear to be here, written in C++:
https://github.com/pytorch/pytorch/blob/master/caffe2/operators/mean_op.cc
https://github.com/pytorch/pytorch/blob/master/caffe2/operators/mean_op.h

How to pickle a namespace in python

Is there a way to save and load an entire namespace using pickle allowing me to perform something like this:
import pickle
import numpy as np
a = 1
# other arbitrary code
pickle.dump(namespace,open('my_namespace.p','wb')
Allowing to open a new python prompt and performing the following code:
import pickle
namespace.update(pickle.load(open('my_namespace.p','rb'))
print(np.array(a)+1)
>>2
# using the rest of the namespace
If your intention is to 'freeze' a particular code version of the modules you use I suggest taking a look at Python Virtual Environment (venv). Otherwise, as jasonharper suggested - it is very unlikely to work well (particularly with modules like NumPy which are complex amalgamates of Python code and binary libraries).
venv would help you deal with that particular problem too.
I think that I get the question. You want to be able to restore all variables and interact with a shell in a different interpreter or at a different time. The easiest way to do this is probably to use a notebook like jupyter or ipython. These allow you to save all commands run and reconstitute them. Sorry for it not being a direct answer, but I think it may "equivalently accomplish" what you specified.

OpenCV 2.4.3 and Python

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.

Why does this use of Smooth cause Python to crash?

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)

Categories