2012-11-20 13 views
13

Niedawno zacząłem używać Intel Performance Primitives (IPP) do przetwarzania obrazu. Dla tych, którzy nie słyszeli o IPP, pomyśl o IPP jako o analogie MKL dla przetwarzania obrazu zamiast algebry liniowej.Używanie obrazów OpenCV Mat z Intel IPP?

Mam już zaimplementowany nieco skomplikowany system wizyjny w OpenCV i chciałbym zamienić niektóre z procedur OpenCV (np. Splot i FFT) dla szybszych procedur IPP. Mój kod OpenCV zawsze korzysta ze struktury danych obrazu cv::Mat. Jednak na podstawie próbek kodu IPP wydaje się, że IPP preferuje strukturę danych CIppiImage.

Mój system wykonuje kilka przekształceń obrazu w OpenCV, następnie chcę zrobić kilka rzeczy w IPP, a następnie wykonać więcej pracy w OpenCV. Oto naiwny sposób, aby OpenCV i IPP grać ładnie razem:

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 

Jednak jest to rodzaj nudne i odczytu/zapisu plików prawdopodobnie przyczynia się do całkowitego czasu wykonania.


staram się uczynić go bardziej płynną na przemian OpenCV i IPP w programie do przetwarzania obrazu. Oto kilka rzeczy, które mogą rozwiązać ten problem:

  1. Czy istnieje jedno-liner, które konwertować cv::Mat do CIppiImage i vice versa?
  2. jestem dość obeznany z cv::Mat szczegółów implementacji, ale nie wiem zbyt wiele o CIppiImage. Czy cv::Mat i CIppiImage mają taki sam układ danych? Jeśli tak, czy mogę zrobić coś podobnego do poniższej obsady? CIppiImage cimg = (CIppiImage)(&myMat.data[0])?

Odpowiedz

7

Istnieje czysty sposób przekazywania danych OpenCV do funkcji IPP.

Jeśli mamy OpenCV Mat, możemy odrzucić *Mat.data[0] na const Ipp<type>*. Na przykład, jeśli mamy do czynienia z 8-bitowymi znakami unsigned char (8u), możemy podłączyć (const Ipp8u*)&img.data[0] do funkcji IPP. Oto przykład przy użyciu funkcji ippiFilter z typowym Lena obrazu:

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

Kiedy piszę outImg (z powyższego kodu) do pliku, daje oczekiwany wynik: enter image description here

Dopasowuje wynik mam kiedy wpadłem wersję NVIDIA nppiFilter, z tymi samymi parametrami: enter image description here


W pierwotnym pytaniu wspomniałem o strukturze o nazwie CIppiImage. CIppiImage tylko proste opakowanie dla tablicy.