来自openCV的cvReleaseImage有一个错误

时间:2014-09-18 12:27:44

标签: c++ opencv

我试图从Image中获取通常称为OCR的数字。

但是当我使用cvMatchTemplate()时,出现错误(vshost32.exe操作已停止。)

我花了大约2个小时的时间才找到理由。幸运的是,我发现这个错误来自cvReleaseImage()

由于我的英语水平有点低,我无法在互联网上理解与此事有关的问题。

所以我需要你的帮助。谢谢。

以下是我的代码。我使用类似于C ++ DLL的OpenCV。

extern "C" __declspec(dllexport) int opencv_UV()
{
double min, max;
double _max;
int index[4];
CvPoint left_top;
IplImage *B[10];
IplImage *C;
B[0]=cvLoadImage("Reference_UV\\0.bmp", -1);
B[1]=cvLoadImage("Reference_UV\\1.bmp", -1);
B[2]=cvLoadImage("Reference_UV\\2.bmp", -1);
B[3]=cvLoadImage("Reference_UV\\3.bmp", -1);
B[4]=cvLoadImage("Reference_UV\\4.bmp", -1);
B[5]=cvLoadImage("Reference_UV\\5.bmp", -1);
B[6]=cvLoadImage("Reference_UV\\6.bmp", -1);
B[7]=cvLoadImage("Reference_UV\\7.bmp", -1);
B[8]=cvLoadImage("Reference_UV\\8.bmp", -1);
B[9]=cvLoadImage("Reference_UV\\9.bmp", -1);



for(int i=0; i<4; i++)
{       
    char name[20];
    strcpy(name,"../Debug");
    char a[1];
    itoa(i,a,1);
    strcat(name, a);
    strcat(name, ".bmp");       
    IplImage *A = cvLoadImage(name, -1);        

    for(int j=0; j<10; j++)
    {
        C = cvCreateImage( cvSize( A->width - B[j]->width+1, A->height - B[j]->height+1 ), IPL_DEPTH_32F, 1 );
        cvMatchTemplate(A, B[j], C, CV_TM_CCOEFF_NORMED);
        cvMinMaxLoc(C, &min, &max, NULL, &left_top);

        if(_max<max)
        {
            _max=max;
            index[i]=j;
        }

        cvReleaseImage(&C);     // I checked there was no error until this point.
    }
    cvReleaseImage(&A);

}

for(int k=0; k<10; k++)
{
    cvReleaseImageHeader(&B[k]);
}

int result=index[0]*1000 + index[1]*100 + index[2]*10 + index[3];

return result;
}

2 个答案:

答案 0 :(得分:1)

我发布了答案,因为我无法添加评论(声誉问题)。您必须先释放标题然后释放图像数据。如果你以另一种方式执行它,即自由图像数据,然后调用cvReleaseImageHeader()函数,那么它看似有效。但在内部泄漏内存,一段时间后你的应用程序将崩溃。您还可以逐步调试以查看IplImage * C的值,看它是否为null,这就是它崩溃的原因。

答案 1 :(得分:0)

图片标题和图片数据是不同的东西。

cvCreateImage() is equivalent to执行:

header = cvCreateImageHeader(size, depth, channels);
cvCreateData(header);

cvReleaseImage() can be seen as是:

的快捷方式
if(*image )
{
    cvReleaseData(*image);
    cvReleaseImageHeader(image);
}

考虑到这一点,以下功能成对使用:

  • cvLoadImage()兄弟是cvReleaseImage();
  • cvCreateImage()兄弟也是cvReleaseImage();
  • 但只有cvCreateImageHeader()cvReleaseImageHeader();
  • 的兄弟

调整代码以遵守这些规则。

还有一件事cvLoadImage()可能会失败!这意味着防御性地编码并测试此函数的返回是个好主意:

B[0]=cvLoadImage("Reference_UV\\0.bmp", -1);
if (B[0] == NULL) {
    // Most probably, the file doesn't exist. Deal with error and
    return;
}

B[1]=cvLoadImage("Reference_UV\\1.bmp", -1);
if (B[1] == NULL) {
    // Most probably, the file doesn't exist. Deal with error and
    return;
}

...