Search code examples
opencviplimage

What is the best way to be able to use Mat object as IplImage object and vice versa?


I am really confused by using Mat and IplImage objects in OpenCV. I read a lot of questions and answers here but I am still in trouble with these 2 types.

Many times, I need converting them to each other that is what makes me lost in those conversions. The functions I know and use sometimes take IplImage objects and sometimes Mat objects.

For example, "cvThreshold" method takes IplImages and "threshold" method takes Mat objects, no problem here but "cvSmooth" method is only for IplImages, I couldn't find a dedicated method for Mat objects (is there?), then I unwillingly convert Mat to IplImage then use in "cvSmooth" and then again convert to Mat. At this point, how can I use Mat object with cvSmooth? I am sure this is not a normal way to handle this issue and there are better ways. Maybe I am missing something in understanding these types.

Can you please help me out to get rid of this problem ?


Solution

  • Calling cvSmooth:

    void callCvSmooth(cv::Mat srcmtx, cv::Mat dstmtx, int smooth_type,
          int param1, int param2, double param3, double param4 )
    {
       IplImage src = srcmtx;
       IplImage dst = dstmtx;
       cvSmooth( &src, &dst, smooth_type, param1, param2, param3, param4 );
    }
    

    But if you look into the cvSmooth implementation you will easily find the C++ analogs:

    CV_IMPL void
    cvSmooth( const void* srcarr, void* dstarr, int smooth_type,
              int param1, int param2, double param3, double param4 )
    {
        cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0;
    
        CV_Assert( dst.size() == src.size() &&
            (smooth_type == CV_BLUR_NO_SCALE || dst.type() == src.type()) );
    
        if( param2 <= 0 )
            param2 = param1;
    
        if( smooth_type == CV_BLUR || smooth_type == CV_BLUR_NO_SCALE )
            cv::boxFilter( src, dst, dst.depth(), cv::Size(param1, param2), cv::Point(-1,-1),
                smooth_type == CV_BLUR, cv::BORDER_REPLICATE );
        else if( smooth_type == CV_GAUSSIAN )
            cv::GaussianBlur( src, dst, cv::Size(param1, param2), param3, param4, cv::BORDER_REPLICATE );
        else if( smooth_type == CV_MEDIAN )
            cv::medianBlur( src, dst, param1 );
        else
            cv::bilateralFilter( src, dst, param1, param3, param4, cv::BORDER_REPLICATE );
    
        if( dst.data != dst0.data )
            CV_Error( CV_StsUnmatchedFormats, "The destination image does not have the proper type" );
    }