【影象計數】基於matlab硬幣計數【含Matlab原始碼 683期】
一、簡介
本設計為硬幣影象識別統計裝置,通過數碼相機獲取平鋪無重疊堆積的硬幣的影象,並通過Matlab工具處理後統計硬幣的數目。
1 影象格式轉換
取的影象格式為RGB彩色影象,需要先將其轉換為8位256級的灰度影象。本程式採用Matlab的影象處理工具箱的函式rgb2gray來實現。
rgb2gray()
功能:
轉換RGB影象或顏色映像表為灰度影象。
語法:
I = rgb2gray(RGB)
newmap = rgb2gray(map)
2 去噪及特徵提取
圖1-2 灰度圖及其直方圖
上圖1-1為硬幣統計的區域性圖片,圖中可見,硬幣主體部分和背景以及影象有著明顯的區別,可以通過選取合適的閾值進行二值化,從而提取出硬幣的特徵。
圖1-2為此影象的直方圖,從圖中可見到比較明顯的閾值分界點,但是並不是非常的明顯,這是因為,圖中有很多的硬幣因為反光的緣故,導致主體部分有些發白,如圖1-3所示。
1.3灰度調整
對於這些發白部分,我們採用灰度調整及中值濾波進行處理,在matlab中,提供了兩個函式進行相應的操作,其中imadjust進行灰度調整,其用法如下
Imadjst(f,[low_in high_in],[low_out high_out],gamma)
Gamma所表示的意義:
1 -------- 凹曲線
<1 -------- 凸直線
=1 -------- 直線
medfilt2用於進行中值濾波處理,其用法如下
F=medfilt2(f,[m n]);
f為輸入影象
[m n]為中值濾波模板
F是中值濾波後輸出的影象。
圖4-1經過灰度調整及中值濾波後的影象如圖1-4所示,可見,經過中值濾波後,硬幣的主體部分有了較大的改善。
1.4二值化處理
經過濾波後,即可對影象進行二值化處理,首先,我們採用人工選擇閾值的方法進行二值化,由圖可見,對於本幅圖片,其合適的閾值在50~100之間,通過試驗,我們選取的值為80。
對影象二值化處理的程式如下:
[M,N]=size(F);
for x=1:M
for y=1:N
if F(x,y)<80
F(x,y)=0; %低於閾值的值黑
else
F(x,y)=255; %高於閾值的值白
end
end
end
處理後的影象如圖1-6所示:
1.5閾值分割
當然仍有許多模糊的硬幣管腳殘影,但已經將硬幣的主體很好的識別了出來,採用人工選擇閾值的方法雖然可以成功分離出硬幣的主體,但是這個閾值這是針對這張圖片有效,對於獲取的其它圖片,這個閾值並不能正確地對影象進行二值化處理,因此我們決定採用自動閾值分割的方法來對影象進行二值化。
我們所選用的自動閾值分割方法為Otsu法,它是一種使類間方差最大的自動確定閾值的方法,該方法具有簡單、處理速度快的特點,是一種常用的閾值選取方法。
在matlab中,提供了一個函式graythresh來實現Otsu法閾值分割,其用法如下:
T=graythresh(f);
其中,f為待進行閾值分割的灰度影象,T為返回的分割灰度比例,將其乘於256即為Otsu法劃定的分割閾值。
優化後的程式如下:
T=graythresh(F);
由圖中可見,噪聲被有效的濾除了,但是,去除了噪聲的同時,也使部分接觸緊密的硬幣在閉運算後可能連成一個整體,如圖1-8中的紅圈所示,因此在此後的識別統計中需要對其進行特殊的處理。
二、原始碼
clear all; close all; f=imread('yingbi2.jpg'); w=imshow(f);title('原影象'); F=rgb2gray(f); %真彩圖轉化為灰度圖 figure;imshow(F);title('灰度圖'); figure;imhist(F);title('直方圖'); F0 = imadjust(F,stretchlim(F),[0 1]); Ft=medfilt2(F0,[5 5]); figure;imshow(Ft);title('灰度調整,中值濾波後的影象'); figure;imhist(Ft);title('灰度調整,中值濾波後的直方圖'); T=graythresh(Ft); T=T*256-5; [M,N]=size(Ft); for x=1:M for y=1:N if Ft(x,y)<T Ft(x,y)=0; %低於閾值的值黑 else Ft(x,y)=255; %高於閾值的值白 end end end figure;imshow(Ft);title('二值化結果'); B=ones(10); F0=imclose(Ft,B); figure;imshow(F0);title('閉運算'); F1=imadjust(F0,[0,1],[1,0],1); figure;imshow(F1);title('反色'); %對影象貼標籤 [L N]=bwlabel(F1,8) Sum = []; %統計每個標籤的數量,有些硬幣可能會重疊在一起的情況一定要用此種方法 for i=1:N [r,c] = find(L==i); rc = [r c]; Num = length(rc); Sum([i])=Num; end
三、執行結果
四、備註
版本:2014a
完整程式碼或代寫加1564658423