我正在使用OpenCV
的 C / 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()
答案 0 :(得分:0)
我发现两个“好图像”(保存在C ++中的图像,然后使用cast方法在Python中重新创建)之间的细微差别来自图像的压缩(.jpg),这在Python和C ++之间是不同的。使用cast方法可以处理png和使用C ++指针在Python中创建的图像。
因此,现在的问题在于两个for循环,它们不能很好地从指针创建图像。有想法吗?