Convert CImg image to cv :: Mat

0

I am using the CImg 2.1.3 library with OpenCV 3.3.0 so I need to convert a CImg object to Mat, in the examples of the libraría they use this code:

cimg_library::CImg<unsigned char> *cvImgToCImg(cv::Mat &cvImg)
{
    cimg_library::CImg<unsigned char> * result = new cimg_library::CImg<unsigned char>(cvImg.cols, cvImg.rows);

    for (int x = 0; x < cvImg.cols; ++x)
        for (int y = 0; y < cvImg.rows; ++y)
            (*result)(x, y) = cvImg.at<uchar>(y, x);

    return result;
}

My question is this:

How can I improve this code to make it faster, if possible?

    
asked by nullptr 06.11.2017 в 16:29
source

1 answer

1

Libraries involved.

Consulting the documentation of The CImg Library , we see that the class CImg contains a constructor that accepts a data pointer next to a width and height to construct an image in a single step:

CImg    (   const t *const  values,
            const unsigned int  size_x,
            const unsigned int  size_y = 1,
            const unsigned int  size_z = 1,
            const unsigned int  size_c = 1,
            const bool  is_shared = false 
        )

The size_x parameter corresponds to the width, size_y to high size_z to the depth of the image (only applicable to volumetric images ), size_c the number of channels.

On the other hand, the documentation of Open Source Computer Vision Library tells us that class Mat has a function for get a pointer to your internal data :

uchar* cv::Mat::ptr (   int     i0 = 0  )

Warns us to make sure that the matrix is continuous ( all of its elements are stored in way attached ) to know the exact behavior.

Proposal.

Knowing this data, we can rewrite your function cvImgToCImg(cv::Mat &cvImg) in the following way:

//                               v <--- Devuelve una instancia, no un puntero
cimg_library::CImg<unsigned char> cvImgToCImg(const cv::Mat &cvImg)
// La matriz entrante no sera modificada ---> ^^^^^
{
    return {cvImg.ptr, cvImg.cols, cvImg.rows};
//         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <--- Se construye en el punto de retorno, favoreciendo OVR
}

Improvements applied.

  • The body of the function cvImgToCImg has been simplified to eliminate iterations of the loops and the call to the parenthesis operator, so that the function works less.
  • Delegate the data copy to internal mechanisms of the CImg library, when passing the data directly to the library instead of assigning it pixel by pixel, we allow the library to apply the internal optimizations available (if available) of them).
  • The input data is constant, this can help the compiler in the optimization decisions since knowing that a variable does not contain side effects can make more aggressive optimization decisions.
  • The resulting object is built at the point of return, favoring optimizing the return value .
  • Dynamic memory is not used (we do not imply the operator new ) which is slower.
  • Warning.

  • I have not tried the code (so I do not know if it compiles) because I do not have the libraries that you use.
  • Libraries internally may be hosting dynamic memory.
  • I do not have benchmarks to compare.
  • I do not know the configuration of the images you are trying, the parameters used to build the CImg may not be suitable.
  • I assume that the matrices received will be attached.
  • answered by 06.11.2017 в 17:43