簡體   English   中英

如何檢測二進制圖像中的某種形狀(植物莖)?

[英]how can I detect a certain shape (plant stem) in a binary image?

當我被困了幾個小時試圖弄清楚如何根據葉子的莖旋轉圖像時,我正在研究一個基於形狀的葉子分類項目。

這是輸入圖像的示例。

樣本

我一直在嘗試使用 opencv 和 filter2D 使用不同的內核甚至 HoughLines 應用形態學變換,這是我迄今為止得到的結果。

檢測到的蒸汽

任何幫助將不勝感激,在此先感謝。


編輯

莖的 position 很重要,因為我要分類的葉子種類不同,所以我要完成的是將葉子放在垂直的 position 中,莖在底部。

我提供的圖像是閾值圖像,我將原始圖像留在這里。

在此處輸入圖像描述

我提供了第二個樣本,因為在這種特殊情況下,我無法將莖放在底部,所以它最終位於頂部。

在此處輸入圖像描述

樣品返回 2 度。

在此處輸入圖像描述

這是一個想法。 將橢圓擬合到閾值葉形(假設它長於寬)。

輸入:

在此處輸入圖像描述

import cv2
import numpy as np

# read image
img = cv2.imread('leaf.png')

# threshold on color
lower=(84,1,68)
upper=(84,1,68)
thresh = cv2.inRange(img, lower, upper)

# get contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)

# fit ellipse to leaf contours
ellipse = cv2.fitEllipse(big_contour)
(xc,yc), (d1,d2), angle = ellipse
print(xc,yc,d1,d1,angle)

# draw ellipse on copy of input
result = img.copy() 
cv2.ellipse(result, ellipse, (0,0,255), 1)

# save results
cv2.imwrite('leaf_threshold.png',thresh)
cv2.imwrite('leaf_ellipse.png',result)

# show results
cv2.imshow("thresh", thresh)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

閾值圖像:

在此處輸入圖像描述

橢圓圖像:

在此處輸入圖像描述 \

橢圓信息:

126.44944763183594 101.98369598388672 112.40930938720703 112.40930938720703 89.33087158203125

So angle = 89.33087158203125 deg (cw from -y axis, i.e. from the top) or 
   angle = 0.66912841796875 deg (ccw from the x axis, i.e. from right side)

添加:

這是一個更完整的解決方案。 但它假設葉子長於寬,因此橢圓長軸沿步進方向對齊。

葉1:

在此處輸入圖像描述

葉 2:

在此處輸入圖像描述

import cv2
import numpy as np

# read image
#img = cv2.imread('leaf1.jpg')
img = cv2.imread('leaf2.jpg')

# threshold on color
lower=(0,0,0)
upper=(130,190,140)
thresh = cv2.inRange(img, lower, upper)

# get contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)

# fit ellipse to leaf contours
ellipse = cv2.fitEllipse(big_contour)
(xc,yc), (d1,d2), angle = ellipse
print(xc,yc,d1,d1,angle)

# draw ellipse on copy of input
graphic = img.copy() 
cv2.ellipse(graphic, ellipse, (0,0,255), 1)


# rotate image so step points downward   
if angle >= 135 and angle <=180:
    result = cv2.rotate(img, cv2.ROTATE_180)
elif angle >= 45 and angle <135:
    result = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
elif angle >= 0 and angle <45:
    result = img.copy()
    

# save results
cv2.imwrite('leaf2_threshold.png',thresh)
cv2.imwrite('leaf2_ellipse.png',graphic)
cv2.imwrite('leaf2_result.png',result)

# show results
cv2.imshow("thresh", thresh)
cv2.imshow("graphic", graphic)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

葉 1 閾值:

在此處輸入圖像描述

葉 1 橢圓:

在此處輸入圖像描述

葉 1 旋轉:

在此處輸入圖像描述

葉 2 閾值:

在此處輸入圖像描述

葉 2 橢圓:

在此處輸入圖像描述

葉 2 旋轉:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM