matlab影象處理--Otsu閾值分割
阿新 • • 發佈:2019-01-13
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);