C ++ + OpenCV =访问冲突读取位置0x02176000

时间:2010-12-17 19:30:49

标签: c++ visual-c++ opencv

此代码实际上一直用到现在。我不知道是什么原因导致它现在抛出错误(我实际上并不记得对代码进行任何更改)。它是(它从文件中读取一个图像到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 );

编辑:

更长的片段:

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 个答案:

答案 0 :(得分:2)

输出缓冲区应该调整为输出图像的大小,但是您没有使用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

您是否也可以尝试“转换为cv :: Mat”步骤,并将其传递给cv::imencode

答案 1 :(得分:2)

编辑:我的不好,我没有使用那种方法......所以我不知道出了什么问题......

我使用“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));
}

我不知道我是否真的需要从vector转换为uchar *,也许我可以节省一些CPU时间而不用它......

答案 2 :(得分:0)

我最近在使用OpenCV 3.0和Visual Studio 2015的项目的Debug版本中遇到了这个问题。该项目之前使用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;
    }
    ...

我使用了从官方OpenCV网站下载的openvc_world300.dll和.lib。由于它们被放置在子文件夹vc12中,我认为它们是使用Visual Studio 2013构建的。我无法测试调试版本,因为我的系统上没有安装适当的Visual C ++ 2013 DLL。

升级到OpenCV 3.2之后,这个问题已经解决了,而且没有触及任何其他内容,所以可能是分布式二进制文件存在错误或问题。