- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was wondering if anyone had quick example code for this, I couldn't find any examples in this forum or OpenCV's website. If not, I have a few questions where I am most confused on.
- OpenCV is interlaced, in bgr format. Ipp expects planar images though (as per the malloc definition.) For now I think I'll avoid this, and just only convert grayscale images, But this is useful for future work/questions.
- The OpenCV widthstep is no longer 32 bit aligned. So my assumption is going to be to transfer row by row from a cv::Mat into an ipp_malloced memory. I'm assuming that OpenCV widthstep < IPP widthstep.
- Is there anything else I should worry about?
Thank you in advance!Constantin
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
No need to worry. IPP supports both interleaved (C3 suffix) and planar (C1 suffix) images and works with data allocated by cv::Mat object. Not alighned on 32 buffere may affect only performance.
Please take a look on to the example in the attach. It shows how to use cvMat data with IPP.
Igor S. Belyakov
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Constantin,
We have quick example about IplImage and IPP image in http://software.intel.com/en-us/articles/using-intel-ipp-with-opencv-21
IplImage* pSrcImg = cvLoadImage( "testimg.bmp", 1 );//lena.jpg
and ippiRemap_8u_C3R((Ipp8u*) pSrcImg->imageData,
also about cvMat
float* pXTable = (float*) malloc(sizeof(float)*nTableSize);
CvMat* pXMap=cvCreateMat(TARGET_HEIGHT,TARGET_WIDTH,CV_32F);
cvSetData (pXMap, (void*) pXTable, sizeof(float)*TARGET_WIDTH);
I'm not sure all of cv::Mat defintion and corresponding functions. So just comments about IPP
1) IPP should support interlaces too, like any function with C3, which supposed for 3 channel image, like rgb, bgr etc. and ippiMaloc_8u_C3 can for general image.
2) IPP function should support no-32bit align memory too. for example, if the cv::Mat point to a continous memory (no padding in each row), if you have the start point of cv::Mat, and know the widthStep, you can call IPP function directly, the ipp malloc is not needed.
cv::Mat mtSamples(1, N, CV_32FC1 );
float* pSamples = (float*)mtSamples.datastart;
ippiRemap_32f_xx(pSamples,
3) As you see, IplImage and IPP image is matched each other, the difference of cv::Mat and IplImage is same as the difference of IPP. So if there are functions which can cast cv::Mat to IplImage, then you can use same on IPP. As you point out, the key problem you may need to take care are to feed IPP function with the pointer of cv::Mat's data and correct widthStep value.
Best Regards,
Ying
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ying and Igor, thank you for your responses. So after more research yesterday I determined the OpenCV (after v2.0) does not pad cv::Mat's anymore. Thus the align function calls are useless. I was interested in correctly using IPP so I implemented a way to copy data over quickly to IPP aligned memory.
NOTE: This example is only for a single channel image! I was unaware if IPP did BGR or RGB and it wasnt necessry for me. I also allow scaling between 8u or 32f if you wish to switch data types.
unsigned char * row_ptr = 0;
switch(output)
{
case IPL_DEPTH_8U:
if(uchar_image_ptr_)
ippFree(uchar_image_ptr_);
uchar_image_ptr_ = ippiMalloc_8u_C1(size.width, size.height, &step);
row_ptr = uchar_image_ptr_;if(mat.depth() != CV_8U)
{
workspace = mat.clone();
double scale = 1.0;
if(mat.depth() == CV_32F || mat.depth() == CV_64F)
scale = 255.0; //Scale from 0.0 - 1.0 to 0-255
mat.convertTo(workspace, CV_8U, scale);
}break;
case IPL_DEPTH_32F:
if(float_image_ptr_)
ippFree(float_image_ptr_);
float_image_ptr_ = ippiMalloc_32f_C1(size.width, size.height, &step);
row_ptr = (unsigned char *)float_image_ptr_;if(mat.depth() != CV_32F)
{
workspace = mat.clone();
double scale = 1.0;
if(mat.depth() == CV_8U || mat.depth() == CV_16U || mat.depth() == CV_32S)
scale = 1/255.0; //Scale from 0.0 - 1.0 to 0-255
mat.convertTo(workspace, CV_32F, 1.0);
workspace = workspace * scale;
}break;
}if(step < workspace.step[0])
std::cerr << "STEPSIZE DOESNT MATCH UP" << std::endl;for(int row = 0; row < workspace.rows; ++row)
{
memcpy(row_ptr, workspace.row(row).data, workspace.step[0]);
row_ptr += step;
}
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page