OpenCV实现分水岭算法


OpenCV实现分水岭算法:

  1. //  分水岭算法原理   
  2. //     
  3.   
  4. IplImage* marker_mask = 0;  
  5. IplImage* markers = 0;  
  6. //IplImage* img0 = 0, *img = 0, *img_gray = 0, *wshed = 0;   
  7. IplImage  *img_gray = 0, *wshed = 0;  
  8. CvPoint prev_pt = {-1,-1};  
  9.   
  10. void on_mouse( int event, int x, int y, int flags, void* param )  
  11. {  
  12.     if( !img )  
  13.         return;  
  14.   
  15.     if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )  
  16.         prev_pt = cvPoint(-1,-1);  
  17.     else if( event == CV_EVENT_LBUTTONDOWN )  
  18.         prev_pt = cvPoint(x,y);  
  19.     else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )  
  20.     {  
  21.         CvPoint pt = cvPoint(x,y);  
  22.         if( prev_pt.x < 0 )  
  23.             prev_pt = pt;  
  24.         cvLine( marker_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );  
  25.         cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );  
  26.         prev_pt = pt;  
  27.         cvShowImage( "image", img );  
  28.     }  
  29. }  
  30.   
  31. void CCVMFCView::OnWatershed()//分水岭   
  32. {  
  33.     int   flag=0;  
  34.     CvRNG rng = cvRNG(-1);  
  35.   
  36.     img0 = cvCloneImage( workImg );         //  建立工作位图   
  37.     cvFlip(img0);  
  38.   
  39.     cvNamedWindow( "image", 1 );  
  40.     //  cvNamedWindow( "watershed transform", 1 );   
  41.   
  42.     img = cvCloneImage( img0 );  
  43.     img_gray = cvCloneImage( img0 );  
  44.     wshed = cvCloneImage( img0 );  
  45.     marker_mask = cvCreateImage( cvGetSize(img), 8, 1 );  
  46.     markers = cvCreateImage( cvGetSize(img), IPL_DEPTH_32S, 1 );  
  47.     cvCvtColor( img, marker_mask, CV_BGR2GRAY );  
  48.     cvCvtColor( marker_mask, img_gray, CV_GRAY2BGR );  
  49.   
  50.     cvZero( marker_mask );  
  51.     cvZero( wshed );  
  52.     cvShowImage( "image", img );  
  53.     //  cvShowImage( "watershed transform", wshed );   
  54.     cvSetMouseCallback( "image", on_mouse, 0 );  
  55.   
  56.     m_ImageType=-3;  
  57.     for(;;)  
  58.     {  
  59.         int c = cvWaitKey(0);  
  60.   
  61.         if( c == 27 ) {  
  62.             if (!flag) {                    //  未加标记   
  63.                 wshed = cvCloneImage( img0 );  
  64.             }  
  65.             break;  
  66.         }  
  67.   
  68.         if( c == 'r' )  
  69.         {  
  70.             cvZero( marker_mask );  
  71.             cvCopy( img0, img );  
  72.             cvShowImage( "image", img );  
  73.         }  
  74.   
  75.         if( c == 'w' || c == '\r' )  
  76.         {  
  77.             CvMemStorage* storage = cvCreateMemStorage(0);  
  78.             CvSeq* contours = 0;  
  79.             CvMat* color_tab;  
  80.             int i, j, comp_count = 0;  
  81.             //cvSaveImage( "wshed_mask.png", marker_mask );   
  82.             //marker_mask = cvLoadImage( "wshed_mask.png", 0 );   
  83.             cvFindContours( marker_mask, storage, &contours, sizeof(CvContour),  
  84.                 CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );  
  85.   
  86.             CvSeq* contourn = contours;  
  87.             int n;  
  88.             for (n=0; contourn != 0; contourn = contourn->h_next,n++) {  
  89.             }                               //  检查边界数   
  90.             if (n) {                        //  已作标记才进行处理                
  91.                 cvZero( markers );  
  92.                 for( ; contours != 0; contours = contours->h_next, comp_count++ )  
  93.                 {  
  94.                     cvDrawContours( markers, contours, cvScalarAll(comp_count+1),  
  95.                         cvScalarAll(comp_count+1), -1, -1, 8, cvPoint(0,0) );  
  96.                 }  
  97.   
  98.                 color_tab = cvCreateMat( 1, comp_count, CV_8UC3 );  
  99.                 for( i = 0; i < comp_count; i++ )  
  100.                 {  
  101.                     uchar* ptr = color_tab->data.ptr + i*3;  
  102.                     ptr[0] = (uchar)(cvRandInt(&rng)%180 + 50);  
  103.                     ptr[1] = (uchar)(cvRandInt(&rng)%180 + 50);  
  104.                     ptr[2] = (uchar)(cvRandInt(&rng)%180 + 50);  
  105.                 }  
  106.   
  107.                 {  
  108.                     double t = (double)cvGetTickCount();  
  109.                     cvWatershed( img0, markers );  //  分水岭算法处理   
  110.                     t = (double)cvGetTickCount() - t;  
  111.                     //                  printf( "exec time = %gms\n", t/(cvGetTickFrequency()*1000.) );   
  112.                 }  
  113.   
  114.                 // paint the watershed image   
  115.                 for( i = 0; i < markers->height; i++ ) {  
  116.                     for( j = 0; j < markers->width; j++ )  
  117.                     {  
  118.                         int idx = CV_IMAGE_ELEM( markers, int, i, j );  
  119.                         uchar* dst = &CV_IMAGE_ELEM( wshed, uchar, i, j*3 );  
  120.                         if( idx == -1 )  
  121.                             dst[0] = dst[1] = dst[2] = (uchar)255;  
  122.                         else if( idx <= 0 || idx > comp_count )  
  123.                             dst[0] = dst[1] = dst[2] = (uchar)0; // should not get here   
  124.                         else  
  125.                         {  
  126.                             uchar* ptr = color_tab->data.ptr + (idx-1)*3;  
  127.                             dst[0] = ptr[0]; dst[1] = ptr[1]; dst[2] = ptr[2];  
  128.                         }  
  129.                     }  
  130.                 }  
  131.   
  132.                 cvAddWeighted( wshed, 0.5, img_gray, 0.5, 0, wshed );  //  图像合成   
  133.                 //              cvShowImage( "watershed transform", wshed );   
  134.                 cvReleaseMemStorage( &storage );  
  135.                 cvReleaseMat( &color_tab );  
  136.             }  
  137.             else {                          //  未加标记   
  138.                 wshed = cvCloneImage( img0 );  
  139.             }  
  140.             cvCopy(wshed,workImg);  
  141.             cvFlip(workImg);  
  142.   
  143.             CClientDC dc(this);  
  144.             StretchDIBits(dc.m_hDC,         //  刷新主窗口   
  145.                 0,0,workImg->width,workImg->height,  
  146.                 0,0,workImg->width,workImg->height,  
  147.                 workImg->imageData,m_lpBmi,DIB_RGB_COLORS,SRCCOPY);  
  148.             flag=1;  
  149.         }  
  150.     }  
  151.   
  152.     cvDestroyWindow( "image" );  
  153.     cvReleaseImage(&img0);  
  154.     cvReleaseImage(&img);  
  155.     cvReleaseImage(&img_gray);  
  156.     cvReleaseImage(&marker_mask);  
  157.     cvReleaseImage(&markers);  
  158.   
  159.     cvFlip(wshed);  
  160.     m_dibFlag=imageReplace(wshed,&workImg);  
  161.   
  162.     Invalidate();  
  163. }  

相关内容