Using IPP with OpenCV

Using IPP with OpenCV

I have been using OpenCV (without IPP) for some time. I understand that OpenCV calls the IPP functions automatically if available. In that case, if I'm interested only in image-processing, do I need to know IPP syntax at all? I mean, will using the IPP syntax (such as the Ipp8u structure) have any advantages at all? Or can I simply continue writing the OpenCV code that I already know, and install and link the IPP libraries to get full advantage?

Thanks!

11 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

Hi,

OpenCV does not use all the functions you can find in IPP. So, of course you should be interested in using IPP directly (in addition to OpenCV native API). Remember, IPP image processing domain contains about 2500 functions (and only small subset of them are used by OpenCV)!

Regards,
Vladimir

Vladimir,

Thanks for the reply. The question then becomes, when do I use OpenCV functions and when do I use the IPP ones? I'm sure the answer must be simple, I just can't think of it!

I saw a couple of tutorials explaining the use of OpenCV with IPP. One of them says that native IPP functions should be used for the processing, while OpenCV needs to be used for displaying the results. But to me it doesn't make sense to use a large library like OpenCV just to display the results.

How do I know which library to use in every situation?

-Aditya

Aditya,

OpenCV uses IPP functions automatically ifIPP is installed (see INSTALL file from OpenCV root directory). Not all OpenCV functions have corresponding optimized analogues in IPP. The same, IPP contains more functions that is necessary to support OpenCV.

So, if you are comfortable with OpenCV features and data types you need notcall IPP functions directly. Some overhead exists but it is not big.

IPP is low level library that contains highly optimized functions and supports a lot of platforms. OpenCV is higher level open source library that oriented rather to research & development.

Alexander

I created a couple of small programs using IPP functions. It seems that the answer to my question of which library's (OpenCV or IPP) functions to use in which situation would be that whenever I need a function that is present only in IPP (and not in OpenCV) I simply convert the required arguments to IPP data types and call the IPP function, then convert the result back to OpenCV data type. Is that correct?

One more thing: OpenCV calls the IPP functions automatically whenever possible. But the data types for the equivalent functions are still different for OpenCV and IPP (for example the OpenCV function may require IplImage while the equivalent IPP function would require Ipp8u etc.). In that case, when OpenCV calls the IPP automatically, does it do all this conversion automatically?

Thanks,

Aditya

Aditya,

OpenCV is high-level library and IPP is low-level library. Image described in OpenCV as IplImage structure somewhere inside contains pointer to Ipp8u* data which you can use in IPP function call. If it is conversion that you are mentioned - yes, such conversion is necessary.

Regards,
Vladimir

I wanted to detect face from a web camera. I found an example of face detection in samples folder.But they have provided a wrapper class called as CIppiImage . I am retriving frame using open cv,so I am not able to figure out that How I will be able to convert Mat Image or IplImage to the type of CIppiImage.

Hi Rajendra,

As i undstand, whatever the wrapper class is, the key is the block of successive data memory, where image are stored.  So you should be able to do this by either pass the pointer of data or copy the data to corresponding parameter.

I happened find one piece code in my machine to do the conversion between IplImage to CippiImage as below, for your reference.

 IplImage* img = NULL;

img = cvLoadImage(argv[1], CV_LOAD_IMAGE_COLOR);
    if(!img)
    {
        printf("Could not load image file: %s\n", argv[1]);
        exit(0);
    }
    
    //convert src IplImage to CIppImage
    CIppImage srcImage;
    //set elements of srcImage
    srcImage.Width(img->width);
    srcImage.Height(img->height);
    srcImage.Color(IC_RGB);
    srcImage.Format(IF_FIXED);
    srcImage.Sampling(IS_422);
    srcImage.ComponentOrder(0);
    srcImage.NChannels(img->nChannels);
    srcImage.Precision(img->depth);
    srcImage.DataPtr(img->imageData);   

Hope it helps,

Best Regards,

Ying

Hello Zing,

Really appreciate for your help.

However there are few issues in the code given by you for conversion of IPlImage* to CIppImage. I am sending you the definition of CIppImage class so that you can guide me accordingly.

class CIppiImage : public CImgHeader
{
public:
CIppiImage();
CIppiImage(const CIppiImage& img);
virtual ~CIppiImage();
CIppiImage& operator =(const CIppiImage& image);

// General Operations
// Set image header and allocate data
BOOL CreateImage(int width, int height, int nChannels = 3, ppType type = pp8u, BOOL bPlane = FALSE);
BOOL CreateImage(CImgHeader header);
// Load image from bmp file
BOOL LoadImage(CFile* pFile);
// Save image to bmp file
BOOL SaveImage(CFile* pFile);
// Reset image size
BOOL SetSize(int width, int height);

// Attributes
// Get image header
CImgHeader GetHeader() const { return *(CImgHeader*)this;}
// Get pointer to data
void* DataPtr();
// Get image size
IppiSize Size() const { IppiSize size = {Width(), Height()}; return size;}
// Get scanline size in bytes
int Step() const;
// Get data size in bytes
int DataSize() const;
// Get image width
int Width() const { return m_width;}
// Get image height
int Height() const { return m_height;}
// Get number of image channels
int Channels() const { return m_channels;}
// Get plane order flag
BOOL Plane() const { return m_plane;}
// Get data type
ppType Type() const { return m_type;}
// Get size of data element in bits
int Depth() const { return m_type & PP_MASK;}
// Get signed data flag
BOOL Sign() const { return m_type & PP_SIGN ? TRUE : FALSE;}
// Get float data flag
BOOL Float() const { return m_type & PP_FLOAT ? TRUE : FALSE;}
// Get complex data flag
BOOL Complex() const { return m_type & PP_CPLX ? TRUE : FALSE;}
// Get string with data type description
CString TypeString() const;
// Get string with channels and plane description
CString ChannelString() const;
// Set data changed / unchanged flag
// This flag must be set to TRUE if data has been changed
// Then CView::OnDraw function will update bitmap and
// set this flag to FALSE
void IsUpdated(BOOL updated) {m_Updated = updated;}
// Get data changed / unchanged flag
// Used by CView::OnDraw function
BOOL IsUpdated() const {return m_Updated;}
protected:
void* m_pData;
BOOL m_Updated;
void Reset();
void AllocateData();
void FreeData();
};

You can easily visualize that CIppImage height,width or get data function doesn't take parameter .

CIppImage class also does not contain function like sampling,format,color.

The identifiers IS_422,IF_FIXED is also not recognized by compiler.

Please check and guide accordingly.\

Thanks in advance,

Raj

Hi Raj,

As far as I see, you base your code on IPP face detection sample (i.e. on its CIppiImage class). Unfortunately, there is no easy way from OpenCV's IplImage to that CIppiImage object. You need to create a new CIppiImage constructor, which takes, for example, (const IplImage*) argument). In this constructor you need to copy wight/height/type fields from IplImage. You need to rewrite data allocation/freeing code in CIppiImage class in order not to deallocate alien's buffer. Something needs to be done with Step() function, its code is too bad.

May be the easier way could be:
   take FaceDetection sample or cut'n'paste whatever you want from FaceDetection to your application,
   substitute CIppiImage class with IpiImage class from OpenCV,
   compile the result source code.
You'll get lot of compilation errors. Eliminate them one-by-one by substitution methods from CIppiImage with data members from IplImage. For example, the compiler will say that 'IplImage has no Width() method'. Just substitute the code from, say
  src->Width()
to
  src->width
And so on. Hopefully, you will find  OpenCV's equivalents for all CIppiImage member functions.

Regards,
Sergey 

Regards, Sergey

Hi Raj,

I guess, you have move forward about the convertion.  Just summarize again so other user may use

There are two CIppiImage in IPP, one in image Proc, one in UIC sample.  I mentioned last time is the latter

All of them, include  IplImage in OpenCV  are almost from the IPL.  Each of them have part of them. You can align them by change the member or member functions.   But it is actually not too complex to align the class of CIppiImage in IPP and IplImage of OpenCV.

1. For example, if for IPP function, we can feed the IpLImage pointer dierctly, (don't need conversion), 
IplImage* pSrcImg = cvLoadImage( "testing.bmp", 1 );  
ippiResize_8u_C3R((Ipp8u*) pSrcImg->imageData,  pSrcImg->widthStep...).

2. But if you need to do the conversion,

CIippImage in imagProc sample  <> IplImage

the code like,

IplImage * frame2=cvQueryFrame(cap);
 IppiSize size;
 size.width = frame2->width; // size of IPP images is the same
 size.height = frame2->height;
 int imgWidthStep=frame2->widthStep;

 CIppiImage *tmpimg=new CIppiImage();
 tmpimg->CreateImage(frame2->width,frame2->height,3,pp8u);

//convert CIppImage, IplImage<->
 ret=ippiCopy_8u_C3R((const Ipp8u*)frame2,frame2->widthStep,(Ipp8u*)tmpimg->DataPtr(),tmpimg->Step(),size);
//vice-versa

2.1 Another issue, as   bmp image was stored in reversed order, so the copy should be like the below

IplImage* frame2 = cvLoadImage( originalfile, 1 );
 // IplImage * frame2=cvQueryFrame(cap);
 IppiSize size;
 size.width = frame2->width; // size of IPP images is the same
 size.height = frame2->height;
 int imgWidthStep=frame2->widthStep;

 srcld->CreateImage(frame2->width,frame2->height,3,pp8u);

  Ipp8u* pSrc=(Ipp8u*)srcld->DataPtr()+srcld->Step()*(srcld->Height()-1);
 ret=ippiCopy_8u_C3R((const Ipp8u*)frame2->imageData,frame2->widthStep,pSrc,-1*srcld->Step(),size);

and copy back

IplImage* pDstImgIPP = cvCreateImage( cvSize(dst->Width(),dst->Height() ), dst->Depth(),dst->Channels());
 Ipp8u* tmpI= (Ipp8u*)dst->DataPtr()+ dst->Step()* (dst->Height()-1);

ret=ippiCopy_8u_C3R((const Ipp8u*)tmpI,-dst->Step(),(Ipp8u*)pDstImgIPP->imageData,pDstImgIPP->widthStep,size);

3. CIppImage in UIC sample <> IplIimage ,    If use the pointer instead of data copy

cap = cvCaptureFromCAM(0);
IplImage * img=cvQueryFrame(cap); 

 CIppImage srcImage;
 srcImage.Attach(size,3,8,img->imageData,img->widthStep);
  

 CIppImage dstImage;
    int ret;
   ret = dstImage.Alloc(srcImage.Size(),srcImage.NChannels(),srcImage.Precision());
    if(0 != ret) {
     return -1;
    }
   
    //detect face
   facedetection_filter(srcImage, params, dstImage);

IplImage dstImg;
   memset((void*)&dstImg, 0, sizeof(dstImg));
    dstImg.nSize = sizeof(dstImg);
    dstImg.nChannels = dstImage.NChannels();
    dstImg.depth = dstImage.Precision();
    strcpy(dstImg.colorModel, "RGB");
    strcpy(dstImg.channelSeq, "BGR");
    dstImg.align = 4;
    dstImg.width = dstImage.Width();
    dstImg.height = dstImage.Height();
 dstImg.widthStep = dstImage.Step();
    dstImg.imageSize = dstImg.widthStep*dstImg.height;
    dstImg.imageData = (char*)dstImage.DataPtr();

Best Regards,

Ying

Faça login para deixar um comentário.