使用英特尔IPP的OpenCV Mat图像?

我最近开始使用Intel Performance Primitives(IPP)进行图像处理。 对于那些没有听说过IPP的人,可以将IPP视为MKL的模拟图像处理而不是线性代数。

我已经在OpenCV中实现了一个有点复杂的视觉系统,我想换掉一些OpenCV例程(例如卷积和FFT)来实现更快的IPP例程。 我的OpenCV代码总是使用cv::Mat图像数据结构。 但是,基于IPP代码示例,IPP似乎更喜欢CIppiImage数据结构。

我的系统在OpenCV中进行了几次图像转换,然后我想在IPP中做一些事情,然后在OpenCV中做更多的工作。 这是让OpenCV和IPP很好地融合在一起的天真方式:

  cv::Mat = load original image use OpenCV to do some work on cv::Mat write cv::Mat to file CIppiImage = read cv::Mat from file //for IPP use IPP to do some work on CIppiImage write CIppiImage to file cv::Mat = read CIppiImage from file use OpenCV to do more work on cv::Mat write final image to file 

但是,这有点乏味,读/写文件可能会增加整体执行时间。


我试图让它在图像处理程序中更加无缝地在OpenCV和IPP之间交替。 以下是一些可以解决问题的方法:

  1. 是否存在将cv::Mat转换为CIppiImage ,反之亦然?
  2. 我对cv::Mat实现细节非常熟悉,但我对CIppiImagecv::MatCIppiImage有相同的数据布局吗? 如果是这样,我可以做类似下面的演员吗? CIppiImage cimg = (CIppiImage)(&myMat.data[0])

将OpenCV数据传递到IPP函数有一种干净的方法。

如果我们有一个OpenCV Mat ,我们可以将*Mat.data[0]转换为const Ipp* 。 例如,如果我们处理8位无符号字符( 8u )数据,我们可以将(const Ipp8u*)&img.data[0]插入到IPP函数中。 以下是使用ippiFilter函数和典型Lena图像的示例:

 Mat img = imread("./Lena.pgm"); //OpenCV 8U_C1 image Mat outImg = img.clone(); //allocate space for convolution results int step = img.cols; //pitch const Ipp32s kernel[9] = {-1, 0, 1, -1, 0, 1, -1, 0, 1}; IppiSize kernelSize = {3,3}; IppiSize dstRoiSize = {img.cols - kernelSize.width + 1, img.rows - kernelSize.height + 1}; IppiPoint anchor = {2,2}; int divisor = 1; IppStatus status = ippiFilter_8u_C1R((const Ipp8u*)&img.data[0], step, (Ipp8u*)&outImg.data[0], step, dstRoiSize, kernel, kernelSize, anchor, divisor); 

当我将outImg (从上面的代码)写到文件时,它给出了预期的结果: 在此处输入图像描述

这与我运行Nvidia版本nppiFilter时使用相同参数得到的结果相符: 在此处输入图像描述


我在原始问题中提到了一个名为CIppiImage的结构。 CIppiImage只是一个简单的数组包装器。