Richard Knop
Richard Knop

Reputation: 83755

C++ + OpenCV = Access violation reading location 0x02176000

This code actually used to work until now. I have no idea what is causing it to throw an error now (I don't actually remember making any changes to the code). Here it is (it reads an image from a file to OpenCV IplImage object and then converts it to jpeg buffer):

  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

The full error is:

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

The fIplImageHeader contains a valid image which I can confirm by using:

cvShowImage( "Window", fIplImageHeader );

EDIT:

A longer snippet:

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 );
}

Upvotes: 3

Views: 8662

Answers (3)

Ratatwisker
Ratatwisker

Reputation: 171

I also recently encountered this problem in Debug builds of a project using OpenCV 3.0 in conjunction with Visual Studio 2015. The project was previously built with Visual Studio 2013 a while back and I can't remember having this problem. Release builds also didn't trigger the exception. The exception occured during the call to imencode which I used like this:

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

I used openvc_world300.dll and .lib which I downloaded from the official OpenCV website. Since they were placed in the subfolder vc12 I assume they were built with Visual Studio 2013. I couldn't test the Debug version since the appropriate Visual C++ 2013 DLLs were not installed on my system.

After upgrading to OpenCV 3.2 this problem was fixed for me without touching anything else, so maybe there was a bug or a problem with the distributed binaries.

Upvotes: 0

Benjamin Le Cadre
Benjamin Le Cadre

Reputation: 21

EDIT : My bad, I was not using that method... So I don't know what is going wrong...

I had the same exception using "imencode", I don't know if I have to resize the jpegBuf vector

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));
}

I don't know if I really need to convert from vector to uchar*, maybe I can save some CPU time without it...

Upvotes: 2

Chris O
Chris O

Reputation: 5037

The output buffer is supposed to be resized to the output image, but you have not specified an explicit size with the buf object. At least this is mentioned from your referenced doc page at http://opencv.willowgarage.com/documentation/cpp/reading_and_writing_images_and_video.html

Can you try setting an explicit size on buf? Right now in your code sample, it is just an empty vector.

EDIT: Yes, I think you're right, if I squint some more at the doc page, it seems to indicate that cv::imencode will do the allocation, so you shouldn't have to. If that's true then, is your input image really large, are you running out of memory? Also can you step into the debug version of cv::imencode?

EDIT: There's another code sample at this page http://opencv.willowgarage.com/documentation/cpp/core_basic_structures.html#Mat

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

Can you also try the "convert to cv::Mat" step, and pass that into cv::imencode?

Upvotes: 2

Related Questions