OpenCV实现分水岭算法:
// 分水岭算法原理 // IplImage* marker_mask = 0; IplImage* markers = 0; //IplImage* img0 = 0, *img = 0, *img_gray = 0, *wshed = 0; IplImage *img_gray = 0, *wshed = 0; CvPoint prev_pt = {-1,-1}; void on_mouse( int event, int x, int y, int flags, void* param ) { if( !img ) return; if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) ) prev_pt = cvPoint(-1,-1); else if( event == CV_EVENT_LBUTTONDOWN ) prev_pt = cvPoint(x,y); else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) ) { CvPoint pt = cvPoint(x,y); if( prev_pt.x < 0 ) prev_pt = pt; cvLine( marker_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 ); cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 ); prev_pt = pt; cvShowImage( "image", img ); } } void CCVMFCView::OnWatershed()//分水岭 { int flag=0; CvRNG rng = cvRNG(-1); img0 = cvCloneImage( workImg ); // 建立工作位图 cvFlip(img0); cvNamedWindow( "image", 1 ); // cvNamedWindow( "watershed transform", 1 ); img = cvCloneImage( img0 ); img_gray = cvCloneImage( img0 ); wshed = cvCloneImage( img0 ); marker_mask = cvCreateImage( cvGetSize(img), 8, 1 ); markers = cvCreateImage( cvGetSize(img), IPL_DEPTH_32S, 1 ); cvCvtColor( img, marker_mask, CV_BGR2GRAY ); cvCvtColor( marker_mask, img_gray, CV_GRAY2BGR ); cvZero( marker_mask ); cvZero( wshed ); cvShowImage( "image", img ); // cvShowImage( "watershed transform", wshed ); cvSetMouseCallback( "image", on_mouse, 0 ); m_ImageType=-3; for(;;) { int c = cvWaitKey(0); if( c == 27 ) { if (!flag) { // 未加标记 wshed = cvCloneImage( img0 ); } break; } if( c == 'r' ) { cvZero( marker_mask ); cvCopy( img0, img ); cvShowImage( "image", img ); } if( c == 'w' || c == '\r' ) { CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours = 0; CvMat* color_tab; int i, j, comp_count = 0; //cvSaveImage( "wshed_mask.png", marker_mask ); //marker_mask = cvLoadImage( "wshed_mask.png", 0 ); cvFindContours( marker_mask, storage, &contours, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); CvSeq* contourn = contours; int n; for (n=0; contourn != 0; contourn = contourn->h_next,n++) { } // 检查边界数 if (n) { // 已作标记才进行处理 cvZero( markers ); for( ; contours != 0; contours = contours->h_next, comp_count++ ) { cvDrawContours( markers, contours, cvScalarAll(comp_count+1), cvScalarAll(comp_count+1), -1, -1, 8, cvPoint(0,0) ); } color_tab = cvCreateMat( 1, comp_count, CV_8UC3 ); for( i = 0; i < comp_count; i++ ) { uchar* ptr = color_tab->data.ptr + i*3; ptr[0] = (uchar)(cvRandInt(&rng)%180 + 50); ptr[1] = (uchar)(cvRandInt(&rng)%180 + 50); ptr[2] = (uchar)(cvRandInt(&rng)%180 + 50); } { double t = (double)cvGetTickCount(); cvWatershed( img0, markers ); // 分水岭算法处理 t = (double)cvGetTickCount() - t; // printf( "exec time = %gms\n", t/(cvGetTickFrequency()*1000.) ); } // paint the watershed image for( i = 0; i < markers->height; i++ ) { for( j = 0; j < markers->width; j++ ) { int idx = CV_IMAGE_ELEM( markers, int, i, j ); uchar* dst = &CV_IMAGE_ELEM( wshed, uchar, i, j*3 ); if( idx == -1 ) dst[0] = dst[1] = dst[2] = (uchar)255; else if( idx <= 0 || idx > comp_count ) dst[0] = dst[1] = dst[2] = (uchar)0; // should not get here else { uchar* ptr = color_tab->data.ptr + (idx-1)*3; dst[0] = ptr[0]; dst[1] = ptr[1]; dst[2] = ptr[2]; } } } cvAddWeighted( wshed, 0.5, img_gray, 0.5, 0, wshed ); // 图像合成 // cvShowImage( "watershed transform", wshed ); cvReleaseMemStorage( &storage ); cvReleaseMat( &color_tab ); } else { // 未加标记 wshed = cvCloneImage( img0 ); } cvCopy(wshed,workImg); cvFlip(workImg); CClientDC dc(this); StretchDIBits(dc.m_hDC, // 刷新主窗口 0,0,workImg->width,workImg->height, 0,0,workImg->width,workImg->height, workImg->imageData,m_lpBmi,DIB_RGB_COLORS,SRCCOPY); flag=1; } } cvDestroyWindow( "image" ); cvReleaseImage(&img0); cvReleaseImage(&img); cvReleaseImage(&img_gray); cvReleaseImage(&marker_mask); cvReleaseImage(&markers); cvFlip(wshed); m_dibFlag=imageReplace(wshed,&workImg); Invalidate(); }OpenCV实现分水岭算法
内容版权声明:除非注明,否则皆为本站原创文章。