Matlab实现简单的图像阈值分割,分离背景与前景

  1. 要求

基于图像的灰度直方图,计算分割双峰的阈值,实现灰度图像前景和背景的分离。分离后的图像矩阵中,前景和背景用0和1表示。

  1. 显示灰度图像

对于有3通道的RGB图像,需要预先使用rgb2gray函数将其转换为单通道的灰度图像。对于灰度图像,通过给定的算法也可以将其转换成为RGB图像,如

Matlab实现简单的图像阈值分割,分离背景与前景
clear, close all
% RGB图像需要使用rgb2gray处理
% I_rgb = imread('peppers.png');
% I = rgb2gray(I_rgb);
% 灰度图像不需要处理
I = imread('cameraman.tif');
figure, imshow(I), title('原图');

Matlab实现简单的图像阈值分割,分离背景与前景
  1. 绘制灰度直方图

Maltab提供了imhist函数,可以绘制灰度图像的直方图

figure, imhist(I), title('灰度直方图');

Matlab实现简单的图像阈值分割,分离背景与前景

可以看到,该图像的灰度直方图大致有两个波峰,分别在15和160附近,表示这个图像的大多数像素点的灰度值都分布在15和160附近。

  1. 手工寻找阈值

Matlab实现简单的图像阈值分割,分离背景与前景
gray_min = 73;                 % 分割阈值
I(I < gray_min) = 0;           % 低于阈值的置0
I(I >= gray_min) = 1;          % 大于等于阈值的置1
figure, imshow(I, []), title('前景背景分割图');

Matlab实现简单的图像阈值分割,分离背景与前景
  1. 自动搜索阈值

5.1 现实问题

当图片数量较少的时候,我们可以通过手工寻找两个波峰之间的波谷的方法,确定一个较合适的阈值,但是当图片数量成百上千时,就需要一个自动寻找阈值的方法。

5.2 搜索算法

这里我们基于一个理想化条件:图像的灰度直方图有且仅有两个波峰,不存在多峰或单峰的情况。

于是,当灰度直方图有且仅有两个波峰时,可以将自动搜索阈值的算法简化成如下几步:

Step 1:获取每个灰度值对应的像素点个数,由此组成数组counts,counts(1)表示灰度值为0的像素点的个数;

Step 2:在counts数组中搜索,确定两个波峰counts(a)和counts(b)以及它们的位置a和b;

Step 3: 在counts中,从a到b搜索最小值counts(c)(对应波谷),将其对应的灰度值c-1作为最佳阈值。

5.3 代码实现

对于 Step1,我们可以使用imhist函数来获取每个灰度值对于的像素点个数

[counts, ~] = imhist(I);       % 获取每个灰度值对应的像素点个数

对于 Step2,单纯搜索counts中的前2个最大值往往无法奏效。对于当前的灰度直方图来说,波峰1附近的峰仍然高于波峰2

Matlab实现简单的图像阈值分割,分离背景与前景

于是我想到可以使用maltab自带的函数maxk,在counts中选出前K个最大值,记录下他们对应的最小灰度值和最大灰度值,分别作为搜索的起点search_start和终点search_end。

[~, index] = maxk(counts, 50); % 选取前50个最大值的索引
search_start = min(index);     % 搜索起点
search_end = max(index);       % 搜索终点

为了更加方便快速的获取最佳阈值,我选择在不改动counts数组大小的基础上搜索最小值。

% 生成无效范围
index_range = [1:search_start search_end:256];
counts(index_range) = inf;     % 将无效范围的灰度值数量设置为最大,即inf
[~, index_min] = min(counts);  % 搜索最小counts对应的索引
gray_min = index_min - 1;      % 索引-1即为灰度值(分割阈值)

在counts数组中,只需要将范围以外的其他数设置为无穷大,接着在counts数组中寻找最小值对应的索引即可。matlab中正无穷大的符号是INFmin函数可以返回数组中的最小值和其对应的索引,这里我们不需要最小值(该灰度值对应的像素点个数),所以用~来表示不需要返回最小值。

I(I < gray_min) = 0;           % &#x4F4E;&#x4E8E;&#x9608;&#x503C;&#x7684;&#x7F6E;0
I(I >= gray_min) = 1;          % &#x5927;&#x4E8E;&#x7B49;&#x4E8E;&#x9608;&#x503C;&#x7684;&#x7F6E;1
figure, imshow(I, []), title('&#x524D;&#x666F;&#x80CC;&#x666F;&#x5206;&#x5272;&#x56FE;');

Matlab实现简单的图像阈值分割,分离背景与前景

5.4 稳定性检验

为了检验这个自动搜索阈值的算法是否具有普适性,我将图像更换为了matlab自带的彩色辣椒图,并将其转换为灰度图,分割结果如下。

Matlab实现简单的图像阈值分割,分离背景与前景
  1. 完整代码获取

Matlab实现简单的图像阈值分割,分离背景与前景

关注公众号,回复”数字图像处理”,即可获取完整代码。

Original: https://blog.csdn.net/qq_42276781/article/details/121962210
Author: Toblerone_Wind
Title: Matlab实现简单的图像阈值分割,分离背景与前景

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/529889/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球