繁体   English   中英

将C ++指针转换为Python numpy数组

[英]Convert C++ pointer to Python numpy array

我正在使用OpenCVC / C ++ DLL上进行工作,在此我执行一些操作。 在此示例中,我更改了在Python上读取的图像的对比度,将其传输到DLL以执行操作,然后在Python上取回结果以显示它。 我正在使用每个图像的第一个像素上的指针来执行此操作,但是在Python中,我找不到使用此指针正确地重新创建图像的方法。

我已经验证了C ++中的Mat对象是连续的,并且检查了从DLL保存的结果是否正确。 对我来说,问题出在Python中,但我看不到我在哪里做错了。

C ++类和函数:

#pragma once
#include <vector>
#include <string>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <thread>

using namespace cv;
using namespace std;

class EpsImageProcessing
{
    // -------------- Methods --------------
public:
    EpsImageProcessing();
    ~EpsImageProcessing();

    unsigned short * imAdjustContrast(void * ptrImg, int width, int height, int contrastValue);

    // -------------- Atributes --------------
    Mat imgResult;
    unsigned short *imgAdress;
};


unsigned short * EpsImageProcessing::imAdjustContrast(void * ptrImg, int width, int height, int contrastValue)
{
    // Get image and reshape it as Mat object
    Mat imgTemp = Mat(height, width, CV_8UC1, (uchar*)ptrImg);

    // Convert to double to perform calculations
    imgTemp.convertTo(imgTemp, CV_32FC1);

    // Calculate the contrast coefficient
    float coeff = (259*((float)contrastValue+255)) / (255*(259 - (float)contrastValue));

    // Change contrast
    imgTemp = coeff * (imgTemp - 128) + 128;

    // Convert image to original type
    imgTemp.convertTo(imgTemp, CV_8UC1);

    // Return result
    imgResult= imgTemp.clone(); // imgTmp is an attribute of the class of my DLL
    imwrite("imgAfter.jpg", imgResult);

    bool test = imgResult.isContinuous(); // return true

    imgAdress = imgResult.ptr<ushort>();

    return imgAdress; //imgResult.ptr<ushort>(); // (unsigned short *)imgResult.data;
}

然后,C包装器在C ++和其他语言(如Python)之间建立链接:

__declspec(dllexport) unsigned short* __stdcall imAdjustContrast(void* handle, void* imgPtr, int width, int height, int contrastValue)
{
    if (handle)
    {
        EpsImageProcessing* data = (EpsImageProcessing*)handle;
        return data->imAdjustContrast(imgPtr, width, height, contrastValue);
    }
    return false;
}

和Python代码:

from ctypes import *
import numpy, os, cv2
import matplotlib.pyplot as plt

dirpath = os.environ['PATH']
os.environ['PATH'] = dirpath + ";C:/x64/Debug/" # include of opencv_world.dll


mydll = cdll.LoadLibrary("MyDll.dll")
class mydllClass(object):
    def __init__(self, width, height, nFrame, path, filename):
        mydll.AllocateHandleImg.argtypes = []
        mydll.AllocateHandleImg.restype = c_void_p

        mydll.imAdjustContrast.argtypes = [c_void_p, c_void_p, c_int, c_int, c_int]
        mydll.imAdjustContrast.restype = POINTER(c_ushort)

        self.obj = mydll.AllocateHandleImg()

    def imAdjustContrast(self, ptrImg, width, height, contrast):
        return mydll.imAdjustContrast(self.obj, ptrImg, width, height, contrast)



img0 = cv2.imread("C:\\Users\\mg\\Downloads\\imgInit.jpg", 0)
imgC = myclass.imAdjustContrast(img0.__array_interface__['data'][0], img0.shape[1], img0.shape[0], -127)
imgAfter = cv2.imread("C:\\Users\\mg\\Downloads\\imgAfter.jpg", 0)

image = numpy.zeros((img0.shape[0],img0.shape[1]), dtype=numpy.dtype(numpy.uint8))
for i in range(img0.shape[0]):
    for j in range(img0.shape[1]):
        indice = i*img0.shape[1]+j
        image[i,j] = numpy.uint8(imgC[indice])
newImg = numpy.ctypeslib.as_array(cast(imgC, POINTER(c_uint8)), shape=(img0.shape))

plt.figure()
plt.subplot(221)
plt.imshow(imgAfter)
plt.gray()
plt.colorbar()
plt.title('image saved from C++ DLL')
plt.subplot(222)
plt.imshow(image)
plt.gray()
plt.colorbar()
plt.title('image recreated in Python (for loop)')
plt.subplot(223)
plt.imshow(newImg)
plt.gray()
plt.colorbar()
plt.title('image recreated in Python (cast)')
plt.show()

而在Python上的最终结果是: 在此处输入图片说明

我发现两个“好的图像”(保存在C ++中的图像和使用cast方法在Python中重新创建的图像)之间的细微差别是由于图像(.jpg)的压缩,这在Python和C ++之间是不同的。 使用cast方法可以处理png和使用C ++指针在Python中创建的图像。

因此,现在的问题是关于两个for循环,它们不能很好地从指针创建图像。 任何想法?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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