文档图像阈值的最佳算法是什么(内部示例)?

信息处理 图像处理 matlab 阈值
2021-12-29 22:07:18

我正在尝试对显示的图像实施各种二值化算法:在此处输入图像描述

这是代码:

clc;
clear;
x=imread('n2.jpg');     %load original image

% 现在我们调整图像的大小,以便我们以后的计算工作变得更容易。

size(x);
x=imresize(x,[500 800]);
figure;
imshow(x);
title('original image');

z=rgb2hsv(x);       %extract the value part of hsv plane
v=z(:,:,3);
v=imadjust(v);

%现在我们找到了 niblack 和 %sauvola 算法所需的均值和标准差

m = mean(v(:))
s=std(v(:))
k=-.4;
value=m+ k*s;
temp=v;

% 实施 niblack 阈值算法:

for p=1:1:500
    for q=1:1:800
        pixel=temp(p,q);
        if(pixel>value)
            temp(p,q)=1;
        else
            temp(p,q)=0;
        end
    end
end
figure;
imshow(temp);
title('result by niblack');
k=kittlerMet(g);
figure;
imshow(k);
title('result by kittlerMet');

% 实施 sauvola 阈值算法:

val2=m*(1+.1*((s/128)-1));
t2=v;
for p=1:1:500
for q=1:1:800
    pixel=t2(p,q);
    if(pixel>value)
        t2(p,q)=1;
    else
        t2(p,q)=0;
    end
end

结尾

figure;
imshow(t2);
title('result by sauvola');

我得到的结果如图所示: 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

如您所见,生成的图像在较暗的地方退化了。有人可以建议如何优化我的结果吗?

4个回答

您的图像没有统一的亮度,因此您不应该使用统一的阈值。您需要一个自适应阈值。这可以通过预处理图像来实现,以使整个图像的亮度更加均匀(用 Mathematica 编写的代码,您必须自己实现 Matlab 版本):

使亮度均匀的一种简单方法是使用关闭过滤器从图像中删除实际文本:

white = Closing[src, DiskMatrix[5]]

在此处输入图像描述

过滤器大小应选择大于字体笔划宽度且小于您要去除的污渍的大小。

编辑: 我在评论中被要求解释关闭操作的作用。这是一个形态扩张,然后是形态侵蚀膨胀实质上是在图像中的每个位置移动结构元素,并选择掩码下最亮的像素,因此:

  • 去除比结构元素更小的暗结构
  • 按结构元素的大小缩小较大的暗结构
  • 扩大明亮的结构

腐蚀操作相反(它选择结构元素内部最暗的像素),所以如果你将它应用到膨胀图像上:

  • 因为比结构元素小而被移除的暗结构仍然消失了
  • 缩小的较暗结构再次放大到原始大小(尽管它们的形状会更平滑)
  • 明亮的结构被缩小到原来的大小

所以关闭操作移除了小的暗物体,对较大的暗物体和亮物体只有很小的变化。

这是一个具有不同结构元素大小的示例:

在此处输入图像描述

随着结构元素大小的增加,越来越多的字符被删除。在半径=5 时,所有字符都被删除。如果半径进一步增加,较小的污渍也会被去除:

在此处输入图像描述

现在您只需将原始图像除以此“白色图像”即可获得(几乎)均匀亮度的图像:

whiteAdjusted = Image[ImageData[src]/ImageData[white]*0.85]

在此处输入图像描述

现在可以使用恒定阈值对该图像进行二值化:

Binarize[whiteAdjusted , 0.6]

在此处输入图像描述

Nikie 的回答似乎是最好的,而且似乎也在起作用并产生了结果。所以它是一个明显的赢家。

但是,仅在文档中我添加了一个参考,这可能非常快。

这种技术称为自适应阈值,它不需要显式学习背景。

本质上,不是找到最合适的全局阈值——我们可以在局部窗口中分割图像(比如大约 7x7 或适当的),并找到随着窗口遍历而变化的阈值。

下面的参考详细说明了确切的方法。 http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm

这种方法在计算上会相对更快。

另一种使用带通滤波器的方法(在 MATLAB 中)。玩弄高斯参数的差异可能会得到更好的结果。该过程基本上是对图像进行带通滤波以去除低频背景斑点,标准化为“graythresh”命令所需的[0,1],阈值图像。

加载图像并转换为灰度双精度:

I = imread('hw.jpg');
I = rgb2gray(I);
I = double(I);

在此处输入图像描述

使用高斯核的差值进行过滤并归一化:

J = imgaussian(I,1.5) - imgaussian(I,0.5);
J = J - min(J(:));
J = J / max(J(:));

在此处输入图像描述

计算阈值并生成 010101:

T = J > graythresh(J);

在此处输入图像描述

这是一个很好的自适应阈值的 Matlab 代码:http: //www.mathworks.com/matlabcentral/fileexchange/8647-local-adaptive-thresholding