在此示例中,用于文档图像阈值处理的最佳算法是什么?


31

我正在尝试对所示图像实施各种二值化算法: 在此处输入图片说明

这是代码:

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');

我获得的结果如下所示: 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

如您所见,最终图像在较暗的点处退化了。有人可以建议如何优化我的结果吗?


1
您是否可以使用颜色信息而不是仅丢弃亮度来丢弃背景?
endlith 2012年

尊敬的先生/女士。我正在做图像处理项目。我是一个有趣的二值化概念。请检查并纠正编码...我接受了编码并运行了程序。但是此编码出现了一些错误...未定义函数或变量'g'。另一个是msp中的错误(第31行)k = kittlerMet(g); ..如何解决...请更正编码...
muthu 2015年

Answers:


49

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

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

white = Closing[src, DiskMatrix[5]]

在此处输入图片说明

过滤器的大小应选择为大于字体笔划宽度,并且小于要尝试去除的污点的大小。

编辑: 我在评论中被要求解释关闭操作的作用。这是形态膨胀,然后是形态侵蚀。膨胀实际上将结构元素移动到图像中的每个位置,并在遮罩下拾取最亮的像素,因此:

  • 去除小于结构元素的深色结构
  • 通过结构元素的尺寸缩小较大的深色结构
  • 扩大明亮的结构

腐蚀操作的作用与此相反(它会在结构化元素内部拾取最暗的像素),因此,如果将其应用于膨胀的图像:

  • 由于小于结构元素而被删除的深色结构仍然消失了
  • 收缩的较暗结构再次放大到其原始大小(尽管它们的形状会更平滑)
  • 明亮的结构缩小到其原始大小

因此,关闭操作将删除较小的深色对象,而对较大的深色对象和明亮的对象仅进行很小的更改。

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

在此处输入图片说明

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

在此处输入图片说明

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

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

在此处输入图片说明

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

Binarize[whiteAdjusted , 0.6]

在此处输入图片说明


5
哇!这真是太酷了!巨大+1!
声子

@nikie +1非常好-关闭过滤器的确切含义是必须“选择大于字体笔划”?字母的宽度或长度?此外,封闭过滤器“确实”在做什么?谢谢!
Spacey 2012年

1
@Mohammad:我在回答中添加了一些解释。是的,这些是非线性运算。共同的标题是形态图像处理。
Niki Estner '04年

1
@nikie没关系,白色是最大值,而不是黑色。:-)
Spacey

1
@gdelfino:为了安全起见,我通常尝试使用足够大的口罩来避免这种情况,并Clip[ImageData[white],{eps,Infinity}]在eps较小的情况下使用。
Niki Estner 2012年

6

Nikie的答案似乎最好,而且似乎正在奏效并产生结果。因此,它无疑是赢家。

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

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

本质上,除了找到最合适的全局阈值外,我们还可以在局部窗口中分割图像(例如大约7x7或合适的大小),并找到随窗口移动而变化的阈值。

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

此方法在计算上相对较快。


这两件事根本不一样吗?即在阈值化之前估计信号的局部均值?
莫里斯

1
@Maurits看起来主要的区别是排序和使用的统计信息。例如,在打开/关闭运算符(由膨胀和腐蚀组成,但顺序不同)中,扫描光栅窗口并获取最大值。(除其他事项外)。但是,在自适应阈值中,可以采用平均值/中位数代替最大值。
Spacey 2012年

OP也对SO提出了要求,我回答了。但是原则上,我认为答案之间没有任何区别,一个总是估算本地统计信息。如果您进行自适应阈值化,那么您还将在此过程中了解背景知识。
莫里斯

6

使用带通滤波器的另一种方法(在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);

在此处输入图片说明


4

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


啊!但是需要图像处理工具箱。:-/
Spacey 2012年

确实。对不起,如果您没有它。但是DIPImage是Matlab的免费Image Tolbox。diplib.org/documentation它提供了几种阈值化方法(检查分段部分),并且您还可以执行所有形态学操作,例如关闭。开发人员还拥有博客cb.uu.se/~cris/blog/index.php/archives/tag/matlab
MyCarta 2012年

0

我会尝试这种编码。但是我没有正确的答案...

clc;
clear;
x=imread('base2.jpg');
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);
m = mean(v(:))
s=std(v(:))
k=-2;
value=m+ k*s;
temp=v;
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');

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

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

在此处输入图片说明

在此处输入图片说明


2
如果要回答这个问题,请说明您在做什么以及原因。
马特·L。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.