在OpenCV中自適應確定canny演算法的分割門限

來源:互聯網
上載者:User

   在OpenCV中用canny運算元進行邊緣檢測速度很快,不過有點不爽的就是高低閾值需要輸入。在matlab中,如果不指定閾值的話,由函數自適應確定,因此仿照matlab中的做法,對canny函數進行了修改,以便當使用者沒有指定高低閾值時,由函數自適應確定閾值。

我在OpenCv原碼庫中增加了一個函數,用於確定高低閾值。

view plaincopy to clipboardprint?
  1. // 仿照matlab,自適應求高低兩個門限   
  2. CV_IMPL void AdaptiveFindThreshold(CvMat *dx, CvMat *dy, double *low, double *high)  
  3. {  
  4.  CvSize size;  
  5.  IplImage *imge=0;  
  6.  int i,j;  
  7.  CvHistogram *hist;  
  8.  int hist_size = 255;  
  9.     float range_0[]={0,256};  
  10.     float* ranges[] = { range_0 };  
  11.  double  PercentOfPixelsNotEdges = 0.7;  
  12.  size = cvGetSize(dx);  
  13.  imge = cvCreateImage(size, IPL_DEPTH_32F, 1);  
  14.  // 計算邊緣的強度, 並存於映像中   
  15.  float maxv = 0;  
  16.  for(i = 0; i < size.height; i++ )  
  17.  {  
  18.   const short* _dx = (short*)(dx->data.ptr + dx->step*i);  
  19.         const short* _dy = (short*)(dy->data.ptr + dy->step*i);  
  20.   float* _image = (float *)(imge->imageData + imge->widthStep*i);  
  21.   for(j = 0; j < size.width; j++)  
  22.   {  
  23.    _image[j] = (float)(abs(_dx[j]) + abs(_dy[j]));  
  24.    maxv = maxv < _image[j] ? _image[j]: maxv;  
  25.   }  
  26.  }  
  27.    
  28.  // 計算長條圖   
  29.  range_0[1] = maxv;  
  30.  hist_size = (int)(hist_size > maxv ? maxv:hist_size);  
  31.  hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);  
  32.  cvCalcHist( &imge, hist, 0, NULL );  
  33.  int total = (int)(size.height * size.width * PercentOfPixelsNotEdges);  
  34.  float sum=0;  
  35.  int icount = hist->mat.dim[0].size;  
  36.    
  37.  float *h = (float*)cvPtr1D( hist->bins, 0 );  
  38.  for(i = 0; i < icount; i++)  
  39.  {  
  40.   sum += h[i];  
  41.   if( sum > total )  
  42.    break;   
  43.  }  
  44. // 計算高低門限   
  45.  *high = (i+1) * maxv / hist_size ;  
  46.  *low = *high * 0.4;  
  47.  cvReleaseImage( &imge );  
  48.  cvReleaseHist(&hist);  
  49. }  
  50.    
  51. 在把cvCanny函數進行以下修改。  
  52. 在函數體中,當程式用兩個sobel運算元計算完水平和垂直兩個方向的梯度強度過後加入以下代碼  
  53. // 自適應確定閾值   
  54.  if(low_thresh == -1 && high_thresh == -1)  
  55.  {  
  56.   AdaptiveFindThreshold(dx, dy, &low_thresh, &high_thresh);  
  57.  }  

// 仿照matlab,自適應求高低兩個門限<br />CV_IMPL void AdaptiveFindThreshold(CvMat *dx, CvMat *dy, double *low, double *high)<br />{<br /> CvSize size;<br /> IplImage *imge=0;<br /> int i,j;<br /> CvHistogram *hist;<br /> int hist_size = 255;<br /> float range_0[]={0,256};<br /> float* ranges[] = { range_0 };<br /> double PercentOfPixelsNotEdges = 0.7;<br /> size = cvGetSize(dx);<br /> imge = cvCreateImage(size, IPL_DEPTH_32F, 1);<br /> // 計算邊緣的強度, 並存於映像中<br /> float maxv = 0;<br /> for(i = 0; i < size.height; i++ )<br /> {<br /> const short* _dx = (short*)(dx->data.ptr + dx->step*i);<br /> const short* _dy = (short*)(dy->data.ptr + dy->step*i);<br /> float* _image = (float *)(imge->imageData + imge->widthStep*i);<br /> for(j = 0; j < size.width; j++)<br /> {<br /> _image[j] = (float)(abs(_dx[j]) + abs(_dy[j]));<br /> maxv = maxv < _image[j] ? _image[j]: maxv;<br /> }<br /> }</p><p> // 計算長條圖<br /> range_0[1] = maxv;<br /> hist_size = (int)(hist_size > maxv ? maxv:hist_size);<br /> hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);<br /> cvCalcHist( &imge, hist, 0, NULL );<br /> int total = (int)(size.height * size.width * PercentOfPixelsNotEdges);<br /> float sum=0;<br /> int icount = hist->mat.dim[0].size;</p><p> float *h = (float*)cvPtr1D( hist->bins, 0 );<br /> for(i = 0; i < icount; i++)<br /> {<br /> sum += h[i];<br /> if( sum > total )<br /> break;<br /> }<br />// 計算高低門限<br /> *high = (i+1) * maxv / hist_size ;<br /> *low = *high * 0.4;<br /> cvReleaseImage( &imge );<br /> cvReleaseHist(&hist);<br />}</p><p>在把cvCanny函數進行以下修改。<br />在函數體中,當程式用兩個sobel運算元計算完水平和垂直兩個方向的梯度強度過後加入以下代碼<br />// 自適應確定閾值<br /> if(low_thresh == -1 && high_thresh == -1)<br /> {<br /> AdaptiveFindThreshold(dx, dy, &low_thresh, &high_thresh);<br /> }

 這樣,在調用cvCanny函數時,指定高低門限為-1,則cvCanny函數就自適應確定門限。 最後,別忘了重新編譯cv庫,對lib和dll庫進行更新。that's all!http://blog.chinaunix.net/u/30231/showart_233944.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.