CV_IMPL CvSeq* cvSegmentImage(const CvArr* srcarr, CvArr* dstarr, double canny_threshold, double ffill_threshold, CvMemStorage* storage) { CvSeq* root = 0; CvMat* gray = 0; CvMat* canny = 0; //CvMat* temp = 0; void* stack = 0; CV_FUNCNAME("cvSegmentImage"); __BEGIN__; CvMat srcstub, *src; CvMat dststub, *dst; CvMat* mask; CvSize size; CvPoint pt; int ffill_lw_up = cvRound(fabs(ffill_threshold)); CvSeq* prev_seq = 0; CV_CALL(src = cvGetMat(srcarr, &srcstub)); CV_CALL(dst = cvGetMat(dstarr, &dststub)); size = cvGetSize(src); CV_CALL(gray = cvCreateMat(size.height, size.width, CV_8UC1)); CV_CALL(canny = cvCreateMat(size.height, size.width, CV_8UC1)); //CV_CALL( temp = cvCreateMat( size.height/2, size.width/2, CV_8UC3 )); CV_CALL(stack = cvAlloc(size.width * size.height * sizeof(Seg))); cvCvtColor(src, gray, CV_BGR2GRAY); cvCanny(gray, canny, 0/*canny_threshold*0.4*/, canny_threshold, 3); cvThreshold(canny, canny, 1, 1, CV_THRESH_BINARY); //cvZero( canny ); //color_derv( src, canny, canny_threshold ); //cvPyrDown( src, temp ); //cvPyrUp( temp, dst ); //src = dst; mask = canny; // a new name for new role // make a non-zero border. cvRectangle(mask, cvPoint(0, 0), cvPoint(size.width - 1, size.height - 1), cvScalarAll(1), 1); for (pt.y = 0; pt.y < size.height; pt.y++) { for (pt.x = 0; pt.x < size.width; pt.x++) { if (mask->data.ptr[mask->step* pt.y + pt.x] == 0) { CvConnectedComp region; int avgVal[3] = { 0, 0, 0 }; icvSegmFloodFill_Stage1(src->data.ptr, src->step, mask->data.ptr, mask->step, size, pt, avgVal, ffill_lw_up, ffill_lw_up, ®ion, stack); /*avgVal[0] = (avgVal[0] + 15) & -32; if( avgVal[0] > 255 ) avgVal[0] = 255; avgVal[1] = (avgVal[1] + 15) & -32; if( avgVal[1] > 255 ) avgVal[1] = 255; avgVal[2] = (avgVal[2] + 15) & -32; if( avgVal[2] > 255 ) avgVal[2] = 255;*/ if (storage) { CvSeq* tmpseq = icvGetComponent(mask->data.ptr, mask->step, region.rect, storage); if (tmpseq != 0) { ((CvContour*)tmpseq)->color = avgVal[0] + (avgVal[1] << 8) + (avgVal[2] << 16); tmpseq->h_prev = prev_seq; if (prev_seq) { prev_seq->h_next = tmpseq; } else { root = tmpseq; } prev_seq = tmpseq; } } icvSegmFloodFill_Stage2(dst->data.ptr, dst->step, mask->data.ptr, mask->step, size, avgVal, region.rect); } } } __END__; //cvReleaseMat( &temp ); cvReleaseMat(&gray); cvReleaseMat(&canny); cvFree(&stack); return root; }
CV_IMPL void cvSegmentImage( const CvArr* srcarr, CvArr* dstarr, double canny_threshold, double ffill_threshold ) { CvMat* gray = 0; CvMat* canny = 0; void* stack = 0; CV_FUNCNAME( "cvSegmentImage" ); __BEGIN__; CvMat srcstub, *src; CvMat dststub, *dst; CvMat* mask; CvSize size; CvPoint pt; int ffill_lw_up = cvRound( fabs(ffill_threshold) ); CV_CALL( src = cvGetMat( srcarr, &srcstub )); CV_CALL( dst = cvGetMat( dstarr, &dststub )); if( src->data.ptr != dst->data.ptr ) { CV_CALL( cvCopy( src, dst )); src = dst; } size = cvGetSize( src ); CV_CALL( gray = cvCreateMat( size.height, size.width, CV_8UC1 )); CV_CALL( canny = cvCreateMat( size.height, size.width, CV_8UC1 )); CV_CALL( stack = cvAlloc( size.width * size.height * sizeof(Seg))); cvCvtColor( src, gray, CV_BGR2GRAY ); cvCanny( gray, canny, 0, canny_threshold, 5 ); mask = canny; // a new name for new role // make a non-zero border. cvRectangle( mask, cvPoint(0,0), cvPoint(size.width-1,size.height-1), 1, 1 ); for( pt.y = 0; pt.y < size.height; pt.y++ ) { for( pt.x = 0; pt.x < size.width; pt.x++ ) { if( mask->data.ptr[mask->step*pt.y + pt.x] == 0 ) { CvConnectedComp region; int avgVal[3] = { 0, 0, 0 }; icvSegmFloodFill_Stage1( src->data.ptr, src->step, mask->data.ptr, mask->step, size, pt, avgVal, ffill_lw_up, ffill_lw_up, ®ion, stack ); icvSegmFloodFill_Stage2( src->data.ptr, src->step, mask->data.ptr, mask->step, size, avgVal, region.rect ); } } } __END__; cvReleaseMat( &gray ); cvReleaseMat( &canny ); cvFree( &stack ); }