【问题标题】:Passing opencv read image to dll c++ function将opencv读取图像传递给dll c++函数
【发布时间】:2021-09-10 19:20:03
【问题描述】:

我在从 c++ 函数读取像素信息时遇到问题,我可以读取所有其他参数,因此我确信我的连接正常。 我的python代码如下

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))

我也试过

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))

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))

但失败了 而我的c++函数如下:

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

当我尝试从 a 中读取时,它们都会给我同样巨大的数字,例如

1212121212121212
1212121212121212
1413131211111010
1012141311101113

如果我通过 python 访问,前 5 个数字应该是 18,但我很困惑是什么导致了这种情况

编辑: 我也试过 cout OSError: exception: access violation reading 0xFFFFFFFFFFFFFFFF返回了

【问题讨论】:

  • real_imgreal_imagemyimage有什么区别?
  • 啊,对不起,它们是一回事。我忘了在这里改变它们。但不影响代码。@Rotem

标签: python c++ opencv dll ctype


【解决方案1】:

您正在传递一个np.uint8 类型的数组,等效的C 指针是unsigned char*

int** a 替换为unsigned char* a


为了测试,你可以填写real_image的前4个元素:

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))

您的 C 代码可能如下所示:

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
    }
}

指针unsigned char* a不是指向二维数组的指针,而是指向一维数组的指针(行主格式)。


要将二维 NumPy 数组传递给 C,最好将 stride 参数添加到 C 函数中。
步幅是在两个连续行之间步进的字节数。


为了测试,您可以填写每行的第 4 个元素:

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

您的 C 代码可能如下所示:

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;
    }
}

注意新的stride 参数和a[i*stride]


从 Python 执行 transform

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))

注意:

  • 很可能col = stride,但并非总是如此。

【讨论】:

    【解决方案2】:

    您正在打印每一行的指针。如果你想打印第一行的元素,你应该这样做:

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

    【讨论】:

    • 我确实尝试过,但每当我这样做时,都会出现访问错误,hllDll.transform(n,ctypes.c_int(myimage.shape[0]), ctypes.c_int(myimage.shape [1]), ctypes.c_int(angle)) OSError: 异常: 访问冲突读取 0xFFFFFFFFFFFFFFFF
    • 这不是解决方案。这不是数组数组。 numpy array 的数据只是线性内存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 2012-12-02
    • 2018-05-03
    相关资源
    最近更新 更多