2012-11-20 6 views
13

Ho recentemente iniziato a utilizzare Intel Performance Primitives (IPP) per l'elaborazione delle immagini. Per coloro che non hanno sentito parlare di IPP, pensa a IPP come l'analogo di MKL per l'elaborazione delle immagini anziché l'algebra lineare.Utilizzando le immagini OpenCV Mat con Intel IPP?

Ho già implementato un sistema di visione un po 'complicato in OpenCV, e mi piacerebbe scambiare alcune delle routine di OpenCV (ad esempio convoluzione e FFT) per le routine IPP più veloci. Il mio codice OpenCV utilizza sempre la struttura dei dati delle immagini cv::Mat. Tuttavia, in base agli esempi di codice IPP, sembra che IPP preferisca la struttura dei dati CIppiImage.

Il mio sistema esegue diverse trasformazioni di immagine in OpenCV, quindi voglio fare un paio di cose in IPP, quindi fare più lavoro in OpenCV. Ecco un modo ingenuo per fare OpenCV e IPP gioca bene insieme:

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 

Tuttavia, questo è una specie di noioso, e la lettura/scrittura di file probabilmente aumenta il tempo complessivo di esecuzione.


Sto cercando di rendere più semplice l'alternanza tra OpenCV e IPP in un programma di elaborazione delle immagini. Qui ci sono un paio di cose che potrebbero risolvere il problema:

  1. C'è una battuta che avrebbe convertire un cv::Mat-CIppiImage e viceversa?
  2. Sono abbastanza familiare con i dettagli di implementazione cv::Mat, ma non so molto di CIppiImage. cv::Mat e CIppiImage hanno lo stesso layout di dati? In tal caso, potrei fare qualcosa di simile al cast seguente? CIppiImage cimg = (CIppiImage)(&myMat.data[0])?

risposta

7

C'è un modo pulito per passare i dati OpenCV in una funzione IPP.

Se disponiamo di una OpenCV Mat, è possibile trasmettere *Mat.data[0] a const Ipp<type>*. Ad esempio, se si tratta di dati a 8 bit senza segno (8u), è possibile collegare (const Ipp8u*)&img.data[0] in una funzione IPP. Ecco un esempio utilizzando la funzione ippiFilter con l'immagine tipica 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); 

Quando scrivo outImg (dal codice di cui sopra) in un file, dà il risultato atteso: enter image description here

Questo corrisponde il risultato ho avuto quando ho eseguito la versione di Nvidia, nppiFilter, con gli stessi parametri: enter image description here


Ho menzionato una struttura chiamata CIppiImage nella domanda originale. CIppiImage solo un semplice wrapper per un array.