Converting cv::Mat to IplImage*

C++Opencv

C++ Problem Overview


The documentation on this seems incredibly spotty.

I've basically got an empty array of IplImages (IplImage** imageArray) and I'm calling a function to import an array of cv::Mats - I want to convert my cv::Mat into an IplImage so I can copy it into the array.

Currently I'm trying this:

while(loop over cv::Mat array)
{
    IplImage* xyz = &(IplImage(array[i]));
    cvCopy(iplimagearray[i], xyz);
}

Which generates a segfault.

Also trying:

while(loop over cv::Mat array)
{
    IplImage* xyz;
    xyz = &array[i];
    cvCopy(iplimagearray[i], xyz);
}

Which gives me a compile time error of: error: cannot convert ‘cv::Mat*’ to ‘IplImage*’ in assignment

Stuck as to how I can go further and would appreciate some advice :)

C++ Solutions


Solution 1 - C++

cv::Mat is the new type introduce in OpenCV2.X while the IplImage* is the "legacy" image structure.

Although, cv::Mat does support the usage of IplImage in the constructor parameters, the default library does not provide function for the other way. You will need to extract the image header information manually. (Do remember that you need to allocate the IplImage structure, which is lack in your example).

Solution 2 - C++

Mat image1;
IplImage* image2=cvCloneImage(&(IplImage)image1);

Guess this will do the job.

Edit: If you face compilation errors, try this way:

cv::Mat image1;
IplImage* image2;
image2 = cvCreateImage(cvSize(image1.cols,image1.rows),8,3);
IplImage ipltemp=image1;
cvCopy(&ipltemp,image2);

Solution 3 - C++

 (you have cv::Mat old)
 IplImage copy = old;
 IplImage* new_image = ©

you work with new as an originally declared IplImage*.

Solution 4 - C++

Here is the recent fix for dlib users link

cv::Mat img = ...
IplImage iplImage = cvIplImage(img);

Solution 5 - C++

Personaly I think it's not the problem caused by type casting but a buffer overflow problem; it is this line

cvCopy(iplimagearray[i], xyz);   

 

that I think will cause segment fault, I suggest that you confirm the array iplimagearray[i] have enough size of buffer to receive copyed data

Solution 6 - C++

According to OpenCV cheat-sheet this can be done as follows:

IplImage* oldC0 = cvCreateImage(cvSize(320,240),16,1);
Mat newC = cvarrToMat(oldC0);

The cv::cvarrToMat function takes care of the conversion issues.

Solution 7 - C++

In case of gray image, I am using this function and it works fine! however you must take care about the function features ;)

CvMat * src=  cvCreateMat(300,300,CV_32FC1);      
IplImage *dist= cvCreateImage(cvGetSize(dist),IPL_DEPTH_32F,3);

cvConvertScale(src, dist, 1, 0);

Solution 8 - C++

One problem might be: when using external ipl and defining HAVE_IPL in your project, the ctor

_IplImage::_IplImage(const cv::Mat& m)
{
    CV_Assert( m.dims <= 2 );
    cvInitImageHeader(this, m.size(), cvIplDepth(m.flags), m.channels());
    cvSetData(this, m.data, (int)m.step[0]);
}

found in ../OpenCV/modules/core/src/matrix.cpp is not used/instanciated and conversion fails.

You may reimplement it in a way similar to :

IplImage& FromMat(IplImage& img, const cv::Mat& m)
{
	CV_Assert(m.dims <= 2);
	cvInitImageHeader(&img, m.size(), cvIplDepth(m.flags), m.channels());
	cvSetData(&img, m.data, (int)m.step[0]);
	return img;
}

IplImage img;
FromMat(img,myMat);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionamrView Question on Stackoverflow
Solution 1 - C++YeenFeiView Answer on Stackoverflow
Solution 2 - C++LovaBillView Answer on Stackoverflow
Solution 3 - C++user2103629View Answer on Stackoverflow
Solution 4 - C++minhazurView Answer on Stackoverflow
Solution 5 - C++octavianView Answer on Stackoverflow
Solution 6 - C++chayanView Answer on Stackoverflow
Solution 7 - C++ksolidView Answer on Stackoverflow
Solution 8 - C++TimmView Answer on Stackoverflow