简体   繁体   中英

Passing opencv read image to dll c++ function

I am having problems of reading pixel info from c++ function, I can read all other argument so I am sure that my connection are working. My python code are as follows

real_img = cv2.imread("215107.jpg", 0)
n=real_image.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8))
hllDll=WinDLL(name)
hllDll.transform(n,ctypes.c_int(myimage.shape[0]), ctypes.c_int(myimage.shape[1]), ctypes.c_int(angle))

I have also tried

src1 = real_image.ctypes.data_as(ctypes.c_char_p)
hllDll.transform(src1,ctypes.c_int(myimage.shape[0]), ctypes.c_int(myimage.shape[1]), ctypes.c_int(angle))

and

src2=ctypes.c_void_p(real_img.ctypes.data)
hllDll.transform(src2,ctypes.c_int(myimage.shape[0]), ctypes.c_int(myimage.shape[1]), ctypes.c_int(angle))

but failed and my c++ function is as follows:

unsigned int transform(int** a, int row,int col, int ang){
for (int i = 0; i < 4; i++) {
        cout << a[i] << endl;
    }
...}

When I try to read from a, they all just give me same huge numbers like

1212121212121212
1212121212121212
1413131211111010
1012141311101113

while they should be 18 for first 5 numbers if I access through python, I am so confused what made this happen

Edit: I also tried cout << a[i][1] << endl; But OSError: exception: access violation reading 0xFFFFFFFFFFFFFFFF returned

You are passing an array of type np.uint8 , the equivalent C pointer is unsigned char* .

Replace int** a with unsigned char* a .


For testing, you may fill the 4 first elements of real_image :

real_image[0, 0] = 1
real_image[0, 1] = 2
real_image[0, 2] = 3
real_image[0, 3] = 4

hllDll.transform(n,ctypes.c_int(real_image.shape[0]), ctypes.c_int(real_image.shape[1]), ctypes.c_int(angle))

Your C code may look as follows:

unsigned int transform(unsigned char* a, int row, int col, int ang){
    for (int i = 0; i < 4; i++) {
        cout << (int)a[i] << endl; // add [0] to access the first row
    }
}

The pointer unsigned char* a is not a pointer to two dimensional array, but a pointer to one dimensional array (in row major format).


For passing two dimensional NumPy array to C, you better add stride argument to your C function.
The stride is the number of bytes to step between two sequential rows.


For testing, you may fill the 4 first element of each row:

real_image[0, 0] = 1
real_image[1, 0] = 2
real_image[2, 0] = 3
real_image[3, 0] = 4

Your C code may look as follows:

unsigned int transform(unsigned char* a, int row, int col, int stride, int ang){
    //Print the first element of each one of the first 4 rows
    for (int i = 0; i < 4; i++) {
        cout << (int)a[i*stride] << endl;
    }
}

Note the new stride argument, and a[i*stride] .


Executing transform from Python:

hllDll.transform(n,ctypes.c_int(real_image.shape[0]), ctypes.c_int(real_image.shape[1]), ctypes.c_int(real_image.strides[0]), ctypes.c_int(angle))

Note:

  • It is most likely that col = stride , but it's not always the case.

You are printing the pointers for each rows. If you want to print elements of the first row, you should do like this:

unsigned int transform(int** a, int row,int col, int ang){
    for (int i = 0; i < 4; i++) {
        cout << a[0][i] << endl; // add [0] to access the first row
    }
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM