我正试图从相机中获取单张图像,对它们进行一些处理并释放使用过的内存。我已经用相似的代码执行了很长一段时间了:
char* img_data = new char[ len ]; // I retrieve len from the camera.
// Grab the actual image from the camera:
// It fills the previous buffer with the image data.
// It gives width and height.
CvSize size;
size.width = width;
size.height = height;
IplImage* img = cvCreateImageHeader( size, 8, 1 );
img->imageData = img_data;
// Do the processing
cvReleaseImage( &img );
此代码运行正常。我最近阅读了here(在imageData描述中),我不应该直接将数据分配给img-> imageData,而是使用SetData(),如下所示:
cvSetData( img, img_data, width );
然而,当我这样做的时候,我在cvReleaseImage()调用时遇到了Segmentation错误。
我做错了什么?
谢谢。
编辑:我已经尝试编译并运行@karlphillip建议的程序,并且我使用cvSetData获得了分段错误,但在直接分配数据时运行正常。 我正在使用Debian 6和OpenCV 2.3.1。
答案 0 :(得分:2)
我也有这个问题,但相信它是从我收集的内容中解决的 this comment;即使用cvReleaseImageHeader()而不是cvReleaseImage()。
例如:
unsigned int width = 100;
unsigned int height = 100;
unsigned int channels = 1;
unsigned char* imageData = (unsigned char*)malloc(width*height*channels);
// set up the image data
IplImage *img = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, channels);
cvSetData(img, imageData, width*channels);
// use img
cvReleaseImageHeader(&img);
// free(imageData) when finished
答案 1 :(得分:1)
问题是你使用C ++方式分配内存(使用new
),同时使用OpenCV的C接口,它试图在free()
内用cvReleaseImage()
释放该内存块。 C和C ++的内存分配不能混合在一起。
解决方案:使用malloc()
分配内存:
char* img_data = (char*) malloc(len * sizeof(char));
// casting the return of malloc might not be necessary
// if you are using a C++ compiler
编辑:(由于OP的评论仍在崩溃)
您没有向我们展示的其他会导致您的应用程序崩溃!我认真地建议您编写一个完整/最小的应用程序来重现您遇到的问题。
以下应用程序在我的Mac OS X中使用OpenCV 2.3.1正常工作。
#include <cv.h>
#include <highgui.h>
int main()
{
char* img_data = (char*) malloc(625);
CvSize size;
size.width = 25;
size.height = 25;
IplImage* img = cvCreateImageHeader( size, 8, 1 );
//img->imageData = img_data;
cvSetData( img, img_data, size.width );
cvReleaseImage( &img );
return 0;
}
答案 2 :(得分:1)
通常,如果您手动分配标头并设置数据,则应该仅释放 标头并自行释放数据:
// allocate img_data
IplImage* img = cvCreateImageHeader( size, 8, 1 );
img->imageData = img_data;
cvReleaseImageHeader( &img ); // frees only the header
// free img_data
如果您调用cvReleaseImage,它也会尝试释放数据,因此您依赖OpenCV实现来执行此操作,这在您的情况下失败,因为它使用free
并且您使用{{1}分配彼此不相容的。
另一种选择是使用new
分配并致电malloc
。
答案 3 :(得分:0)
我想在此讨论中添加一个细节。似乎有某种错误 cvReleaseHeader()函数。 您必须先释放标题,然后释放图像数据。 如果你以另一种方式,即免费图像数据,然后调用cvReleaseHeader()函数,那么欺骗性工作。但在内部它会泄漏内存,一段时间后你的应用程序就会崩溃。