关于两个CvSeq的定义及初始操作如下:
CvSeq* point_seq = 0;
point_seq = cvCreateSeq( CV_32SC2,
sizeof(CvSeq),
sizeof(CvPoint),
storage );
CvSeq* labels = 0;
用完过后,使用
cvReleaseMemStorage(&(point_seq->storage))
cvReleaseMemStorage(&(labels->storage))
释放CvSeq的内存。
但是在释放时会出现此种问题:
0x77bc15de处未处理的异常:0xC0000005:读取位置0xfeeefef6时发生访问冲突。
这个问题应该是由于内存重复释放引发的。因此我们可以设置断点查看一下,释放的2个CvSeq中的storage的内存:
很神奇的是:两块CvSeq共用了一个storage空间。释放时只释放其一即可,更深入的解释,目前自己还没有发现。
另外,openCV内存释放的很多问题,在这篇文章里都有说明:
http://blog.csdn.net/xiaowei_cqu/article/details/7586847
这里是源码:
IplImage* display; display = cvCreateImage(cvSize(img->width, img->height), 8, 3); cvZero(display); CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* point_seq = 0; point_seq = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage ); CvPoint pt_ball; int num_i = 0; for(int h = 0; h < img->height; h++) { for(int w = 0; w < img->width; w++) { if(( (uchar*) (img->imageData + h * img->widthStep) )[w * img->nChannels + 0] == 255) { pt_ball.x = w; pt_ball.y = h; cvSeqPush( point_seq, &pt_ball ); num_i ++; } } } int sum_point = num_i; int color_templ[4*6*3] //色彩盒 = { 0,0,121, 93,0,158, 91,20,237, 255,61,255, 170,110,240, 200,161,245, 76,0,13, 113,52,0, 127,91,0, 188,114,0, 203,140,68, 236,211,190, 38,88,0, 77,118,46, 66,130,98, 112,182,46, 118,197,124, 174,221,178, 19,57,96, 10,98,163, 0,160,171, 0,242,255, 59,245,255, 139,247,255 }; double pos = 5.0; CvSeq* labels = 0; double threshold = pos*pos; int class_count = cvSeqPartition( point_seq, 0, &labels, is_equal, &threshold ); //显示相关 std::cout << "there're " << class_count << " clusters"; int class_num = 0; num_i = 0; for(int h = 0; h < img->height; h++) { for(int w = 0; w < img->width; w++) { if(( (uchar*) (img->imageData + h * img->widthStep) )[w * img->nChannels + 0] == 255) { class_num = *(int*)cvGetSeqElem( labels, num_i ); num_i ++; ((UCHAR *)(display->imageData + h*display->widthStep))[w*3 + 0] = color_templ[(((class_num))%4)*18 + ((class_num/4 + 3)%6)*3 + 0]; ((UCHAR *)(display->imageData + h*display->widthStep))[w*3 + 1] = color_templ[(((class_num))%4)*18 + ((class_num/4 + 3)%6)*3 + 1]; ((UCHAR *)(display->imageData + h*display->widthStep))[w*3 + 2] = color_templ[(((class_num))%4)*18 + ((class_num/4 + 3)%6)*3 + 2]; } } } cvNamedWindow("display", -1); cvShowImage("display", display); cvWaitKey(0); int * pBoundaries = new int [4*class_count]; //0: head 1: bottom 2: left 3: right for(int i = 0; i < class_count; i++) //赋初值 { pBoundaries[4*i + 0] = img->height + 1; pBoundaries[4*i + 1] = 0; pBoundaries[4*i + 2] = img->width + 1; pBoundaries[4*i + 3] = 0; } num_i = 0; for(int h = 0; h < img->height; h++) { for(int w = 0; w < img->width; w++) { if(( (uchar*) (img->imageData + h * img->widthStep) )[w * img->nChannels + 0] == 255) { class_num = *(int*)cvGetSeqElem( labels, num_i ); num_i++; //进行赋值 if(h < pBoundaries[4*class_num + 0]) { pBoundaries[4*class_num + 0] = h; } if(h > pBoundaries[4*class_num + 1]) { pBoundaries[4*class_num + 1] = h; } if(w < pBoundaries[4*class_num + 2]) { pBoundaries[4*class_num + 2] = w; } if(w > pBoundaries[4*class_num + 3]) { pBoundaries[4*class_num + 3] = w; } } } } //将最终区域存储 int numOfPatch = 0; for(int i = 0; i < class_count; i++) { if( (pBoundaries[4*i+1] - pBoundaries[4*i+0] > img->height/20) && (pBoundaries[4*i+3] - pBoundaries[4*i+2] > img->width/20) ) { numOfPatch ++; //此番循环之得到个数 } } int * pPatch = new int[4*numOfPatch]; int temp_i = 0; for(int i = 0; i < class_count; i++) { if( (pBoundaries[4*i+1] - pBoundaries[4*i+0] > img->height/10) && (pBoundaries[4*i+3] - pBoundaries[4*i+2] > img->width/10) ) { pPatch[4*temp_i + 0] = pBoundaries[4*i+0]; pPatch[4*temp_i + 1] = pBoundaries[4*i+1]; pPatch[4*temp_i + 2] = pBoundaries[4*i+2]; pPatch[4*temp_i + 3] = pBoundaries[4*i+3]; temp_i ++; } } *pNumOfPatch = numOfPatch; //释放内存 delete [] pBoundaries; //那些CvSeq的释放……………………………… cvReleaseMemStorage(& (labels->storage)); cvReleaseMemStorage(& storage);