文章目录
- 一、什么是图像二值化以及为什么要做图像二值化?
- 二、阈值二值化算法
- 2.1 全局固定阈值
- 2.2 OTSU阈值
- 2.3 局部均值阈值法
- 2.4局部中值阈值法
- 三、FPGA实现局部均值阈值法
一、什么是图像二值化以及为什么要做图像二值化?
图像二值化是将灰度图像转换为只有两个值(通常是黑和白)的图像处理过程。二值化的基本思想是通过设定一个阈值,将图像中的像素分为这两类。所有高于阈值的像素被设为前景,而低于阈值的像素被设为背景。如下所示:
通常处理是将所有高于阈值的像素被设为前景(白色255),而低于阈值的像素被设为背景(黑色0),如下所示:
对于人眼观察图片来说,重点是看图像的清晰度、色彩、构图等等。而对于机器识别来说不能分辨这些元素,机器只关心的是图像的轮廓以及边缘。正如上图所示,二值化后的图片虽然只显示黑色和白色,但是对于我们依然能分辨出图像的内容是什么,这也有助于后面的机器识别,机器学习等等。
二值化的优点:
- 二值化将图像信息简化为两个值,减少了数据的复杂性,便于后续处理和分析。
- 由于数据量减少,后续的图像处理(如特征提取、物体识别等)速度更快。
- 二值化可以增强图像中对象与背景之间的对比,使得对象更加明显,便于识别和分析。
- 二值化是图像分割的一种基本方法,能够有效地将感兴趣的对象从背景中分离出来。
- 在某些应用中(如文档图像处理、二维码识别等),二值化是必要的步骤,因为这些应用通常只关注对象的形状和轮廓。
- 通过选择合适的阈值,二值化可以有效地减少图像中的噪声影响,从而提高后续处理的准确性。
二、阈值二值化算法
阈值二值化主要分为两大类:全局阈值和局部阈值。全局阈值又分:固定阈值、OTSU(大律法)、Kittler-Illingworth阈值法等等。局部阈值又分:均值阈值、中值阈值、高斯加权均值阈值等等。不同的阈值法,处理后的图像结果也大不相同。
2.1 全局固定阈值
顾名思义,就是一幅图像只用一个阈值例如127来判断。如果一个像素点的灰度值小于127,则赋值为0(黑色),如果灰度值大于127则赋值为255(白色),代码以及结果如下所示:
% 读取图像
img = imread('../../../...'); % 替换为你的图像文件名% 将图像转换为灰度图像(如果是彩色图像)
if size(img, 3) == 3grayImg = rgb2gray(img);
elsegrayImg = img;
end% 显示原始灰度图像
subplot(121);
imshow(grayImg);
title('原始灰度图像');% 设置固定阈值
threshold = 128; % 可以根据需要调整阈值% 应用全局固定阈值法
binaryImg = grayImg > threshold; % 生成二值图像% 将逻辑数组转换为uint8类型的二值图像
binaryImg = uint8(binaryImg) * 255; % 将逻辑值转换为0和255% 显示二值图像
subplot(122);
imshow(binaryImg);
title('二值化图像');
固定阈值需要找的一个合适的阈值,但是这样的局限性太大了,只能处理整幅亮度合适的图像。如果一幅图像整体过暗或者过亮,则并不适应,如下所示:
可以看到全局固定阈值的处理只适合光照均匀的图片。
2.2 OTSU阈值
Otsu阈值法是一种自动选择图像二值化阈值的技术,它通过最大化前景和背景之间的类间方差来确定最佳阈值。该方法由日本学者大津弘提出来的,也叫大律法。步骤如下:
-
首先,计算图像的灰度直方图,得到每个灰度级的像素数量。
-
再次,设定一个阈值T,将像素分为两类:前景(灰度值大于T)和背景(灰度值小于或等于T)
-
然后,计算前景和背景的平均灰度值和类间方差。类间方差的定义为: σ B 2 ( T ) = w 1 ( T ) ∗ w 2 ( T ) ∗ ( μ 1 ( T ) − μ 2 ( T ) ) 2 σ^2_B(T)=w_1(T)*w_2(T)*(μ_1(T)-μ_2(T))^2 σB2(T)=w1(T)∗w2(T)∗(μ1(T)−μ2(T))2
其中: w 1 ( T ) 和 w 2 ( T ) w_1(T)和w_2(T) w1(T)和w2(T)分别是前景和背景的权重(像素数量的比例), μ 1 ( T ) 和 μ 2 ( T ) μ_1(T)和μ_2(T) μ1(T)和μ2(T)分别是前景和背景的平均灰度值。 -
最大化类间方差,遍历所有可能的阈值T,计算对于的类间方差 σ B 2 ( T ) σ^2_B(T) σB2(T),选择使类间方差最大化的阈值Y作为阈值。
大律法不需要手动设置阈值,适用于不同的图像,在灰度直方图呈双峰分布的情况下,效果尤为显著。但是在噪声较多的图像中,可能会导致不准确的阈值选择以及对于单峰分布的图像,OTSU方法可能无法得到合适的阈值。
% 读取图像
img = imread('../../.../.....'); % 替换为你的图像文件名% 将图像转换为灰度图像(如果是彩色图像)
if size(img, 3) == 3grayImg = rgb2gray(img);
elsegrayImg = img;
end% 使用Otsu方法计算最佳阈值
threshold = graythresh(grayImg); % 返回的阈值在[0, 1]之间
threshold = threshold * 255; % 将其转换为0-255的范围% 应用阈值进行二值化
binaryImg = grayImg > threshold; % 生成二值图像
binaryImg = uint8(binaryImg) * 255; % 将逻辑值转换为0和255% 显示原始灰度图像和二值化图像
figure;% 原始灰度图像
subplot(1, 2, 1); % 1行2列的第1个子图
imshow(grayImg);
title('原始灰度图像');% 二值化图像
subplot(1, 2, 2); % 1行2列的第2个子图
imshow(binaryImg);
title('Otsu二值化图像');
可以看到,对于单峰图像,OTSU也不没有显示出优势。
2.3 局部均值阈值法
对于每个局部区域,计算该区域的均值作为阈值。适用于光照变化较大的图像。
% 读取图像
img = imread('../../..../....'); % 替换为你的图像文件名% 将图像转换为灰度图像(如果是彩色图像)
if size(img, 3) == 3grayImg = rgb2gray(img);
elsegrayImg = img;
end% 定义局部窗口大小
windowSize = 5; % 窗口大小可以根据需要调整% 计算局部均值阈值
localMean = imfilter(double(grayImg), fspecial('average', windowSize), 'replicate');% 生成二值图像
binaryImg = grayImg > localMean;% 将逻辑值转换为0和255
binaryImg = uint8(binaryImg) * 255;% 显示原始灰度图像和二值化图像
figure;% 原始灰度图像
subplot(1, 2, 1);
imshow(grayImg);
title('原始灰度图像');% 二值化图像
subplot(1, 2, 2);
imshow(binaryImg);
title('局部均值阈值法二值化图像');
2.4局部中值阈值法
对于每个局部区域,计算该区域的中值作为阈值,能更好地处理噪声。
各种算法其实没有好坏之分,具体看实际使用场景,不存在一种能处理所有场景的算法,选择合适的就好。
三、FPGA实现局部均值阈值法
前面我们知道局部阈值就是将图像分成很多块部分,计算每个区域的均值,然后这个区域的像素灰度值与其比较再做二值化。我们可以用前面的55滑动窗口将图像分成很多55的区域来计算均值,代码和均值滤波的代码几乎一样,这里就不再赘述,直接打开仿真,输入图像为一幅灰度图像,如下图所示:
打开仿真生成的新图像:
可以看到我们用Verilog代码生成的局部二值化图像和matlab一致,窗口计算的均值可以任意根据需求改动,比如均值再减去一个常数或者加一个常数等,不同的阈值处理出来的图像不一样。