歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> OpenCV實現分水嶺算法

OpenCV實現分水嶺算法

日期:2017/3/1 10:26:36   编辑:Linux編程

OpenCV實現分水嶺算法:

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