Преобразование cv::Mat в IplImage*
Документация на это кажется невероятно пятнистой.
Я в основном получил пустой массив IplImage*s (IplImage** imageArray), и я вызываю функцию для импорта массива cv::Mats - я хочу преобразовать мой cv:: Mat в IplImage *, поэтому я может скопировать его в массив.
В настоящее время я пытаюсь это:
while(loop over cv::Mat array)
{
IplImage* xyz = &(IplImage(array[i]));
cvCopy(iplimagearray[i], xyz);
}
Который генерирует segfault.
Также пытаюсь:
while(loop over cv::Mat array)
{
IplImage* xyz;
xyz = &array[i];
cvCopy(iplimagearray[i], xyz);
}
Что дает мне ошибку времени компиляции:error: cannot convert ‘cv::Mat*’ to ‘IplImage*’ in assignment
Застрял в том, как я могу пойти дальше и был бы признателен за некоторые советы:)
7 ответов
cv::Mat
это новый тип, введенный в OpenCV2.X, в то время как IplImage*
является "устаревшей" структурой изображения.
Хотя, cv::Mat
поддерживает использование IplImage
в параметрах конструктора библиотека по умолчанию не предоставляет функции для другого способа. Вам нужно будет извлечь информацию заголовка изображения вручную. (Помните, что вам нужно выделить структуру IplImage, чего нет в вашем примере).
Mat image1;
IplImage* image2=cvCloneImage(&(IplImage)image1);
Угадай, это сделает работу.
Изменить: Если вы столкнулись с ошибками компиляции, попробуйте следующим образом:
cv::Mat image1;
IplImage* image2;
image2 = cvCreateImage(cvSize(image1.cols,image1.rows),8,3);
IplImage ipltemp=image1;
cvCopy(&ipltemp,image2);
(you have cv::Mat old)
IplImage copy = old;
IplImage* new_image = ©
вы работаете с новым как первоначально объявленный IplImage*.
Вот недавнее исправление для пользователей dlib ссылки
cv::Mat img = ...
IplImage iplImage = cvIplImage(img);
Лично я думаю, что это не проблема, вызванная приведением типов, а проблема переполнения буфера; именно эта линия
cvCopy(iplimagearray[i], xyz);
я думаю, что это вызовет ошибку сегмента, я предлагаю вам подтвердить, что массив iplimagearray[i] имеет достаточный размер буфера для получения скопированных данных
Согласно шпаргалке OpenCV это можно сделать следующим образом:
IplImage* oldC0 = cvCreateImage(cvSize(320,240),16,1);
Mat newC = cvarrToMat(oldC0);
Функция cv::cvarrToMat заботится о проблемах конвертации.
Одной из проблем может быть: при использовании внешнего ipl и определении HAVE_IPL в вашем проекте, 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]);
}
находится в../OpenCV/modules/core/src/matrix.cpp не используется / не создан и преобразование не выполняется.
Вы можете переопределить его так, как:
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);
В случае серого изображения, я использую эту функцию, и она отлично работает! однако вы должны позаботиться о функциях функции;)
CvMat * src= cvCreateMat(300,300,CV_32FC1);
IplImage *dist= cvCreateImage(cvGetSize(dist),IPL_DEPTH_32F,3);
cvConvertScale(src, dist, 1, 0);