简体   繁体   中英

OpenCV - How to write IplImage array in Mat form?

My old project was wrote in C, which includes lots of "IplImage".

Here is one example,

IplImage** img_array = new IplImage* [img_number];
for(int i = 0; i < img_number; i++)
{
    img_array[i] = cvCreateImage(cvSize(320, 240), IPl_DEPTH_8U, 3);
    cvSet(img_array[i], cvScalar(0, 0, 0));
}
.
.
.
.
.
for(int i = 0; i < img_number; i++)
{
    cvReleaseImage(&img_array[i]);
}
delete[] img_array;

Now I have to rewrite my project into C++ form, which I should use cv::Mat.

However, I am not sure the equal way to write my code above into cv::Mat?

I tried write in this way:

int dims[] = {img_number, 320, 240};
cv::Mat img_array(3, dims, CV_8UC3);

everything seems good though, but when comes to a line:

for(int i = 0; i < img_number; i++)
{
    img_array[i] = random_img.clone();
}

an error showup:

C2676:binary operator'[':'cv::Mat'does not define this operator or a conversion to a type acceptable to the predefined operator

After that I found another way that might possibly do, but requires using vector:

vector<Mat> img_array;
for(int i = 0 ; i < img_number; i++)
{
    img_array.push_back(random_img.clone());
}

I haven't implement yet, I am not sure whether this is the solution I want?

Any advice is welcome.

You should view cv::Mat class as a replacement for old IplImage* . The constructor you were using is supposed to create a multidimensional cv::Mat instance, which is probably not what you were looking for. According to your IplImage* based code you were probably trying to create a set of Mat images from a set of IplImage pointers . For that this ctor will serve better:

Mat::Mat(const IplImage* img, bool copyData=false)

If you set copyData argument to true , the constructor will copy the contents of IplImage* and control the new data buffer as usual (reference counting, proper deallocation etc.) If you set it to false, the original IplImage* data will be used and you must take care not to free it before you are done with your cv::Mat instance.

The original docs are here

And, yes, generally it is better to place your cv::Mat instances into a vector. In this case the memory used by Mat s will be automatically freed when the vector goes out of scope (unless you have created some other cv::Mat s which reference the original data, but that's another story)

Edit It appears that the Mat constructor above is not recommended to use. You should use cvarrToMat() function instead, as suggested in answers to this question

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM