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:
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.