6

===解決===簡單的物體識別

感謝您的建議和意見。通過編寫Beginning Python Visualization書(第9章 - 圖像處理)中給出的flood_fill算法,我已經實現了我想要的。我可以計算對象,爲每個對象(因此是高度和寬度)獲取包圍矩形,最後可以爲每個對象構建NumPy數組或矩陣。

雖然它不是一個優化的方法,但它做我想要的。我使用的源代碼(lab2.py)和png文件(lab2-particles.png)已被置於http://code.google.com/p/ccnworks/source/browse/#svn/trunk/AtSc450之下。

您需要安裝NumPy和PIL,並使用matplotlib來查看直方圖。代碼的核心在於發生主要遞歸對象搜索操作的objfind函數內。

一個進一步的更新:

SciPy的的ndimage.label()不正是我想要的東西,太。

乾杯大衛 - 沃德法利扎卡里平從與NumPy和SciPy的郵件列表指出這直接進入我的眼睛:)

=========== ==

您好,

我有一個包含由粒子光譜儀測量冰顆粒的陰影的圖像。我希望能夠識別每個對象,以便以後可以在我的計算中對它們進行分類和使用。

本質上,我願意做的只是簡單地實現一個模糊選擇工具,我可以簡單地選擇每個實體。

我怎麼能輕鬆解決這個問題? (最好使用Python)

謝謝。

注:在我的問題中,我指的是每個特定的連接像素作爲對象或實體。我打算提取它們並創建NumPy數組表示,如下所示。 (這裏我使用左上角的對象;如果存在像素,則使用1,如果不使用0,則該對象的形狀爲3乘3,相應地3像素高3像素寬,這是真實冰粒在2D域上的投影,其爲球形和等效半徑的假設下是(高度+寬度)/ 2,和後來一些定標--from像素實際尺寸和體積計算將遵循)

import numpy as np 

np.array([[1,1,1], [1,1,1], [0,0,1]]) 

array([[1, 1, 1], 
     [1, 1, 1], 
     [0, 0, 1]]) 

下面是從一個部我將要使用的圖像。

screenshot http://img43.imageshack.us/img43/2327/particles.png

+5

對我而言,簡單的對象識別聽起來像是一個矛盾。 – Joren 2009-09-19 18:14:25

+0

你會建議什麼? – 2009-09-19 18:42:49

+3

請不要在你的問題中說「解決」。要麼接受最佳答案,要麼回答自己的問題並接受。 – Soviut 2012-04-03 23:52:24

回答

2

OpenCV有一個Python接口,你可能會發現有用。

+0

找到了這個:http://opencv.willowgarage.com/documentation/python/pattern_recognition.html 但是讓我感到困惑的是,例子不是很有幫助。 – 2009-09-19 18:45:37

5
  1. 掃描每個正方形(例如,從左上角,左到右,上到下的)

  2. 當你點擊一個藍色方塊則:

    一個。將此方塊記錄爲新對象的位置

    b。發現所有其它的連續藍色正方形(例如,通過看這個廣場的鄰居,這些鄰居的鄰居,等等),它們標記爲同一對象的一部分

  3. 繼續掃描

  4. 當您找到另一個藍色方塊時,請在進行第2步之前測試它是否是已知對象的一部分;或者在步驟2b,刪除任何方你有對象

+0

我正在考慮實施類似於您在此提及的內容。感謝您的清晰佈局比我:) – 2009-09-19 18:43:53

+0

有了一些幫助,我寫了一個簡單的flood_fill實現,並可以計算給定圖像上的對象數量(冰粒子陰影)。而且,是的,它包括我預期的遞歸。現在我想能夠構造代表每個對象的簡單numpy數組。 (如我的問題另外演示)最後,我正在考慮將所有這些數組添加到數組中,稍後我可以簡單地循環並獲取它們的形狀。形狀很重要,因爲我會將它們用於冰粒對象的高度和寬度。 – 2009-09-20 19:27:29

3

看着你所提供的圖像關聯後,你下一步需要做的是應用一個簡單的region growing algorithm

如果我使用MATLAB,我會用bwlabel/bwboundaries功能。我相信,在地方是一個同等功能numpy的,或使用OpenCV的與Python包裝由@kwatford

+0

SciPy包有一個類似的標記功能(http://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.measurements.label.html#scipy.ndimage.measurements.label),我可以標記所有正確使用它的像素。但這隻能解決問題的第一部分。我應該能夠分別區分每個實體。不幸的是,這沒有任何功能。需要寫出:) – 2009-09-19 18:48:36

+0

我理解它的方式是圖像中的每個藍色物體都是一個實體,對嗎? 然後通過將所有像素標註爲區域,您只需選擇標記爲1的所有像素,然後選擇標記爲2的像素,依次類推以獲取每個對象... 下一步將爲每個對象(邊界,形狀,面積,大小等),這將用於監督分類任務。 – Amro 2009-09-19 19:58:23

+0

我在註釋部分的問題中澄清了我對實體的用法。現在,我所要做的就是爲每個對象獲取邊界矩形或正方形,用於某些情況下的寬度和高度。 – 2009-09-20 19:40:41

3

的建議我用來做這種對顯微分析,並最終把我需要到圖像處理一切,用C編寫的分析包,通過Tcl驅動。 (它只處理512 x 512的圖像,這就解釋了爲什麼512經常出現這種情況,有些像素分配了各種大小的像素,但大部分工作是用8位像素完成的,這就解釋了爲什麼有0xff和圖像上最大有意義數254)

簡而言之,Tcl命令開始處的'zz'將行的其餘部分發送到包的解析器,該解析器使用給定的參數調用適當的C例程。 'zz'後面是一個表示命令輸入和輸出的參數。 (可以有多個輸入,但只有一個輸出。)'r'表示512 x 512 x 8位圖像。第三個單詞是要調用的命令的名稱; '圖'按照以下文字所述標記圖像。因此,'zz rr圖形'的意思是'調用ZZ解析器;輸入一個r圖像到圖形命令並取回一個r圖像。' Tcl命令行的其餘部分指定要使用哪個預分配映像。 ('g'圖像是ROI,即感興趣區域,圖像;幾乎所有的ZZ操作都是在ROI控制下完成的。)因此,'r1 r1 g8'表示'使用r1作爲輸入,使用r1作爲輸出即標記輸入圖像本身),然後在圖像g8 ---即r8用作ROI ---的相應像素>> 0的任何地方進行操作。

我不認爲它可以在任何地方在線,但如果你想通過源代碼挑選,甚至編譯整個shebang,我很樂意將它發送給你。下面是手冊的摘錄(但我認爲我在這個日期的手冊中看到一些錯誤---這令人尷尬......):

示例6.計數功能。

問題

計數的共同任務。計數的項目被稱爲「特徵」,通常需要仔細準備圖像,以便特徵與要計數的實際對象以一對一的方式對應。然而,在這裏,我們忽略了圖像準備,而是考慮了計數機制。第一次計數練習是找出目錄中的圖像上有多少個特徵./cells?

方法

首先,讓我們定義「特徵」。一個特徵是「set」(非零)像素的最大組,所有這些都可以通過沿着南北 - 東 - 西(上 - 下 - 右 - 左)路徑從一個集合像素行進到另一個達到,開始來自給定的像素。在圖像上檢測並標記這些特徵的zz命令是「zz rr graphs R:src R:dest G:ROI」,所謂的是因爲這種特徵的數學術語是「圖形」。如果圖像上的所有像素都已設置,則圖像上只有一個圖形,但它包含262144像素(512 * 512)。如果像素被設置並且以棋盤圖案清除(等於零),則將會有131072(512 * 512/2)個圖,但是每個圖僅包含一個像素。 簡單地說,「zz rr圖」開始於圖像的左上角,並從左到右掃描每一行,直到它找到一個設置的像素,然後查找所有設置的像素通過北,南,東,或西邊界(「4連接」)。然後它將該圖中的所有像素設置爲1(0x01)。在找到並標記圖形1後,它會在第一次發現圖形1後的像素之後的像素處再次開始掃描,這次忽略了任何已屬於圖形的像素。它找到的前254個圖將被標記爲唯一;但是之後發現的所有圖形都將標記爲255(0xff) ,因此無法相互區分。能夠準確計數任意數量圖形的關鍵是分階段處理每個圖像,即查找圖像上的圖形數量,如果數目大於254,則擦除剛剛找到的254個圖形,重複處理,直到找到254個或更少的圖。 Tcl語言提供了設置此操作控制的手段。

讓我們開始構建將RZ圖像文件讀入R圖像並檢測和標記圖形所需的命令。在處理循環之前,我們聲明並歸零一個變量來保存圖像序列中的特徵總數。在處理循環中,我們首先將圖像文件讀入R圖像並檢測並標記圖形。接下來,我們將一些變量歸零以跟蹤計數,然後使用「ra max」命令來確定是否檢測到超過254個圖。

set nGraphs [ zz ra max r1 a1 g1 ] 

如果nGraphs確實等於255,那麼254高精度地計數圖表應該被添加到總的,從1到254的曲線應該被擦除,並重復多次計數,因爲它需要減小下面255.

while {$nGraphs == 255} { 
    incr sumGraphs 254 
    zz rbr lt r1 155 r1 g1 0 255 
    set sumGraphs 0 
    zz rr graphs r1 r1 g8 
    set nGraphs [ zz ra max r1 a1 g8 ] 
} 

圖的數目。當「while」循環退出時,可變nGraphs必須持有大於255以下的數,也就是一個數準確計數的圖表;這會添加到圖像系列中功能數量的不斷上升中。

incr sumGraphs $nGraphs 

處理循環後,打印出系列中找到的特徵的總數。

puts 「Total number of features in $inDir \ 
images $beginImg through $endImg is $sumGraphs.」 

處理循環後,打印出系列中找到的特徵的總數。

+0

這是一個非常冗長的答案。需要一些時間才能掌握您的解釋:) – 2009-09-20 19:45:10

+0

請注意,我將第2段添加爲程序包的Tcl命令行語法的簡要介紹。這可能會幫助你「抓住」。 順便說一下,本手冊中還有其他一些示例,說明如何使用形態學操作準備圖像,然後在查找和計算特徵後,執行諸如製作其大小分佈的操作。 我從來沒有認真地嘗試過將它適用於Python,儘管它一直在我的腦海中做了一段時間。 – behindthefall 2009-09-21 00:18:15

+0

另外BTW:'圖表'基本上使用Paul Heckbert所着的Graphics Gems,Vol.I,第721頁的算法。 – behindthefall 2009-09-21 00:25:14

2

Connected component analysis可能是你在找什麼。

+0

我知道這項技術必須有一個新的:)感謝指針。 pygraph(http://code.google.com/p/python-graph/)和Python封裝的opencv都支持這些算法,但是它們的用法對我來說並不是很清楚。你有沒有使用過這些功能? – 2009-09-20 19:43:30