OpenCV - Как написать массив IplImage в форме Mat?

Мой старый проект был написан на C, который включает в себя множество "IplImage".

Вот один пример,

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;

Теперь я должен переписать свой проект в форму C++, которую я должен использовать cv::Mat.

Тем не менее, я не уверен, что такой же способ написать мой код выше в cv::Mat?

Я пытался написать так:

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

все кажется хорошим, но когда дело доходит до строки:

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

отображение ошибки:

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

После этого я нашел другой способ, который мог бы, но требует использования вектора:

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

Я еще не внедрил, я не уверен, что это решение, которое я хочу?

Любой совет приветствуется.

1 ответ

Решение

Вы должны посмотреть cv::Mat класс как замена старого IplImage*, Конструктор, который вы использовали, должен создать многомерный cv::Mat экземпляр, который, вероятно, не то, что вы искали. В соответствии с вашими IplImage* основанный код, который вы, вероятно, пытались создать набор изображений Mat из набора IplImage указатели. Для этого этот ctor будет служить лучше:

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

Если вы установите copyData в качестве аргумента true конструктор будет копировать содержимое IplImage* и контролировать новый буфер данных как обычно (подсчет ссылок, правильное освобождение и т. д.). Если вы установите его в false, будут использоваться исходные данные IplImage*, и вы должны позаботиться не освобождать его, пока вы не закончили работу с экземпляром cv::Mat.

Оригинальные документы здесь

И, да, как правило, лучше поместить ваши экземпляры cv::Mat в вектор. В этом случае память используется Mats будет автоматически освобожден, когда вектор выйдет из области видимости (если вы не создали какой-либо другой cv::Matкоторые ссылаются на исходные данные, но это уже другая история)

Редактировать Похоже, что конструктор Mat выше не рекомендуется использовать. Вы должны использовать cvarrToMat() вместо этого, как предлагается в ответах на этот вопрос

Другие вопросы по тегам