2013-01-31 2 views
1

Я пытался выполнить сравнение содержимого данных в моем объекте IplImage.Не удается получить доступ к данным IplImage

У меня есть следующие:

IplImage img1 = IplImage(cv::imread("C:\\TestIm\\barrier_snapshot1.png"),    
                CV_LOAD_IMAGE_GRAYSCALE); 
    for (int i=0; i < img1.widthStep * img1.height; i++) { 
     cout << img1.imageData[i] << endl; 
    } 

Но когда я пытаюсь напечатать, он вызывает исключение, и я даже не могу поймать его, чтобы напечатать сообщение и посмотреть, что я делаю неправильно. Мое изображение - Оттенки серого, и я верю, что если я не использую cvCreateImage(), все в порядке? Я знаю, что это будет что-то глупое или связанное с доступом к массиву, которое я, похоже, не получаю легко из документации IplImage.

* ПОЧЕМУ Я ОБЕСПЕЧЕН СМЕШАТЬ C И C++ КОД В МОЕЙ ПРОЕКТИРОВАНИИ? *

К сожалению, у меня нет выбора! Я работаю над проектом с улучшенными приложениями обнаружения движения. В моем устаревшем исходном коде приложения используются тяжелые вещи BOOST и OpenCV. В частности, он использует IplImage * (я ненавижу его, затрудняет жизнь и вызывает утечку памяти) для хранения таких вещей, как маски изображений. Я понимаю, что если я сохраню IplImage * в долгосрочной перспективе, у меня будет незаконное обращение и нарушение прав доступа. поэтому я сохраняю копию фактического содержимого, указанного IplImage *. В качестве примера:

// getLongHistory() returns IplImage* 
IplImage history_long = *(motionHistory.getLongHistory()); 

Всего изображений маски 6, которые сделаны с использованием IplImage *. В этот момент я осуждаю программиста, который решил сделать это в IplImage *. Проблема возникает, когда я пытаюсь загрузить эти маски изображения и это, как я это делаю:

// Passing pointer to the address of the mask stored (alive in the memory) 
motionHistory.setLongHistory(&(matcher.getCurrentSceneObject().getLongHistory())); 

Я считаю, что у меня возникают проблемы с глубокой копии и неполную копию объектов IplImage. Я считаю, что делать это как cv :: Mat от IplImage * и загружать его как IplImage * из cv :: Mat, вероятно, уменьшит нагрузку, поскольку я подозреваю, что он, вероятно, делает SOMETHING под высокоуровневыми функциями, чтобы копирование данных и соответственно рентабельность инвестиций. Но, как новичок, я могу предположить все. Пожалуйста помоги!

UPDATE

В моем коде я делал это в прошлом:

/* I store all my mask images in a vector of pairs made of <int, IplImage> 
* __MASK_LONG__ etc. are predefined intergers 
* getMaskLong() etc. methods return IplImage* to the respective mask images. 
*/ 

    myImages.clear(); // To make sure that I have no extra stuff 
    myImages.push_back(std::make_pair<int, IplImage>(_MASK_LONG_, maskHistory.getMaskLong())); 
    myImages.push_back(std::make_pair<int, IplImage>(_MASK_SHORT_, maskHistory.getMaskShort())); 

Однако, после получения предложения и делать некоторые основные R & А, теперь я делаю это предотвращение мелкого копирования:

myImages.clear(); 
    myImages.push_back(std::make_pair<int, IplImage>(_MASK_LONG_, *cvCloneImage(maskHistory.getMaskLong()))); 
    myImages.push_back(std::make_pair<int, IplImage>(_MASK_SHORT_, *cvCloneImage(maskHistory.getMaskShort()))); 

Я могу подтвердить, что t его работы, поскольку я могу видеть, как последние изображения маски загружаются в окно OpenCV! И я вполне уверен, что ВАЖНО делать Deep Copy по крайней мере 2/3 раза в любой задаче программирования. Так что спасибо за то, что поставили меня на правильный путь. Но теперь у меня есть проблема, которую я имел в виду при реализации этих изменений - отказ в распределении памяти. И сообщение встречалось: (! У МЕНЯ НЕТ ВЫБОР !! ЭТО унаследованное приложение)

OpenCV Error: Insufficient memory (Failed to allocate 3686404 bytes) in OutOfMemoryError, 
file /home/naresh/OpenCV-2.4.0/modules/core/src/alloc.cpp, line 52 

Если я достаточно глубоко, чтобы знать о C/C++, во-первых, я совершал преступление, смешивая их вместе. Во-вторых, существует несоответствие, то есть неправильный набор вызовов для malloc/free в файле alloc.cpp (где возникает проблема). Или может быть, что куча повреждена или полна. Неужели я глуп?

+1

У вас есть причина не использовать C++ API вместо C api? Использование cv :: Mat вместо IplImage делает вашу жизнь чрезвычайно легкой. –

+0

@IanMedeiros Я знаю, кто-то ругал меня за это !!! К сожалению, да! Пожалуйста, проверьте мое обновленное описание проблемы !!! – HubbyHaguBear

+0

Серьезно, я могу полностью понять стремление избежать глубоких копий матриц, но работа с методами, возвращающими указатели на IplImages, - это SCREAMING для нарушений доступа и утечек памяти. Способ реализации конструктора cv :: Mat copy, оператора присваивания и деструктора уже позволяет избежать глубоких копий данных. Если есть какой-то план для работы над этим кодом в течение долгого времени, я бы серьезно подумал, что нужно сделать рефакторинг. –

ответ

2

Не смешивайте интерфейс C OpenCV с интерфейсом C++.

В идеале, вы должны решить эту проблему, используя исключительно интерфейс C++, как следующее:

cv::Mat gray = cv::imread("C:\\TestIm\\barrier_snapshot1.png", CV_LOAD_IMAGE_GRAYSCALE); 

cv::Mat_<uchar>::iterator it = gray.begin<uchar>(); 
cv::Mat_<uchar>::iterator end = gray.end<uchar>(); 
for (; it != end; ++it) 
{ 
    cout << *it << endl;   
} 

Или:

cv::Mat gray = cv::imread("C:\\TestIm\\barrier_snapshot1.png", CV_LOAD_IMAGE_GRAYSCALE); 

for (int i = 0; i < gray.cols; i++) 
{ 
    for (int j = 0; j < gray.rows; j++) 
    { 
     cout << gray[gray.cols * j + i] << endl; 
    } 
} 

Да, cv::imread() также может загружать входное изображение в оттенках серого. Но если вам действительно нужно придерживаться интерфейса C, тогда отмените cv::imread() и вместо этого используйте cvLoadImage(). Есть несколько сообщений, объясняющих, как это сделать, используйте поле поиска .

Если вы решили продолжить смешивать интерфейсы (пожалуйста, не делайте этого), check this thread, так как он объясняет, как конвертировать IplImage* в cv::Mat.

+0

спасибо за это ... Я как бы понял, что моя проблема, вероятно, очень старая, но одна из самых страшных проблем в C/C++; Глубокая и мелкая копия. Проблема в том, что у меня очень большое приложение обработки изображений (Motion Detection), которое использует библиотеки Boost и OpenCV. Унаследованный код, написанный для обработки алгоритма обнаружения движения, сильно использует IplImage *. Пожалуйста, проверьте мое описание проблемы, так как я немного обновил его, чтобы пользователи знали, где у меня проблемы ... Я очень ценю вашу помощь, и я проголосовал за вас. – HubbyHaguBear

+0

[Вы видели это?] (Http: // stackoverflow.com/a/13403839/176769) – karlphillip

Смежные вопросы