2012-07-17 26 views
1

這是我的源圖像(忽略點,他們以後手工添加):如何確定最佳參數cvCanny多邊形逼近

enter image description here

我的目標是獲得的粗略多邊形逼近兩隻手。事情是這樣的:

enter image description here

我對如何做這樣的總體思路;我想用cvCanny查找邊緣,cvFindContours查找輪廓,然後用cvApproxPoly

我面臨的問題是我不知道如何正確使用cvCanny,特別是,我應該使用最後3個參數(threshold1 & 2,apertureSize)?我試過了:

cvCanny(source, cannyProcessedImage, 20, 40, 3); 

但是結果不理想。左手看上去比較精緻,但對於右手它檢測到非常少:

enter image description here

一般來說它不可靠的,因爲我想。有沒有辦法猜測Canny的「最佳」參數,或者至少有一個詳細的解釋(初學者可以理解)他們做了什麼,以便我可以做出有根據的猜測?或者有更好的方法可以完全做到這一點?

回答

4

也許最簡單的解決方案之一就是使Otsu在灰度圖像上進行閾值處理,找到二值圖像上的輪廓並且比它們近似。這裏是代碼:

Mat img = imread("test.png"), gray; 
vector<Vec4i> hierarchy; 
vector<vector<Point2i> > contours; 

cvtColor(img, gray, CV_BGR2GRAY); 
threshold(gray, gray, 0, 255, THRESH_OTSU); 
findContours(gray, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); 

for(size_t i=0; i<contours.size(); i++) 
{ 
    approxPolyDP(contours[i], contours[i], 5, false); 
    drawContours(img, contours, i, Scalar(0,0,255)); 
} 

imshow("result", img); 
waitKey(); 

這是結果:

enter image description here

+0

謝謝,這是更簡單和有效! – houbysoft 2012-07-17 16:29:35

6

看來你必須降低閾值。

上遲滯閾值的Canny算子工作:它選擇一個輪廓如果至少一個像素被作爲最大閾值,較爲明亮,需要所有所連接的輪廓象素,如果他們是高於下門限。

論文建議以2:1或3:1的比例(例如10和30,或20和60等)採用兩個閾值。對於某些應用程序,手動和硬編碼確定的閾值就足夠了。它也可能是你的情況。我懷疑如果你降低門檻,你會得到很好的結果,因爲圖像並不複雜。

一些方法來自動確定最佳精明的門檻已經被提出。他們中的大多數依賴於梯度幅度來估計最佳閾值。

步驟:

  • 提取梯度(索貝爾是一個不錯的選擇)
  • 你可以將它轉換爲UCHAR。漸變的漸變可以有比255更大的數值,但沒關係。 opencv的索貝爾迴歸祖國。
  • 製作結果圖像的直方圖。
  • 在您的直方圖的第95個百分點處取最大閾值,並將下限定爲高/ 3。
  • 你應該根據你的應用程序可能調整百分位值,但效果會比一個硬編碼HIG值和低值
  • 更強大

注:一個優秀的閾值檢測算法在Matlab實現。它基於上面的想法,但有點複雜。

注2:如果輪廓和照度在圖像區域之間沒有很大的變化,這種方法將起作用。如果輪廓在圖像的某個部分更清晰,那麼您需要局部自適應閾值,這是另一個故事。但看着你的照片,它不應該是這樣。

+0

謝謝你的解釋,我現在更好地理解它。 +1。我選擇了另一個答案作爲接受的答案,因爲這對我來說更簡單。 – houbysoft 2012-07-17 16:30:02