4

我正在研究應用程序來識別圓形/橢圓形狀內的線狀特徵。形狀如下所示(在此示出了兩個):圖像特徵檢測

Shapes

  • 的形狀本身能夠圓和橢圓形之間略有不同。
  • 形狀內至多有5條線,它們在每個形狀的大致相同的區域中找到。
  • 這些線在長度,厚度,旋轉和曲率方面可能略有不同。
  • 這些線條有時可以輕觸/相交。
  • 通常有5個,但偶爾會有一行可能完全丟失。
  • 我不關心顏色,黑色和白色閾值罰款。

每個對象(100 +以上)將被視頻單獨捕獲;捕捉是手動/物理過程(即,我每次都拿着相機)。我可以完全控制相機,因此我可以爲每次拍攝定位。

現在我正在嘗試使用OpenCV來進行識別。我能夠修改示例「臉部識別」應用程序以使用另一個Haar標識符XML文件,但這似乎只能處理外部圓/橢圓的檢測。

我對產生每個樣品的對象信息,描述該5條內部線以用於進一步處理:

{ 
    1: { length: 20, avg_thick: 2.3 }, 
    2: { length: 4, avg_thick: 2.0 }, 
    3: { length: 9.1, avg_thick: 2.1 }, 
    4: { length: 2, avg_thick: 1.9 }, 
    5: { length: 17, avg_thick: 2.1 } 
} 

這是我的第一個項目,涉及圖像識別。我應該使用哪些算法或程序來進行研究?謝謝!

UPDATE:

由於圖像將通過手拍照,它們不是純的黑/白。嘗試應用閾值使得形狀內的(虛線)線條有時會消失。我怎樣才能改善閾值結果?

+1

你看過霍夫變換嗎? – WildCrustacean

+0

不,這是我第一個涉及圖像識別的項目,所以我全新的。我會閱讀有關的,謝謝。 – Harper

+0

它可能不適合這種應用,特別是如果線條彎曲,但值得一看。 – WildCrustacean

回答

4

如果線條近似直線,使用Hough transform找到所有的線條,和霍夫的圓形版本變換,以求各界/省略號(那麼你可以檢查被包圍圓/橢圓已經發現,以及哪些線在它內部)。

如果線條不直:你的意思是「狹長的區域」而不是線條,對吧? :)你將不得不骷髏(可能首先是閾值)。有用的教程:「Skeletonization using OpenCV-Python」。由於您需要寬度(=從骨架到邊緣的距離),請使用skimage.morphology.medial_axis(...,return_distance = True)。你可能還需要一些方法來通過每個骨架的分支並修剪短的分支(沒有任何現成的東西已經這樣做了,對不起)。

Haar類型的方法根本不起作用,它只適用於(即使在理論上)具有固定相對位置和形狀的特徵。您想要某種幾何特徵提取算法,而不是圖像識別。

編輯:在樣品Python代碼:

import numpy, scipy, scipy.ndimage, skimage.morphology, matplotlib.pyplot 

img = scipy.ndimage.imread("test.png") 

# quick and dirty threshold 
binary_img = img[:,:,0] < 0.1 

# skeletonize 
skel_binary, skel_distances = skimage.morphology.medial_axis(binary_img, return_distance=True) 

# find individual lines 
structure_element = scipy.ndimage.generate_binary_structure(2,2) 
skel_labels, num_skel_labels = scipy.ndimage.measurements.label(skel_binary, structure=structure_element) 

for n in range(1, num_skel_labels + 1): 
    # make a binary label for this line 
    line = (skel_labels == n) 
    # calculate width from skeleton 
    mean_width = 2 * numpy.mean(skel_distances[ line ]) 
    print "line %d: width %f" % (n, mean_width) 
    # you need some way to find the ends of a line 
    # perhaps the most distant pair of points? 

# show the labels 
# the circle is also labelled 
# you need some way to check which label is the circle and exclude that 
matplotlib.pyplot.imshow(skel_labels) 
matplotlib.pyplot.show() 

Output from program above

這一個版本的那些產生你上面貼還(檢查線寬作品)圖像合理的結果圖像放大了10倍。它不涉及相交線,也許你可以爲此做一個圖算法。此外,您還需要以某種方式排除外部圓圈(它似乎總是n = 1,因爲標籤是從左上角發現的,而第一個標籤區域是圓圈)。

編輯:如何(或是否)閾值是一個有趣的問題。您可以嘗試自動閾值處理,也許基於大津的方法,或基於高斯混合(example)。我認爲你可能會得到最好的結果與某種統計模型的背景和前景色亮度,結合局部自適應閾值。真的取決於你的圖像的性質。

+0

非常感謝您的幫助。您能否添加更多的細節並解決更新後的問題? – Harper

+0

非常好,謝謝! – Harper

1
  1. 鏤空圖像並跟蹤每一行,然後您將獲得每行的行數和長度。
  2. 對於每一行,計算面積(計算原始BW圖像中黑色像素的數量),然後將其除以長度以找出平均厚度。
+0

非常感謝您的幫助。您能否添加更多的細節並解決更新後的問題? – Harper