> Is there any one using CVtypes.py, created by G. Bishop, based on ctypes?
I was, but have since switched over the ctypes-opencv package, which
was originally based on CVtypes, but has been extended quite a bit,
especially with respect to data structures and memory management.
But I believe the answer is similar for either package, which is you
need to convert your data into a C-compatible data block:
> I have a usual pyhton list
First thing to remember is that, under the covers this is actually a
Python structure that is an internal array of python objects (which
happen to be integers). So this structure has no actual compact
memory block holding nothing but the numeric values, as would an
> I want to conver it to CvMat:
> I write
> import CVtypes as cv
This can't work, since as noted above, there's no raw memory block for
OpenCV to reference that will yield the numeric values. Taking a
pointer of the list isn't going to help either since all you get is
one level of indirection still to the wrong sort of data.
As long as you are starting with a Python data structure, I can't
really think of any method to assign the data in a single step that
doesn't involve creating an appropriate memory block that contains the
true values. If memory usage would be a problem, you could avoid that
by walking the Python list and assigning the matrix individually (with
something like cvSetReal2D) but if memory is an issue, the scale if
probably such that iterating over the list would be a performance
But something like this would work:
>>> from CVtypes import *
>>> from ctypes import c_float
>>> src = [1,2,23,1,12,1]
>>> data = (c_float * len(src))(*src)
<__main__.c_float_Array_6 object at 0x009DF5D0>
>>> xy = cvCreateMatHeader(len(src)/2, 2, CV_32FC1)
>>> cvSetData(xy, data, CV_AUTOSTEP)
<ctypes.LP_CvMat object at 0x009DFDF0>
The use of "c_float * len" creates an array data type of the right
length. You need to match the expected data type (e.g., "c_float" to
match your array type of 32F - you would use c_byte for an 8U matrix).
Creating an instance of that type creates an array, whose contents are
set during construction by passing in the list contents.
Note that if you use cvSetData as above, you have to keep the "data"
reference around to ensure the ctypes object (and thus the underlying
buffer) stays alive, since SetData just points to your data block.
One note - the ctypes-opencv package does define a helper function
"as_c_array" which essentially creates the same array
>>> from opencv import *
>>> as_c_array(src, elem_ctype=c_float)
<__main__.c_float_Array_6 object at 0x009DFE90>
Also, if you use the cvMat constructor with ctypes-opencv in lieu of
the CreateMatHeader/SetData combination, as in:
>>> xy = cvMat(len(src)/2, 2, CV_32FC1, data)
then ctypes-opencv will automatically hold a reference to the data
object for you.