二值法方法綜述及matlab程序


     在某些圖像處理當中一個關鍵步是二值法,二值化一方面能夠去除冗余信息,另一方面也會使有效信息丟失。所以有效的二值化算法是后續的處理的基礎。比如對於想要最大限度的保留下面圖的中文字,以便后續的定位處理。 二值化算法包括全局二值化和局部二值化, 全局二值化具有速度快但效果相對差的特點, 局部二值化算法具有速度慢效果好的特點。

 

PICTs0012

原圖

全局閾值             

方法一:直接采用im2bw ;手動閾值

方法二:迭代法求閾值

bw

    迭代式閾值選取的基本思路是:首先根據圖像中物體的灰度分布情況,選取一個近似閾值作為初始閾值,一個較好的方法就是將圖像的灰度均值作為初始閾值;然后通過分割圖像和修改閾值的迭代過程獲得認可的最佳閾值。迭代式閾值選取過程可描述如下。

(1)選取一個初始閾值T。

(2)利用閾值T把給定圖像分割成兩組圖像,記為R1和R2 。

(3)計算R1和R2 均值u1和 u2

(4)選取新的閾值T,且T=(u1+u2)/2

(5)重復第(2)~(4)步,直至R1和R2均值不再變化為止。

  具體實現時,首先根據初始開關函數將輸入圖逐個圖像分為前景和背景,在第一遍對圖像掃描結束后,平均兩個積分器的值以確定一個閾值。用這個閾值控制開關再次將輸入圖分為前景和背景,並用做新的開關函數。如此反復迭帶直到開關函數不在發生變化,此時得到的前景和背景即為最終分割結果。迭代所得的閾值分割的圖像效果良好。基於迭代的閾值能區分出圖像的前景和背景的主要區域所在,但在圖像的細微處還沒有很好的區分度。對某些特定圖像,微小數據的變化卻會引起分割效果的巨大改變,兩者的數據只是稍有變化,但分割效果卻反差極大。對於直方圖雙峰明顯,谷底較深的圖像,迭代方法可以較快地獲得滿意結果,但是對於直方圖雙峰不明顯,或圖像目標和背景比例差異懸殊,迭代法所選取的閾值不如其它方法。將全局平均值作為初始閾值,將圖像分為兩部分,求每部分的均值,迭代,直到這兩部分均值不在變化。

function [b1 ] = binary_iterate( f1 ) % 用迭代的方法對圖像進行二值化 t=mean(f1(:)); is_done=false; count=0; while ~is_done r1=f1(f1<=t); r2=f1(f1>t); temp1=mean(r1(:)); if isnan(temp1); temp1=0; end temp2=mean(r2(:)); if isnan(temp2) temp2=0; end t_new=(temp1+temp2)/2; is_done=abs(t_new-t)<1; t=t_new; count=count+1; if count>=1000 Error='Error:Cannot find the ideal threshold.' Return end end b1=im2bw(mat2gray(f1),t/256); end

方法三:居於最大類間差的方法----Otsu法

bw

     圖像記t為前景與背景的分割閾值,前景點數占圖像比例為w0,平均灰度為u0;背景點數占圖像比例為w1,平均灰度為u1,則圖像的總平均灰度為:u=w0*u0+w1*u1從最小灰度值到最大灰度值遍歷t,當t使得值g=w0*(u0-u)^2+w1*(u1-u)^2最大時t即為分割的最佳閾值。

    大津法可作如下理解:該式實際上就是類間方差值,閾值t 分割出的前景和背景兩部分構成了整幅圖像,而前景取值u0,概率為 w0,背景取值u1,概率為w1 ,總均值為u,根據方差的定義即得該式。因方差是灰度分布均勻性的一種度量,方差值越大,說明構成圖像的兩部分差別越大,當部分目標錯分為背景或部分背景錯分為目標都會導致兩部分差別變小,因此使類間方差最大的分割意味着錯分概率最小。直接應用大津法計算量較大,因此在實現時采用了等價的公式g=w0*w1*(u0-u1)^2第二,第三種方法得到的閾值相差不大,效果也類似,不能解決光照不均的局面。這是因為用全局閾值是無法根據每個特定的區域采用不同的閾值,於是只能嘗試采用局部閾值,或是對圖像進行預處理改進其直方圖特性。

function [b1,reT] =binary_otus( f1 ) % otus法二值化 [r c]=size(f1); gray_level=256; resultT=0; hist=zeros(gray_level,1); for i=1:r for j=1:c hist(f1(i,j)+1)=hist(f1(i,j)+1)+1; end end hist=hist/(r*c); vmax=0; for tt=1:gray_level T=tt-1; w0=0;w1=0;u0=0;u1=0;var=0;%重要的地方,在每次循環遍歷的時候。要把涉及到的變量清零。 for i=1:T+1 w0=w0+hist(i); u0=u0+(i-1)*hist(i); end u0=u0/w0; w1=1-w0; for j=T+2:gray_level u1=u1+(j-1)*hist(j); end u1=u1/w1; var=w0*w1*(u0-u1)^2; %     v(tt)=var; if var>vmax vmax=var; resultT=T; end end b1=im2bw(mat2gray(f1),resultT/255); reT=resultT/255; end

局部閾值法

方法四:分塊otus

 

 

   bw

   對圖像分塊,對每塊采用方法三最大類間差的方法處理,(改進的地方分塊的長寬不是一致的)設置的窗口為10*10.。 看上圖,明顯看到光照不均那段被檢測出來 了,但是缺點是要很好的設置好分塊的大小。而且圖片產生了偽影,多出了很多黑塊。怎么會出現這些黑塊呢?觀察后發現黑塊往往是在圖像灰度細節不夠豐富的區域產生。黑塊產生的原因一定是出在每個分塊采用的二值化方法--otsu算法。otsu算法更適合空間細節不豐富但灰度細節卻很豐富的圖像,因為這種圖像往往才會有明顯的類間距。對於灰度不豐富的圖像,otsu 得到的閾值較不理想。

function [ b1] = binary_part(gray_image,a,b) % 采用局部二值化,各個局部采用otus法 [m,n]=size(gray_image); result=zeros(m,n); for i=1:a:m for j=1:b:n if ((i+a)>m)&&((j+b)>n)     %分塊 block1=gray_image(i:end,j:end); %右下角區塊 elseif ((i+a)>m)&&((j+b)<=n) block1=gray_image(i:end,j:j+b-1); %最右列區塊 elseif ((i+a)<=m)&&((j+b)>n) block1=gray_image(i:i+a-1,j:end);  %最下行區塊 else block1=gray_image(i:i+a-1,j:j+b-1); %普通區塊 end [ block,~]=binary_otus(block1); if ((i+a)>m)&&((j+b)>n)            %合並結果 result(i:end,j:end)=block; elseif ((i+a)>m)&&((j+b)<=n) result(i:end,j:j+b-1)=block; elseif ((i+a)<=m)&&((j+b)>n) result(i:i+a-1,j:end)=block; else result(i:i+a-1,j:j+b-1)=block; end end end b1=result; end

方法五:ernsen算法

bw

    ernsen算法憑其優異的綜合性能, 在局部二值化領域占有重要一席, 它較適合解決光照不均的問題。這個算法的中心思想是:設當前像素為P,計算以P為中心的大小為(2w+1)*(2w+1)窗口內的所有像素的最大值M與最小值N,兩者的均值T,if(M-N)> S 則當前點P的閾值為T。else當前窗口所在區域的灰度級差別較小,那么窗口在目標區或在背景區,若T>T1則當前點灰度值為255,否則,當前點灰度值為0。S設為15, T1設為20。(這兩個值的設定還是需要根據具體的圖像具體分析)從上圖中可以看到bernsen方法能夠較為有效的解決光照不均的問題。美中不足的是這方法運行的時間太長,針對這一問題也有很多的改善的方法。

 

function [ b1 ] = binary_bernsen( f1 ) % 局部二值化方法,局部區域采用簡單閾值。 [m,n]=size(f1); s=15; t1=20; exI=uint8(ones(m+2,n+2));%擴展圖片,預分配一個矩陣 re=uint8(ones(m,n)); exI(2:m+1,2:n+1)=f1;%把原圖片賦給矩陣 %==========對矩陣進行填充==========% exI(1,:)=exI(2,:); exI(m+2,:)=exI(m+1,:); exI(:,1)=exI(:,2); exI(:,n+2)=exI(:,n+1); for i=2:m+1
    for j=2:n+1
        %===========求3*3區域內的閾值並對圖像進行二值化,結果存在re中==========% ma=max(max(exI(i-1:i+1,j-1:j+1))); mi=min(min(exI(i-1:i+1,j-1:j+1))); t=(ma+mi)/2; if ma-mi>s if exI(i,j)>t re(i-1,j-1)=255; else re(i-1,j-1)=0; end else 
            if t>t1 re(i-1,j-1)=255; else re(i-1,j-1)=0; end end end end b1=re; end

 

主函數:

clc; clear all; [fn pn fi]=uigetfile('*.*','choose a picture'); Img=imread([pn fn]); Img_gray=rgb2gray(Img); Img_bw=binary_bernsen(Img_gray);%這里修改對應的函數 figure; imshow(Img_bw); imwrite(Img_bw,'bw.jpg')


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM