使用OpenCV Mat图像与英特尔IPP? [英] Using OpenCV Mat images with Intel IPP?

查看:1136
本文介绍了使用OpenCV Mat图像与英特尔IPP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始使用 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做一些工作cv :: Mat
write cv :: Mat to file

CIppiImage = read cv :: Mat from file // for IPP
使用IPP做一些关于CIppiImage的工作
将CIppiImage写入文件

cv :: Mat =从文件中读取CIppiImage
使用OpenCV在cv :: Mat上执行更多工作b $ b write final图像到文件

然而,这是一种乏味,读/写文件可能会增加执行时间。






我想让它在图像处理程序中更加无缝地交替使用OpenCV和IPP。这里有几个可以解决这个问题的方法:


  1. 有一个单线可以转换 cv :: Mat CIppiImage ,反之亦然吗?

  2. 我非常熟悉 cv :: Mat 实现细节,但我不太了解 CIppiImage cv :: Mat CIppiImage 有相同的数据布局吗?如果是这样,我可以做类似于下面的转换吗? CIppiImage cimg =(CIppiImage)(& myMat.data [0])




如果我们有一个OpenCV Mat ,我们可以将 * Mat.data [0] 转换为 const Ipp< type& code>。例如,如果我们处理8位unsigned char( 8u )数据,我们可以插入(const Ipp8u *)& img。 data [0] 转换为IPP函数。下面是一个使用 ippiFilter 函数和典型 Lena 图片:

  Mat img = imread(./ Lena.pgm); // OpenCV 8U_C1 image 
Mat outImg = img.clone(); //为卷积结果分配空间

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 只是一个数组的简单包装器。


I've recently started using Intel Performance Primitives (IPP) for image processing. For those who haven't heard of IPP, think of IPP as the analogue of MKL for image processing instead of linear algebra.

I've already implemented a somewhat complicated vision system in OpenCV, and I'd like to swap out some of the OpenCV routines (e.g. convolution and FFT) for faster IPP routines. My OpenCV code always uses the cv::Mat image data structure. However, based on the IPP code samples, it seems that IPP prefers the CIppiImage data structure.

My system does several image transformations in OpenCV, then I want to do a couple of things in IPP, then do more work in OpenCV. Here's a naive way to make OpenCV and IPP play nicely together:

 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

However, this is kind of tedious, and reading/writing files probably adds to the overall execution time.


I'm trying to make it more seamless to alternate between OpenCV and IPP in an image processing program. Here are a couple of things that could solve the problem:

  1. Is there a one-liner that would convert a cv::Mat to CIppiImage and vice versa?
  2. I am pretty familiar with the cv::Mat implementation details, but I don't know much about CIppiImage. Do cv::Mat and CIppiImage have the same data layout? If so, could I do something similar to the following cast? CIppiImage cimg = (CIppiImage)(&myMat.data[0])?

解决方案

There's a clean way to pass OpenCV data into an IPP function.

If we have an OpenCV Mat, we can cast *Mat.data[0] to an const Ipp<type>*. For example, if we're dealing with 8-bit unsigned char (8u) data, we can plug (const Ipp8u*)&img.data[0] into an IPP function. Here's an example using the ippiFilter function with the typical Lena image:

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

When I write outImg (from the above code) to a file, it gives the expected result:

This matches the result I got when I ran the Nvidia version, nppiFilter, with the same parameters:


I mentioned a structure called CIppiImage in the original question. CIppiImage just a simple wrapper for an array.

这篇关于使用OpenCV Mat图像与英特尔IPP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆