MATLAB--数字图像处理 Otsu算法(MATLAB原理验证)

简介: MATLAB--数字图像处理 Otsu算法(MATLAB原理验证)

概念

OTSU算法是由日本学者OTSU于1979年提出的一种对图像进行二值化的高效算法。(大津算法)

Otsu原理

对于图像 t (x,y),前景(即目标)和背景的分割阈值记作 T,属于前景的像素点数占整幅图像的比例记为 ω0,平均灰度为 μ0;背景像素点数占整幅图像的比例为 ω1,平均灰度为 μ1;整幅图像的平均灰度记为μ,类间方差记为g。
假设图像大小为M×N,图像中像素的灰度值小于阈值 T 的像素个数为 N0,像素灰度大于阈值T的像素个数为 N1在这里插入图片描述
注:(7)式是将(5)式代入(6)式得到的,我们的重点放在(7)式上。

Otsu用处

利用Otsu算法,我们可以得到一个阈值,利用该阈值对图像进行二值化等操作。相比于单阈值的固定阈值,otsu算法效果更好。

MATLAB中实现Otsu算法的是 garythresh()函数,一般都与im2bw()配套使用

例:

t=rgb2gray(imread('a1.jpg'));
x=graythresh(t);%获取otsu算得的阈值
t=im2bw(t,x);

graythresh()源码--MATLAB

function [level em] = graythresh(I)
%GRAYTHRESH Global image threshold using Otsu's method.
%   LEVEL = GRAYTHRESH(I) computes a global threshold (LEVEL) that can be
%   used to convert an intensity image to a binary image with IM2BW. LEVEL
%   is a normalized intensity value that lies in the range [0, 1].
%   GRAYTHRESH uses Otsu's method, which chooses the threshold to minimize
%   the intraclass variance of the thresholded black and white pixels.
%
%   [LEVEL EM] = GRAYTHRESH(I) returns effectiveness metric, EM, as the
%   second output argument. It indicates the effectiveness of thresholding
%   of the input image and it is in the range [0, 1]. The lower bound is
%   attainable only by images having a single gray level, and the upper
%   bound is attainable only by two-valued images.
%
%   Class Support
%   -------------
%   The input image I can be uint8, uint16, int16, single, or double, and it
%   must be nonsparse.  LEVEL and EM are double scalars. 
%
%   Example
%   -------
%       I = imread('coins.png');
%       level = graythresh(I);
%       BW = im2bw(I,level);
%       figure, imshow(BW)
%
narginchk(1,1);
validateattributes(I,{'uint8','uint16','double','single','int16'},{'nonsparse'}, ...
              mfilename,'I',1);

if ~isempty(I)
  % Convert all N-D arrays into a single column.  Convert to uint8 for
  % fastest histogram computation.
  I = im2uint8(I(:));
  num_bins = 256;
  counts = imhist(I,num_bins);
  
  % Variables names are chosen to be similar to the formulas in
  % the Otsu paper.
  p = counts / sum(counts);
  omega = cumsum(p);
  mu = cumsum(p .* (1:num_bins)');
  mu_t = mu(end);
  
  sigma_b_squared = (mu_t * omega - mu).^2 ./ (omega .* (1 - omega));

  % Find the location of the maximum value of sigma_b_squared.
  % The maximum may extend over several bins, so average together the
  % locations.  If maxval is NaN, meaning that sigma_b_squared is all NaN,
  % then return 0.
  maxval = max(sigma_b_squared);
  isfinite_maxval = isfinite(maxval);
  if isfinite_maxval
    idx = mean(find(sigma_b_squared == maxval));
    % Normalize the threshold to the range [0, 1].
    level = (idx - 1) / (num_bins - 1);
  else
    level = 0.0;
  end
else
  level = 0.0;
  isfinite_maxval = false;
end

% compute the effectiveness metric
if nargout > 1
  if isfinite_maxval
    em = maxval/(sum(p.*((1:num_bins).^2)') - mu_t^2);
  else
    em = 0;
  end
end

Ostu算法(个人实现 MATLAB版)

t=rgb2gray(imread('a1.jpg'));
[m,n]=size(t);

%counts为图片总像素个数值
counts=m*n;

%count是一个256行一列的矩阵 记录了每个灰度级上像素点的个数
count=imhist(t);

%每个灰度级上像素点占总像素点数量的比例(概率)
p=count/counts;

%cumsum 计算累加概率 
w0=cumsum(p);

%u  计算的是平均灰度  比如灰度级为0~125的平均灰度值
%(1:256)'  矩阵转置 1行256列转换为256行1列
u=cumsum(p.*(1:256)');

%u_end是全局平均灰度
u_end=u(end);

%d 求方差 d是256行一列的矩阵
d=(w0*u_end-u).^2./(w0.*(1-w0));

%在d中寻找为最大方差的灰度值 这里y是最大方差的灰度值
[x,y]=max(d);

%为了和im2bw配合使用 进行归一化
%x就是所得阈值
x=(y-1)/255

算法结果验证

t=rgb2gray(imread('a1.jpg'));
[m,n]=size(t);
counts=m*n;
count=imhist(t);
p=count/counts;
w1=cumsum(p);
u=cumsum(p.*(1:256)');
u_end=u(end);%u_end是全局平均灰度
d=(w1*u_end-u).^2./(w1.*(1-w1));
[x,y]=max(d);
x=(y-1)/255 %x就是所得阈值
xx=graythresh(t)%graythresh计算出的阈值

结果 

%自己编写的代码计算出的阈值
x =

    0.7569

%利用garythresh计算出的阈值
xx =

    0.7569

结论
该代码与gragthresh()计算出的阈值大体上完全一致!

疑点解惑

在我们自己编写的代码中,计算方差用的是下面的公式,
与原理中计算方差的公式( g=ω0ω1(μ0-μ1)^ )不一样
难道是原理错了?
哈哈
不是,其实都是一个公式,我们在代码中的公式只是原理公式的变形罢了,这是为了减少变量,提高运算速度。

%d 求方差 d是256行一列的矩阵
d=(w1*u_end-u).^2./(w1.*(1-w1));

公式变形

在这里插入图片描述
注意:上图中的u就是验证代码中的u_end,代表的是图像全局的平均灰度
而u是代表灰度值 T前面的平均灰度。
这里要注意图中的w0u0就是验证代码中的u,对每个灰度级数乘以对应的概率并累加,这是因为u0的计算公式是每个灰度级乘以对应的数量,再除以前面一共的像素数量,这里前面一共的像素数量可以用总量乘以前面占的概率w0。哈哈,对,就是这里,就可以把w0u0中的w0约掉,所以w0*u0==u(这里的u是验证代码中的u,代表灰度值乘以概率的累加值)

其实只需要知道g=w0w1(u1-u0)^2就行了,验证代码只是为了减少变量,做了一下变形,哎,数学还是要学好啊
下面在给个版本的验证算法,原理差不多,只是个别地方做了精简(其实现在看来,这个算法反而搞复杂了)

C=imread('h.jpg');   
C=rgb2gray(C);
%读取图像

figure,imshow(C);title('原始灰度图像');%绘原图

count=imhist(C);                       %直方图统计
subplot(1,3,1); 
imhist(C);                  %绘制直方图

[r,t]=size(C); 

%图像矩阵大小 

N=r*t;                                 %图像像素个数 

L=256;                                 %制定凸显灰度级为256 
count=count/N;                        
%各级灰度出现概率

for i=2:L 
    if count(i)~=0  ;       
st=i-1;         
break
    end
end
%以上循环语句实现寻找出现概率不为0的最小灰度值
for i=L:-1:1 
    
if count(i)~=0; 
    
nd=i-1;  

break   


end 

end 

%实现找出出现概率不为0的最大灰度值
f=count(st+1:nd+1); 

p=st;q=nd-st; 
%p和q分别是灰度的起始和结束值

u=0;

for i=1:q
    
    u=u+f(i)*(p+i-1); 
    
    ua(i)=u; 
    
end 
%计算图像的平均灰度值
for i=1:q 
    
    w(i)=sum(f(1:i)); 
    
end 

%计算出选择不同k的时候,A区域的概率 

d=(u*w-ua).^2./(w.*(1-w));   %求出不同k值时类间方差 

[y,tp]=max(d);                %求出最大方差对应的灰度值 

th=tp+p;
if th<=160     
th=tp+p; 
else     
th=160 
end                            %根据具体情况适当修正门限 

Y1=zeros(r,t); 
for i=1:r 
    
for j=1:t 
        X1(i,j)=double(C(i,j));    
        
end 
end 
for i=1:r     
for j=1:t     
if (X1(i,j)>=th)         
Y1(i,j)=X1(i,j);     
else Y1(i,j)=0;     
end 
end 
end 
%上面一段代码实现分割 
figure,imshow(Y1);title('灰度门限分割图像');
目录
相关文章
|
17天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
2天前
|
供应链 算法 调度
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。
|
10天前
|
存储 算法
基于HMM隐马尔可夫模型的金融数据预测算法matlab仿真
本项目基于HMM模型实现金融数据预测,包括模型训练与预测两部分。在MATLAB2022A上运行,通过计算状态转移和观测概率预测未来值,并绘制了预测值、真实值及预测误差的对比图。HMM模型适用于金融市场的时间序列分析,能够有效捕捉隐藏状态及其转换规律,为金融预测提供有力工具。
|
19天前
|
算法
基于GA遗传算法的PID控制器参数优化matlab建模与仿真
本项目基于遗传算法(GA)优化PID控制器参数,通过空间状态方程构建控制对象,自定义GA的选择、交叉、变异过程,以提高PID控制性能。与使用通用GA工具箱相比,此方法更灵活、针对性强。MATLAB2022A环境下测试,展示了GA优化前后PID控制效果的显著差异。核心代码实现了遗传算法的迭代优化过程,最终通过适应度函数评估并选择了最优PID参数,显著提升了系统响应速度和稳定性。
|
10天前
|
机器学习/深度学习 算法 信息无障碍
基于GoogleNet深度学习网络的手语识别算法matlab仿真
本项目展示了基于GoogleNet的深度学习手语识别算法,使用Matlab2022a实现。通过卷积神经网络(CNN)识别手语手势,如&quot;How are you&quot;、&quot;I am fine&quot;、&quot;I love you&quot;等。核心在于Inception模块,通过多尺度处理和1x1卷积减少计算量,提高效率。项目附带完整代码及操作视频。
|
16天前
|
算法
基于WOA鲸鱼优化的购售电收益与风险评估算法matlab仿真
本研究提出了一种基于鲸鱼优化算法(WOA)的购售电收益与风险评估算法。通过将售电公司购售电收益风险计算公式作为WOA的目标函数,经过迭代优化计算出最优购电策略。实验结果表明,在迭代次数超过10次后,风险价值收益优化值达到1715.1万元的最大值。WOA还确定了中长期市场、现货市场及可再生能源等不同市场的最优购电量,验证了算法的有效性。核心程序使用MATLAB2022a实现,通过多次迭代优化,实现了售电公司收益最大化和风险最小化的目标。
|
16天前
|
算法
通过matlab对比遗传算法优化前后染色体的变化情况
该程序使用MATLAB2022A实现遗传算法优化染色体的过程,通过迭代选择、交叉和变异操作,提高染色体适应度,优化解的质量,同时保持种群多样性,避免局部最优。代码展示了算法的核心流程,包括适应度计算、选择、交叉、变异等步骤,并通过图表直观展示了优化前后染色体的变化情况。
|
13天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于深度学习网络的宝石类型识别算法matlab仿真
本项目利用GoogLeNet深度学习网络进行宝石类型识别,实验包括收集多类宝石图像数据集并按7:1:2比例划分。使用Matlab2022a实现算法,提供含中文注释的完整代码及操作视频。GoogLeNet通过其独特的Inception模块,结合数据增强、学习率调整和正则化等优化手段,有效提升了宝石识别的准确性和效率。
|
19天前
|
算法 5G 数据安全/隐私保护
基于MIMO系统的PE-AltMin混合预编码算法matlab性能仿真
本文介绍了基于交替最小化(AltMin)算法的混合预编码技术在MIMO系统中的应用。通过Matlab 2022a仿真,展示了该算法在不同信噪比下的性能表现。核心程序实现了对预编码器和组合器的优化,有效降低了硬件复杂度,同时保持了接近全数字预编码的性能。仿真结果表明,该方法具有良好的鲁棒性和收敛性。
31 8
|
18天前
|
存储 人工智能 缓存
【AI系统】布局转换原理与算法
数据布局转换技术通过优化内存中数据的排布,提升程序执行效率,特别是对于缓存性能的影响显著。本文介绍了数据在内存中的排布方式,包括内存对齐、大小端存储等概念,并详细探讨了张量数据在内存中的排布,如行优先与列优先排布,以及在深度学习中常见的NCHW与NHWC两种数据布局方式。这些布局方式的选择直接影响到程序的性能,尤其是在GPU和CPU上的表现。此外,还讨论了连续与非连续张量的概念及其对性能的影响。
42 3
下一篇
DataWorks