2012-11-20 73 views
13

我最近開始使用Intel Performance Primitives (IPP)進行圖像處理。對於那些沒有聽說過IPP的人,可以將IPP看作是MKL的模擬圖像處理代替線性代數。在英特爾IPP上使用OpenCV Mat圖像?

我已經在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::MatCIppiImage,反之亦然?
  2. 我對cv::Mat的實現細節非常熟悉,但我對CIppiImage瞭解不多。 cv::MatCIppiImage是否具有相同的數據佈局?如果是這樣,我可以做類似於下面的演員的東西嗎? CIppiImage cimg = (CIppiImage)(&myMat.data[0])

回答

7

有一個簡單的方法可以將OpenCV數據傳遞到IPP函數中。

如果我們有OpenCV Mat,我們可以投*Mat.data[0]const Ipp<type>*。例如,如果我們處理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(從上面的代碼)到一個文件,它提供了預期的結果: enter image description here

此結果相匹配我有,當我跑了Nvidia的版本,nppiFilter,用同樣的參數: enter image description here


我在原始問題中提到了一個名爲CIppiImage的結構。 CIppiImage只是一個數組的簡單包裝。