C ++ + OpenCV = Место чтения нарушения доступа 0x02176000 - PullRequest
3 голосов
/ 17 декабря 2010

Этот код фактически работал до сих пор. Я понятия не имею, что сейчас вызывает ошибку (на самом деле я не помню, чтобы какие-либо изменения в коде). Вот оно (оно читает изображение из файла в объект OpenCV IplImage, а затем преобразует его в буфер jpeg):

  IplImage* fIplImageHeader = cvLoadImage( filePath.c_str() );

  vector<int> p;
  p.push_back( CV_IMWRITE_JPEG_QUALITY );
  p.push_back( 75 ); // JPG quality
  vector<unsigned char> buf;
  cv::imencode( ".jpg", fIplImageHeader, buf, p ); // this line gives error

Полная ошибка:

Unhandled exception at 0x638fee22 in Client.exe: 0xC0000005: Access violation reading location 0x02176000.

fIplImageHeader содержит действительное изображение, которое я могу подтвердить, используя:

cvShowImage( "Window", fIplImageHeader );

EDIT:

Более длинный фрагмент:

while ( l < 30 )
{
            // path to image
    std::stringstream sstm;
    string filePath;
    sstm << workingDirectory << "/temp/" << k << ".jpg";
    filePath = sstm.str();

    cout << filePath.c_str() << endl;

    // load image to IplImage
    IplImage* fIplImageHeader = cvLoadImage( filePath.c_str() );

    // convert to JPG
    vector<int> p;
    p.push_back( CV_IMWRITE_JPEG_QUALITY );
    p.push_back( 75 ); // JPG quality
    vector<unsigned char> buf;
    cv::imencode( ".jpg", fIplImageHeader, buf, p );

            // do stuff

    k++;
    l++;
    if (10 == k)
    {
        k = 0;
    }

    char key = cvWaitKey( 1000/30 );

    cvReleaseImage( &fIplImageHeader );
}

Ответы [ 3 ]

2 голосов
/ 07 мая 2011

РЕДАКТИРОВАТЬ: мой плохой, я не использовал этот метод ... Так что я не знаю, что происходит не так ...

У меня было то же исключение с использованием "imencode", я не знаю, нужно ли мне изменять размер вектора jpegBuf

void CWebcamWidget::putJpegImage(IplImage *iplImage) {
    // Sans compression jpeg
    //image = QImage((const uchar*)iplImage->imageData, iplImage->width, iplImage->height, QImage::Format_RGB888).rgbSwapped();

    // Still doesn't work using cv::vector...
    cv::vector<int> p;
    p.push_back(CV_IMWRITE_JPEG_QUALITY);
    p.push_back(75); // JPG quality
    cv::vector<uchar> jpegBuf;
    imencode(".jpg", iplImage, jpegBuf, p);

    // Conversion vector<uchar> => uchar*
    uchar *buf;
    memcpy(buf, &jpegBuf[0], sizeof(uchar)*jpegBuf.size());

    image = QImage((const uchar*)buf, iplImage->width, iplImage->height, QImage::Format_RGB888).rgbSwapped();
    imageLabel->setPixmap(QPixmap::fromImage(image));
}

Я не знаю, действительно ли мне нужно конвертировать из вектора в uchar *, может быть, я смогу сэкономить некоторое время процессора без него ...

2 голосов
/ 18 декабря 2010

Предполагается, что размер выходного буфера будет изменен к выходному изображению, но вы не указали явный размер для объекта buf. По крайней мере, это упомянуто на вашей ссылочной странице документа в http://opencv.willowgarage.com/documentation/cpp/reading_and_writing_images_and_video.html

Можете ли вы попробовать установить явный размер на buf? Прямо сейчас в вашем примере кода это просто пустой вектор.

РЕДАКТИРОВАТЬ: Да, я думаю, что вы правы, если я еще немного кослюсь на странице документа, это, похоже, указывает на то, что cv::imencode сделает распределение, так что вам не придется это делать. Если это правда, действительно ли ваше входное изображение действительно большое, у вас не хватает памяти? Также вы можете войти в отладочную версию cv::imencode?

РЕДАКТИРОВАТЬ: На этой странице есть еще один пример кода http://opencv.willowgarage.com/documentation/cpp/core_basic_structures.html#Mat

IplImage* img = cvLoadImage("greatwave.jpg", 1);
Mat mtx(img); // convert IplImage* -> cv::Mat

Можете ли вы также попробовать шаг "convert to cv :: Mat" и передать его в cv::imencode?

0 голосов
/ 18 января 2017

Я также недавно столкнулся с этой проблемой в сборках Debug проекта, использующего OpenCV 3.0 в сочетании с Visual Studio 2015. Некоторое время назад проект был собран с Visual Studio 2013, и я не могу вспомнить, чтобы у меня была эта проблема. Выпуски сборки также не вызвали исключение. Исключение произошло во время вызова на imencode, который я использовал следующим образом:

bool writeImageToDisk(const std::string& filename, cv::Mat image) {
    std::vector<uchar> imageData;
    bool result = cv::imencode(".jpg", image, imageData);
    if (!result) {
        return false;
    }
    ...

Я использовал openvc_world300.dll и .lib, которые я скачал с официального сайта OpenCV. Поскольку они были помещены в подпапку vc12, я предполагаю, что они были созданы с помощью Visual Studio 2013. Я не смог протестировать версию Debug, поскольку соответствующие библиотеки Visual C ++ 2013 не были установлены в моей системе.

После обновления до OpenCV 3.2 эта проблема была исправлена ​​для меня, не затрагивая ничего другого, поэтому, возможно, произошла ошибка или проблема с распределенными двоичными файлами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...