1. 程式人生 > >matlab影象處理--Otsu閾值分割

matlab影象處理--Otsu閾值分割

Otsu演算法:取一個最優閾值把原影象分為前景色(A部分)與背景色(B部分),兩部分的類間方差越大,說明兩部分差別越大,便能有效的分割影象。所以該演算法最關鍵的是找到最優閾值。

方差:    例如  1,2,3,4,5

 

              先求均值:1/5(1+2+3+4+5)=3

 

              方差=1/5[(1-3)^2+(2-3)^2+(3-3)^2+(4-3)^2+(5-3)^2]=

              (上式能把1/5分別帶入相乘)

類間方差:與方差相似,求不同部分之間的方差      

               例如1,2,3,4,5。把1,2,3當成一個A部分,4,5當成B部分,由方差可知,需要得到總均值,A部分所有比例,B部分所佔比例,A部分值(即均值),B部分值(即均值)

              PA(A比例)=3/5           PB(B比例)=2/5

              ave_all(總均值)=3       ave_A(A均值)=1/3(1+2+3)       ave_B(B均值)=1/2(4+5) 

              類間方差=PA*(ave_A-ave_all)^2+PB*(ave_B-ave_all)^2(Otsu演算法)

 

公式程式碼如下:

 

close;clear;clc;
I=im2double(imread('coins.png'));  %變為雙精度,即0-1
subplot(221);imhist(I);            %顯示灰度直方圖
[M,N]=size(I);                     %得到影象行列畫素
number_all=M*N;                    %總畫素值
hui_all=0;                         %預設影象總灰度值為0
ICV_t=0;                           %預設最大方差為0
%得到影象總灰度值
for i=1:M
    for j=1:N
        hui_all=hui_all+I(i,j);
    end
end
all_ave=hui_all*255/number_all;   %影象灰度值的總平均值


%t為某個閾值,把原影象分為A部分(每個畫素值>=t)與B部分(每個畫素值<t)
for t=0:255                       %不斷試探最優t值
    hui_A=0;                      %不斷重置A部分總灰度值
    hui_B=0;                      %不斷重置B部分總灰度值
    number_A=0;                   %不斷重置A部分總畫素
    number_B=0;                   %不斷重置B部分總畫素
    for i=1:M                     %遍歷原影象每個畫素的灰度值
        for j=1:N
            if (I(i,j)*255>=t)    %分割出灰度值》=t的畫素
                number_A=number_A+1;  %得到A部分總畫素
                hui_A=hui_A+I(i,j);   %得到A部分總灰度值
            elseif (I(i,j)*255<t) %分割出灰度值《t的畫素
                number_B=number_B+1;  %得到B部分總畫素
                hui_B=hui_B+I(i,j);   %得到B部分總灰度值
            end
        end
    end
    PA=number_A/number_all;            %得到A部分畫素總數與影象總畫素的比列
    PB=number_B/number_all;            %得到B部分畫素總數與影象總畫素的比列
    A_ave=hui_A*255/number_A;          %得到A部分總灰度值與A部分總畫素的比例
    B_ave=hui_B*255/number_B;          %得到B部分總灰度值與B部分總畫素的比例
    ICV=PA*((A_ave-all_ave)^2)+PB*((B_ave-all_ave)^2);  %Otsu演算法
    if (ICV>ICV_t)                     %不斷判斷,得到最大方差
        ICV_t=ICV;
        k=t;                           %得到最大方差的最優閾值
    end
end
k                                      %顯示閾值

 

在MATLAB中自帶Otsu演算法,呼叫即可  

 

    k=graythresh(I)               %I為灰度影象。k為最優閾值,其大小在[0,1]之間 ,為雙精度型別         

    程式碼如下:

 close;clear;clc;
I=im2double(imread('coins.png'));
k=graythresh(I);              %得到最優閾值
J=im2bw(I,k);                  %轉換成二值圖,k為分割閾值
subplot(121);imshow(I); 
subplot(122);imshow(J);