回答
這裏有一些想法,可以讓你開始。我不想在OpenCV中編寫和調試C++的負載 - 通常人們會提出問題並且不會再次登錄,或者花費幾個小時來處理某些事情,然後他們告訴您他們提供的單個樣本映像根本沒有代表性他們的實際圖像和25分鐘解釋的方法完全不合適。
一個想法是形態膨脹 - 你可以這樣做,在這樣的命令行中使用ImageMagick的:
convert gappy.jpg -threshold 50% -morphology dilate disk:5 result.png
另一個想法可能是找到所有「行結束」像素與命中和小姐形態。這在OpenCV中可用,但我正在使用ImageMagick來保存編碼/調試。結構元素是這樣的:
希望你可以看到,第一個(最左邊的)結構元素表示東西線的西方端,並且所述第二個表示的北端南北線等。如果你還沒有得到它,最後一個是東西南西線的西南端。
基本上,我覺得行結束,然後用藍色像素擴張它們,疊加層到原:
convert gappy.jpg -threshold 50% \
\(+clone -morphology hmt lineends -morphology dilate disk:1 -fill blue -opaque white -transparent black \) \
-flatten result.png
這裏有一個特寫前後:
你還可以找到沒有鄰居的單身像素,使用「峯」結構元素,像這樣:
,然後你可以找到所有的峯值和紅色像素這樣的擴張他們:
convert gappy.jpg -threshold 50% \
\(+clone -morphology hmt Peaks:1.9 -fill red -morphology dilate disk:2 -opaque white -transparent black \) \
-flatten result.png
這裏前後特寫:
根據您的原始圖像的外觀,您可能會反覆應用上述想法,直到輪廓完整爲止 - 也許您可以通過充水並檢測輪廓「持有水」而沒有洪水到處填寫「泄漏」。
顯然你會做白色的紅色峯和藍色的線結束來完成你的輪廓 - 我只是用顏色來說明我的技術。
馬克Setchell的答案是一個有趣的方式來學習新的東西。我的方法非常簡單直接。
我從頭頂上獲得了以下解決方案。它涉及夾在兩個形態學操作
之間的簡單模糊運算我已經解釋了什麼我已經沿着代碼中完成:
#---- I converted the image to gray scale and then performed inverted binary threshold on it. ----
img = cv2.imread('leaf.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, 1)
#---- Next I performed morphological erosion for a rectangular structuring element of kernel size 7 ----
kernel = np.ones((7, 7),np.uint8)
erosion = cv2.morphologyEx(thresh, cv2.MORPH_ERODE, kernel, iterations = 2)
cv2.imshow('erosion', erosion)
#---- I then inverted this image and blurred it with a kernel size of 15. The reason for such a huge kernel is to obtain a smooth leaf edge ----
ret, thresh1 = cv2.threshold(erosion, 127, 255, 1)
blur = cv2.blur(thresh1, (15, 15))
cv2.imshow('blur', blur)
#---- I again performed another threshold on this image to get the central portion of the edge ----
ret, thresh2 = cv2.threshold(blur, 145, 255, 0)
#---- And then performed morphological erosion to thin the edge. For this I used an ellipse structuring element of kernel size 5 ----
kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
final = cv2.morphologyEx(thresh2, cv2.MORPH_ERODE, kernel1, iterations = 2)
cv2.imshow(final', final)
希望這有助於:)
這裏有一個稍微不同的方式來完成它使用ImageMagick
1)閾值和擴張輪廓
convert 8y0KL.jpg -threshold 50% -morphology dilate disk:11 step1.gif
2)較小的量
convert step1.gif -morphology erode disk:8 step2.gif
3)墊由1像素的所有周圍的黑色侵蝕,並用白色floodfill外部並所有除去填充1個像素大約
convert step2.gif -bordercolor black -border 1 -fill white -draw "color 0,0 floodfill" -alpha off -shave 1x1 step3.gif
4)以較小的量腐蝕並獲得過渡白色邊緣。請注意,我們從擴張11開始,然後我們侵蝕8,然後我們現在侵蝕3。所以8 + 3 = 11應該讓我們回到中線附近。
convert step3.gif -morphology erode disk:3 -morphology edgein diamond:1 step4.gif
5)創建動畫比較
convert -delay 50 8y0KL.jpg step4.gif -loop 0 animation.gif
有趣!它只是表明 - 我試圖保留這兩個中等大小的斑點在左上角! –
這裏還有一個建議,即是多 「的計算機視覺文學」 爲主。作爲經驗法則的預處理步驟,通常是減少所有邊緣以確保它們大約爲1個像素厚度的好主意。流行的邊緣細化方法是non-maximal suppression(NMS)。
然後,我將開始分析圖像,並找到我有的所有連接組件。 OpenCV已經提供了connectedComponents
函數。一旦確定了連通分量組,就可以爲每個組擬合貝塞爾曲線。將貝塞爾曲線擬合成一組二維點的自動方法可在Graphics Gem書中找到。他們的方法也有C代碼available。擬合貝塞爾曲線的目標是儘可能多地高度理解每個組件組。
接下來,你需要加入這些Bezier曲線一起。在Shpitalni and Lipson的工作中可以使用使用端點聚類連接線的方法。在那篇文章中,看一下他們的自適應聚類方法,名爲「實體鏈接和端點聚類」。
最後,將所有曲線組合在一起後,您可以擬合最終的貝塞爾曲線,所有點都必須得到一個漂亮自然的邊緣貼圖。
作爲一個附註,你可以在cartoon curve extraction看看Ming-Ming Cheng的作品。有可用於該方法here too基於OpenCV的代碼,而是將輸出以下一次應用到你的形象:
免責聲明:
我可以證明貝塞爾曲線擬合算法的性能,我個人使用它,它工作得很好。 Cheng的曲線提取算法的效果也很好,但是,由於使用了梯度檢測(這有一種使細線變粗的傾向),它會產生外形很薄的不好看的「斑點」。如果您可以找到解決此「增厚」效應的方法,則可以跳過Bezier曲線提取並直接跳入端點聚類以將曲線連接在一起。
希望這會有所幫助!
- 1. OpenCV-如何統一不同的輪廓,一個封閉輪廓
- 2. 顏色貼圖上的輪廓:不連續(Python)
- 3. 圖像的輪廓軸
- 4. 如何使用JavaCV識別另一輪廓內的輪廓?
- 5. HTML 5,CSS邊框輪廓不一致
- 6. 如何從輪廓恢復圖像?
- 7. 如何爲圖像添加輪廓?
- 8. WebGL並排圖像導致圖像輪廓
- 9. 使用python/PIL的圖像輪廓
- 10. 從圖像生成輪廓
- 11. 提取外部輪廓或圖像的輪廓在Python
- 12. 輪廓opencv:如何消除二進制圖像中的小輪廓
- 13. 如何生成輪廓圖?
- 14. 使用openCV查找圖像輪廓
- 15. 停止從不連續點繪製輪廓的pyplot.contour
- 16. 使用R的輪廓圖
- 17. 如何獲得輪廓的像素點?
- 18. 如何使頂部輪廓?
- 19. 每頁像輪廓
- 20. 如何顯示圖像(html,javascript)的地圖區域的輪廓?
- 21. 如何水平連接OpenCV輪廓?
- 22. 檢測圖像中的文字輪廓
- 23. 圖像分割中的輪廓完成
- 24. DrawString與圖像中的輪廓
- 25. 查找圖像的輪廓Python OpenCV
- 26. 如何使用Python替換圖像中的輪廓(矩形)和新圖像?
- 27. 如何使用透明度繪製PNG圖像輪廓(邊框)
- 28. 如何使用opencv在某個圖像中找到輪廓
- 29. 當輪廓不存在時,Matplotlib輪廓圖失敗
- 30. 如何計算輪廓的直方圖?
您可以嘗試擴張或適合花鍵/多項式輪廓點。 –
我試過膨脹和多項式方法,前者容易受噪音影響,最後一個不能完成這項任務,並且如果有任何方法可以獲得與給定曲線最接近的曲線? – wanger
形狀總是橢圓形的?例如,它可能是您正在尋找的廣場嗎? –