/* chain function * this function does the actual processing */ static GstFlowReturn gst_pyramid_segment_chain (GstPad * pad, GstBuffer * buf) { GstPyramidSegment *filter; GstBuffer *outbuf; filter = GST_PYRAMID_SEGMENT (GST_OBJECT_PARENT (pad)); filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buf); filter->cvSegmentedImage = cvCloneImage (filter->cvImage); cvPyrSegmentation (filter->cvImage, filter->cvSegmentedImage, filter->storage, &(filter->comp), filter->level, filter->threshold1, filter->threshold2); /* TODO look if there is a way in opencv to reuse the image data and * delete only the struct headers. Would avoid a memcpy here */ outbuf = gst_buffer_new_and_alloc (filter->cvSegmentedImage->imageSize); gst_buffer_copy_metadata (outbuf, buf, GST_BUFFER_COPY_ALL); memcpy (GST_BUFFER_DATA (outbuf), filter->cvSegmentedImage->imageData, GST_BUFFER_SIZE (outbuf)); gst_buffer_unref (buf); cvReleaseImage (&filter->cvSegmentedImage); g_assert (filter->cvSegmentedImage == NULL); return gst_pad_push (filter->srcpad, outbuf); }
void f( IplImage* src, IplImage* dst ) { CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* comp = NULL; cvPyrSegmentation( src, dst, storage, &comp, 4, 200, 50 ); int n_comp = comp->total; for( int i=0; i<n_comp; i++ ) { CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem( comp, i ); // do_something_with( cc ); } cvReleaseMemStorage( &storage ); }
IplImage* BouyBaseObject::SegmentationMask(const IplImage * imgIn) const { IplImage * imgOut = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); IplImage * src = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); IplImage* hsv = cvCreateImage( cvGetSize(imgIn), 8, 3 ); IplImage * chan0 = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); IplImage * chan1 = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); IplImage * chan2 = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); IplImage * chan3 = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); cvCvtColor( imgIn, hsv, CV_BGR2YCrCb ); cvSplit(hsv,chan0,chan1,chan2, NULL); //cvConvertImage(imgIn,src); src = cvCloneImage(chan0); CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* comp = NULL; //lower last param for more segments cvPyrSegmentation( src, imgOut, storage, &comp, 3, 200, 50 ); cvAbsDiffS(imgOut,imgOut,CV_RGB(255,255,255)); //cvNormalize(imgOut,imgOut,255,0, CV_MINMAX); //cvThreshold(imgOut,imgOut,250,255,CV_THRESH_TOZERO); // int n_comp = comp->total; // for( int i=0; i<n_comp; i++ ) // { // CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem( comp, i ); // cvDrawRect(imgOut,cvPoint(cc->rect.x,cc->rect.y),cvPoint(cc->rect.x+cc->rect.width,cc->rect.y+cc->rect.height),CV_RGB(255,255,255)); // //do_something_with( cc ); // } cvReleaseImage(&src); cvReleaseImage(&hsv); cvReleaseImage(&chan0); cvReleaseImage(&chan1); cvReleaseImage(&chan2); cvReleaseImage(&chan3); cvReleaseMemStorage( &storage ); return imgOut; }
//对序列中的每个元素进行操作,此序列的元素是由cvPyrSegmentation返回的连续区域 void f( IplImage* src, IplImage* dst ) { // 分配存储区域,storage指针指向opencv存储区 CvMemStorage* storage = cvCreateMemStorage(0); // 序列的初始位置 CvSeq* comp = NULL; // 金字塔处理,参数分别为:输入、输出、存储、位置指针、金字塔层数、建立连接时的错误阈值,分割簇的错误阈值 // 建立连接时的错误阈值:小于等于该值得点连接;分割簇的错误阈值:小于等于该值的点看做一个区域 cvPyrSegmentation( src, dst, storage, &comp, 4, 200, 50 ); // 获取序列元素的个数 int n_comp = comp->total; for( int i=0; i<n_comp; i++ ) { // 依次获得每一个元素的值 CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem( comp, i ); // do_something_with( cc ); // 这里可以做点什么 } // 释放内存 cvReleaseMemStorage( &storage ); }
IplImage* BouyObject::SegmentationMask2(const IplImage * imgIn, IplImage* debugOut) const { // CvSize imageSize = cvSize(imgIn->width & -2, imgIn->height & -2 ); // IplImage* imgSmallCopy = cvCreateImage( cvSize(imageSize.width/2, imageSize.height/2), IPL_DEPTH_8U, 1 ); IplImage * imgOut = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); IplImage * circleMask = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); IplImage * src = cvCloneImage(imgIn); IplImage * scratch = cvCloneImage(src); IplImage * hist = HistogramMask(imgIn); //IplImage * bestMask = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* comp = NULL; CvFont font; cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, .5,.5); std::ostringstream s; cvZero(imgOut); cvZero(circleMask); cvZero(scratch); //cvZero(bestMask); CvScalar avgColor; double bestColor = -1; CvRect bestRect; double bestDiag = 0; // IplImage* hsv = cvCreateImage( cvGetSize(imgIn), 8, 3 ); // IplImage * chan0 = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); // IplImage * segsum = cvCreateImage(cvGetSize(imgIn),IPL_DEPTH_8U, 1); //cvCvtColor( imgIn, hsv, CV_BGR2YCrCb ); //cvCopyImage(imgIn,hsv); //cvSplit(hsv,chan0,chan1,chan2, NULL); //cvConvertImage(imgIn,src); //lower last param for more segments //cvPyrSegmentation( hsv, scratch, storage, &comp, 3, 100, 90 ); cvPyrSegmentation( src, scratch, storage, &comp, 2, 0, 100); int n_comp = comp->total; std::list<CvBox2D> blobList; for( int i = n_comp-1; i>=1; i-- ) { CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem( comp, i ); cvAbsDiffS(scratch,src,cc->value); cvNot(src,src); cvThreshold(src,src,254,255,CV_THRESH_BINARY); blobList = VisionUtils::GetBlobBoxes(src,0.0008,.95,false); for(std::list<CvBox2D>::iterator it = blobList.begin(); it != blobList.end(); it++) { CvRect rect = VisionUtils::ToCvRect(*it); VisionUtils::MakeSquare(rect); double diagonal = sqrt(rect.width * rect.width + rect.height * rect.height); cvDrawCircle(circleMask,cvPoint(rect.x+rect.width/2.,rect.y+rect.height/2),diagonal/2.5,CV_RGB(255,255,255),CV_FILLED); avgColor = cvAvg (hist,circleMask); if((bestColor < 0 || bestColor < avgColor.val[0]) && avgColor.val[0] > mSegment2Threshold) { bestDiag = diagonal; bestColor = avgColor.val[0]; bestRect = rect; cvCopy(circleMask,imgOut); } //cvMinMaxLoc(imgIn,) cvZero(circleMask); } } if(debugOut && bestColor > 0) { s.clear(); s << "bestColor(" << bestColor << ") " << mType; cvPutText(debugOut,s.str().c_str(),cvPoint(bestRect.x+bestRect.width/2.,bestRect.y+bestRect.height/2),&font,CV_RGB(255,255,255)); cvDrawCircle(debugOut,cvPoint(bestRect.x+bestRect.width/2.,bestRect.y+bestRect.height/2),bestDiag/2.5,CV_RGB(255,255,255)); } // cvShowImage("best",bestMask); // cvWaitKey(0); //VisionUtils::ClearEdges(imgOut); cvReleaseImage(&scratch); cvReleaseImage(&src); cvReleaseImage(&hist); cvReleaseImage(&circleMask); cvReleaseMemStorage( &storage ); return imgOut; }
void CV_PyrSegmentationTest::run( int /*start_from*/ ) { const int level = 5; const double range = 20; int code = CvTS::OK; CvPoint _cp[] ={{33,33}, {43,33}, {43,43}, {33,43}}; CvPoint _cp2[] ={{50,50}, {70,50}, {70,70}, {50,70}}; CvPoint* cp = _cp; CvPoint* cp2 = _cp2; CvConnectedComp *dst_comp[3]; CvRect rect[3] = {{50,50,21,21}, {0,0,128,128}, {33,33,11,11}}; double a[3] = {441.0, 15822.0, 121.0}; /* ippiPoint cp3[] ={130,130, 150,130, 150,150, 130,150}; */ /* CvPoint cp[] ={0,0, 5,5, 5,0, 10,5, 10,0, 15,5, 15,0}; */ int nPoints = 4; int block_size = 1000; CvMemStorage *storage; /* storage for connected component writing */ CvSeq *comp; CvRNG* rng = ts->get_rng(); int i, j, iter; IplImage *image, *image_f, *image_s; CvSize size = {128, 128}; const int threshold1 = 50, threshold2 = 50; rect[1].width = size.width; rect[1].height = size.height; a[1] = size.width*size.height - a[0] - a[2]; OPENCV_CALL( storage = cvCreateMemStorage( block_size ) ); for( iter = 0; iter < 2; iter++ ) { int channels = iter == 0 ? 1 : 3; int mask[] = {0,0,0}; image = cvCreateImage(size, 8, channels ); image_s = cvCloneImage( image ); image_f = cvCloneImage( image ); if( channels == 1 ) { int color1 = 30, color2 = 110, color3 = 180; cvSet( image, cvScalarAll(color1)); cvFillPoly( image, &cp, &nPoints, 1, cvScalar(color2)); cvFillPoly( image, &cp2, &nPoints, 1, cvScalar(color3)); } else { CvScalar color1 = CV_RGB(30,30,30), color2 = CV_RGB(255,0,0), color3 = CV_RGB(0,255,0); assert( channels == 3 ); cvSet( image, color1 ); cvFillPoly( image, &cp, &nPoints, 1, color2); cvFillPoly( image, &cp2, &nPoints, 1, color3); } cvRandArr( rng, image_f, CV_RAND_UNI, cvScalarAll(0), cvScalarAll(range*2) ); cvAddWeighted( image, 1, image_f, 1, -range, image_f ); cvPyrSegmentation( image_f, image_s, storage, &comp, level, threshold1, threshold2 ); if(comp->total != 3) { ts->printf( CvTS::LOG, "The segmentation function returned %d (not 3) components\n", comp->total ); code = CvTS::FAIL_INVALID_OUTPUT; goto _exit_; } /* read the connected components */ dst_comp[0] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 0 ); dst_comp[1] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 1 ); dst_comp[2] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 2 ); /*{ for( i = 0; i < 3; i++ ) { CvRect r = dst_comp[i]->rect; cvRectangle( image_s, cvPoint(r.x,r.y), cvPoint(r.x+r.width,r.y+r.height), CV_RGB(255,255,255), 3, 8, 0 ); } cvNamedWindow( "test", 1 ); cvShowImage( "test", image_s ); cvWaitKey(0); }*/ code = cvTsCmpEps2( ts, image, image_s, 10, false, "the output image" ); if( code < 0 ) goto _exit_; for( i = 0; i < 3; i++) { for( j = 0; j < 3; j++ ) { if( !mask[j] && dst_comp[i]->area == a[j] && dst_comp[i]->rect.x == rect[j].x && dst_comp[i]->rect.y == rect[j].y && dst_comp[i]->rect.width == rect[j].width && dst_comp[i]->rect.height == rect[j].height ) { mask[j] = 1; break; } } if( j == 3 ) { ts->printf( CvTS::LOG, "The component #%d is incorrect\n", i ); code = CvTS::FAIL_BAD_ACCURACY; goto _exit_; } } cvReleaseImage(&image_f); cvReleaseImage(&image); cvReleaseImage(&image_s); } _exit_: cvReleaseMemStorage( &storage ); cvReleaseImage(&image_f); cvReleaseImage(&image); cvReleaseImage(&image_s); if( code < 0 ) ts->set_failed_test_info( code ); }
static int aPyrSegmentation(void* agr) { CvPoint _cp[] ={33,33, 43,33, 43,43, 33,43}; CvPoint _cp2[] ={50,50, 70,50, 70,70, 50,70}; CvPoint* cp = _cp; CvPoint* cp2 = _cp2; CvConnectedComp *dst_comp[3]; CvRect rect[3] = {50,50,21,21, 0,0,128,128, 33,33,11,11}; double a[3] = {441.0, 15822.0, 121.0}; /* ippiPoint cp3[] ={130,130, 150,130, 150,150, 130,150}; */ /* CvPoint cp[] ={0,0, 5,5, 5,0, 10,5, 10,0, 15,5, 15,0}; */ int chanels = (int)agr; /* number of the color chanels */ int width = 128; int height = 128; int nPoints = 4; int block_size = 1000; int color1 = 30, color2 = 110, color3 = 180; int level = 5; long diff, l; int code; CvMemStorage *storage; /* storage for connected component writing */ CvSeq *comp; double lower, upper; unsigned seed; char rand; AtsRandState state; int i,j; IplImage *image, *image_f, *image_s; CvSize size; uchar *f_cur, *f_row; uchar *row; uchar *cur; int threshold1, threshold2; code = TRS_OK; if(chanels != 1 && chanels != 3) return TRS_UNDEF; /* read tests params */ if(!trsiRead( &width, "128", "image width" )) return TRS_UNDEF; if(!trsiRead( &height, "128", "image height" )) return TRS_UNDEF; if(!trsiRead( &level, "5", "pyramid level" )) return TRS_UNDEF; /* create Image */ l = width*height; size.width = width; size.height = height; rect[1].height = height; rect[1].width = width; a[1] = l - a[0] - a[2]; image = cvCreateImage(cvSize(size.width, size.height), IPL_DEPTH_8U, chanels); image_s = cvCreateImage(cvSize(size.width, size.height), IPL_DEPTH_8U, chanels); memset(image->imageData, color1, chanels*l); image_f = cvCreateImage(cvSize(size.width, size.height), IPL_DEPTH_8U, chanels); OPENCV_CALL( storage = cvCreateMemStorage( block_size ) ); /* do noise */ upper = 20; lower = -upper; seed = 345753; atsRandInit( &state, lower, upper, seed ); /* segmentation by pyramid */ threshold1 = 50; threshold2 = 50; switch(chanels) { case 1: { cvFillPoly( image, &cp, &nPoints, 1, color2); cvFillPoly( image, &cp2, &nPoints, 1, color3); row = (uchar*)image->imageData; f_row = (uchar*)image_f->imageData; for(i = 0; i<size.height; i++) { cur = row; f_cur = f_row; for(j = 0; j<size.width; j++) { atsbRand8s( &state, &rand, 1); *(f_cur)=(uchar)((*cur) + rand); cur++; f_cur++; } row+=image->widthStep; f_row+=image_f->widthStep; } cvPyrSegmentation( image_f, image_s, storage, &comp, level, threshold1, threshold2 ); //if(comp->total != 3) { code = TRS_FAIL; goto exit; } /* read the connected components */ /*dst_comp[0] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 0 ); dst_comp[1] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 1 ); dst_comp[2] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 2 );*/ break; } case 3: { cvFillPoly( image, &cp, &nPoints, 1, CV_RGB(color2,color2,color2)); cvFillPoly( image, &cp2, &nPoints, 1, CV_RGB(color3,color3,color3)); row = (uchar*)image->imageData; f_row = (uchar*)image_f->imageData; for(i = 0; i<size.height; i++) { cur = row; f_cur = f_row; for(j = 0; j<size.width; j++) { atsbRand8s( &state, &rand, 1); *(f_cur)=(uchar)((*cur) + rand); atsbRand8s( &state, &rand, 1); *(f_cur+1)=(uchar)(*(cur+1) + rand); atsbRand8s( &state, &rand, 1); *(f_cur+2)=(uchar)(*(cur+2) + rand); cur+=3; f_cur+=3; } row+=image->widthStep; f_row+=image_f->widthStep; } cvPyrSegmentation(image_f, image_s, storage, &comp, level, threshold1, threshold2); /* read the connected components */ if(comp->total != 3) { code = TRS_FAIL; goto exit; } dst_comp[0] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 0 ); dst_comp[1] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 1 ); dst_comp[2] = (CvConnectedComp*)CV_GET_SEQ_ELEM( CvConnectedComp, comp, 2 ); break; } } diff = 0; /*diff = atsCompare1Db( (uchar*)image->imageData, (uchar*)image_s->imageData, chanels*l, 4); for(i = 0; i < 3; i++) { if(dst_comp[i]->area != a[i]) diff++; if(dst_comp[i]->rect.x != rect[i].x) diff++; if(dst_comp[i]->rect.y != rect[i].y) diff++; if(dst_comp[i]->rect.width != rect[i].width) diff++; if(dst_comp[i]->rect.height != rect[i].height) diff++; }*/ trsWrite( ATS_CON | ATS_LST | ATS_SUM, "upper =%f diff =%ld \n",upper, diff); if(diff > 0 ) code = TRS_FAIL; else code = TRS_OK; exit: cvReleaseMemStorage( &storage ); cvReleaseImage(&image_f); cvReleaseImage(&image); cvReleaseImage(&image_s); /* trsFree(cp); */ /* _getch(); */ return code; }