光照不均勻圖像分割技巧1——分塊閾值
點(diǎn)擊上方“程序員大白”,選擇“星標(biāo)”公眾號(hào)
重磅干貨,第一時(shí)間送達(dá)
前言
??在數(shù)字圖像處理中,圖像分割是很關(guān)鍵的一步,當(dāng)圖像質(zhì)量較好,光照很均勻的時(shí)候只需用全局閾值的方法就能很完美地完成圖像分割任務(wù),但是有些時(shí)候會(huì)遇到光照不均勻的現(xiàn)象,這個(gè)時(shí)候就需要用一些技巧才能達(dá)到比較好的分割效果,本文要介紹的是一種通過(guò)分塊閾值進(jìn)行分割的方法。
實(shí)例
??在進(jìn)入正題之前,我們先看一個(gè)實(shí)例,下面圖1和圖3為做硬幣面額識(shí)別拍攝的,可以看到,由于硬幣表面的反光以及打光角度的原因,圖片存在嚴(yán)重的光照不均現(xiàn)象。
??如果對(duì)兩幅圖像直接進(jìn)行全局閾值可以得到圖2和圖4的結(jié)果,可以看到分割的效果很差,比如第一幅,右上角的光照要強(qiáng)一些,而且右上角的硬幣存在一定的反光,灰度值整體偏高,導(dǎo)致最后分割效果很差。第二幅則是左邊部分光照太強(qiáng),左邊的硬幣分割效果很差。
??本文將用分塊閾值的方法解決這一問(wèn)題。

圖1 光照不均勻圖像1 ??????? 圖2 全局閾值處理結(jié)果

圖3 光照不均勻圖像2 ???????圖4 全局閾值處理結(jié)果
分塊閾值思路
??通過(guò)將圖像分割成若干塊,分別進(jìn)行閾值分割,可以在一定程度上解決光照或反射造成的不均勻影響。選擇的塊要足夠小,以便每個(gè)塊的光照都近似均勻的,這樣自動(dòng)閾值時(shí),在高灰度區(qū)域就會(huì)用高閾值分割,在低灰度區(qū)域就會(huì)用低閾值分割。
??圖5為分塊結(jié)果,示例中分塊與硬幣大小相當(dāng),分完塊之后就可以按塊進(jìn)行全局閾值法(這里采用常用的最大類間方差法,otsu法)處理了,但是需要注意的是有的塊中只有背景,這個(gè)時(shí)候需要進(jìn)行判斷,排除對(duì)這種塊的處理。
??對(duì)于這種塊的判斷,筆者嘗試過(guò)用otsu方法中提到的可分性度量:

?? 筆者在計(jì)算出各個(gè)塊的可分性度量之后,發(fā)現(xiàn)區(qū)分效果并不是很好,后來(lái)通過(guò)分析最大類間方差法,有個(gè)想法就是用分割閾值處的類間平均灰度差判斷圖像塊的可分性,當(dāng)圖像中只有背景或只有物體時(shí),由于灰度值比較接近,則用otsu法算出的“背景”和“前景”平均灰度差(類間灰度差)會(huì)很小,類間平均灰度差?Δm 的數(shù)學(xué)表達(dá)式如下:

??如圖5中各塊標(biāo)注的文字所示,T為分割閾值,d為類間平均灰度差,可以看到當(dāng)塊中只有背景時(shí),平均灰度差與有物體時(shí)相差很大,選取特征區(qū)分效果很好。本示例中,選灰度差20就能將兩種不同的塊很好的區(qū)分開(kāi)。

圖5 分塊情況
??之后僅對(duì)既有物體又有背景的塊進(jìn)行自動(dòng)閾值處理、二值化、填充孔洞,可以得到圖6的結(jié)果,可以看到每個(gè)硬幣都被很好的分割出來(lái)

圖6 分塊閾值處理結(jié)果
代碼
%功能:對(duì)一副圖像進(jìn)行分塊閾值,可解決光照不均分割不足的問(wèn)題%通過(guò)判斷類間灰度差以排除純背景或純物體的干擾%作者:wikiwen%日期:2017/10/24%平臺(tái):matlab R2014clc,clear;close all;rn=5;cn=5;I = rgb2gray(imread('d.jpg'));[R , C]=size(I);%分別返回行和列數(shù)rblk=R/rn;cblk=C/cn;%小塊的行數(shù)和列數(shù)x = 0:cblk:C;y = 0:rblk:R;M = meshgrid(x,y); %產(chǎn)生網(wǎng)格N = meshgrid(y,x); %產(chǎn)生網(wǎng)格imshow(I);hold onplot(x,N,'r'); %畫(huà)出水平橫線plot(M,y,'r'); %畫(huà)出垂直豎線T = zeros(rn,cn);dif = zeros(rn,cn);J = false(R,C);%初始化二值圖X = uint8(zeros(rblk,cblk));%分塊閾值,并判斷類間灰度差以排除純背景或純物體的干擾for r=1:rnfor c=1:cnr0=rblk*(r-1)+1;r1=rblk*r;c0=cblk*(c-1)+1;c1=cblk*c;X = I(r0:r1,c0:c1);T(r,c) = graythresh(X);[h,~] = histcounts(X,0:255);T_int =uint8(T(r,c)*255);dif(r,c) = graydiffer(h,T_int);%計(jì)算類間灰度差的函數(shù)略str = ['T=',num2str(T_int),' d=',num2str(dif(r,c))];text(c0+cblk/4,r0+rblk/2,str,'color','black');%顯示信息if dif(r,c)>20J(r0:r1,c0:c1) = ~im2bw(X,T(r,c));endendendJ = imfill(J,'holes');%填充孔洞figure;imshow(J)
%功能:計(jì)算一幅圖像前景和背景類間平均灰度差%輸入:直方圖數(shù)據(jù)h,分割閾值T%輸出:類間平均灰度差%作者:wikiwen%日期:2017/10/26function[differ] = graydiffer(h,T)s1 = sum(h(1:T));s2 = sum(h(T:255));n1 = 1:T;n2 = T:255;u1 = double(n1)*h(1:T)' / s1; %背景灰度均值u2 = double(n2)*h(T:255)' / s2; %前景灰度均值differ = uint8(u2-u1);end
推薦閱讀
關(guān)于程序員大白
程序員大白是一群哈工大,東北大學(xué),西湖大學(xué)和上海交通大學(xué)的碩士博士運(yùn)營(yíng)維護(hù)的號(hào),大家樂(lè)于分享高質(zhì)量文章,喜歡總結(jié)知識(shí),歡迎關(guān)注[程序員大白],大家一起學(xué)習(xí)進(jìn)步!

