項目開源部分代碼:Extract-inner-imagehtml
項目成果:git
- 設計了一套基於背光板(冷光片)和暗箱的圖像處理計數裝置,能夠對較規則目標進行計數,正確率可達99%(每計數500個);
- 對圓柱形、方形和圓形目標物體,利用距離變換和分水嶺算法分割圖像並提取出各個目標區域,再基於面積特徵,計算出目標個數;
- 對於環形物體,設計了一種提取環形目標物體中內環圖像的算法,將計算目標個數轉化爲計算內環圖像的個數;
- 利用C++語言和OpenCV庫實現了該系統的核心算法,並利用Qt設計了軟件界面。
軟件界面:github
算法選型:算法
- 第一期作圓柱形毛氈柱的計數時,首先想到的是滑窗(模板匹配),對於不一樣型號的圓柱形毛氈柱設定特定的模板,而後從左上到右下,遍歷0-180度,根據IOU來判斷是不是一個目標物體,可是對於T形或者L形的擺放會產生誤檢,區域生長算法也是由於沒法避免這種缺點而被淘汰,其次這種算法耗時太長;
- 接着打算直接對目標物體進行分割,嘗試了凹點分割和分水嶺算法,顧名思義,先找到粘連圖像的凹點,再按照必定的規則進行配對分割,可是當兩個圓柱形頂部或側面無縫相接時,是找不到這樣的凹點的,所以須要用到面積特徵來篩選,然而即便篩選事後也不能進行分割;一樣的分水嶺算法也是不能分割相鄰過於緊密的目標;
- 考慮到圓柱形的縱向橫截面積與矩形相似,所以嘗試了角點檢測算法來檢測矩形的四個頂點,實際效果中顯示有些角點未檢測到,而有些角點檢測了屢次。主要的緣由是圓柱形的側面並非嚴格的直角,會有一些弧度,所以這種方法不適用;
- 接着矩形的思路走,矩形有四條邊,所以想起是否能夠用霍夫變換檢測直線,將矩形的四條邊檢測出來,而後按照直線圍成的輪廓來判斷是不是目標物體,可是實際中的目標物體並非嚴格的直線,其次,先用canny邊緣檢測算法時,圖像中傾斜的目標物體的邊緣是鋸齒形狀的間斷的線,所以會出現無數多條誤檢直線,這個方法一樣pass;
- 最後選擇的是基於面積特徵的方法,基本思路是將圖像二值化後,目標區域處理爲白色,計算出圖像中的非零點,而後與一個目標的像素點相除求出目標物體個數。可是這種方法有一個很是明顯的缺點:由於毛氈是有彈性的,並非徹底規則的物體,因此對圖像總體計算像素點會累計很大的偏差。爲下降偏差,首先採用的是對二值化後的圖像進行邊緣處理,簡單求外部輪廓,而後將各個輪廓提取出來求取像素點並計算個數,再對全部個數求和。對算法進行測試時發現,當圖像中目標物體距離比較近時,檢測到的輪廓並很少,分割效果比較差。爲了提升目標的分割個數,換用基於標記的分水嶺算法對圖像進行分割,而後對分割後的圖像進行輪廓提取,結果顯示是可行的。
項目算法:函數
先對圖像灰度化,二值化,而後進行距離變換,再對變換後的圖像利用分水嶺算法分割,獲得帶有分割線,並對分割區域賦予隨機顏色獲得圖像src_water,用opencv自帶的findContours函數對src_water尋找輪廓contours,輪廓的參數爲RETR_LIST(即所有輪廓),從新建立一個原圖大小的全0圖像(黑色),經過遍歷contours中的輪廓,將輪廓內部所有填充爲白色,生成黑底白目標的mask,與原圖二值化後的圖像相與來提取出各個目標區域。測試
特別注意,本算法使用opencv中自帶的watershed時,原圖參數處的圖片爲原圖二值化後利用Gray2RGB函數將單通道二值圖轉換成三通道圖片。由於本算法涉及到面積特徵,經過這種方式能夠減小偏差。當目標物體顏色爲白色等淺色時,圖像的邊緣會出現陰影,watershed後邊緣會出現不少噪點,影響面積特徵。spa
提取算法的具體流程見下圖:設計
上述算法中當循環次數不符合條件時,繼續計算更新後的src_th的非零像素點的緣由是,分水嶺算法並非能徹底將目標物體所有分隔開,會將幾個目標物體分割在一塊兒,也會遺漏幾個目標,所以將提取到的目標在二值圖中刪除後,最後剩下的會是全黑圖或者幾個目標。3d
提取算法的結果圖以下:htm
該算法將計算目標個數轉化爲計算內環圖像的個數,所以核心是提取環形目標物體中內環圖像的算法,將背景和環形目標物體置爲一個顏色,內環圖像置爲另外一個顏色,算法流程圖以下:
該算法中findcontours的輪廓參數是RETR_EXTERNAL(外部輪廓),上述算法中當循環次數不符合條件時,繼續對更新後的src_th進行PickUp算法的緣由是同上。PickUp算法的理論結果圖以下:
PickUp算法的做用是消除間隙輪廓。當幾個目標物體距離太近,圍成一個封閉空間時,對該圖像求取輪廓會包含內部封閉空間,若是直接對提取出來的圖像src_temp進行兩個mask相與,相或操做,會出現下圖的錯誤,經過PickUp算法能夠將間隙輪廓、封閉空間消除。
PickUp算法的實際結果圖以下所示:
將內環圖像提取出來後,對圖像進行腐蝕操做,消除噪點,再對圖像求取輪廓,對輪廓進行計數統計從而獲得目標物體的個數。
項目程序總結:
- 項目中涉及到使用Opencv中的findcontours函數對二值圖尋找輪廓,二值圖以下圖左所示,findcontours函數以後的二值圖以下圖右所示。
- Opencv中形態學的腐蝕膨脹操做默認是對白色元素進行操做,膨脹,直觀上就是把白色區域擴大,腐蝕,與膨脹相反,縮小白色區域。