代码如下:
clc;
clear;
x=imread('n2.jpg'); %load original image
%现在我们调整图像的大小这样以后我们的计算工作就变得更容易了。 sauvola算法
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阈值算法的百分比:
m = mean(v(:))
s=std(v(:))
k=-.4;
value=m+ k*s;
temp=v;
实施sauvola阈值算法的百分比:
/>
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
我获得的结果如下:
您可以看到在较暗的地方所产生的图像质量下降。有人可以建议如何优化我的结果吗?
#1 楼
您的图像亮度不均匀,因此不应使用统一的阈值。您需要一个自适应阈值。这可以通过对图像进行预处理以使图像上的亮度更加均匀来实现(用Mathematica编写的代码,您必须自己实现Matlab版本):亮度均匀是使用封闭滤镜从图像中去除实际文本:字体笔划的宽度,并且小于要尝试去除的污点的大小。这是形态膨胀,然后是形态侵蚀。膨胀实质上将结构元素移动到图像中的每个位置,并在遮罩下拾取最亮的像素,因此:
去除小于结构元素的暗结构
缩小按结构化元素的大小可以放大较大的深色结构
放大明亮的结构
腐蚀操作的作用与此相反(它会在结构化元素内部拾取最暗的像素),因此如果将其应用于膨胀后的图像:
由于比结构元素小而被删除的深色结构仍然消失了
缩小的深色结构再次被放大到原始形状大小(尽管它们的形状会更平滑)
明亮的结构会减小到其原始大小
,因此关闭操作可以删除较小的深色物体,而对较大的深色物体和明亮的物体只需进行较小的更改即可。
下面是一个具有不同结构元素大小的示例:
随着结构元素的大小增加,越来越多的字符被删除。在radius = 5处,所有字符均被删除。如果半径进一步增大,那么较小的污点也将被去除: (几乎)均匀亮度:
white = Closing[src, DiskMatrix[5]]
现在可以使用恒定阈值对图像进行二值化:
whiteAdjusted = Image[ImageData[src]/ImageData[white]*0.85]
评论
$ \ begingroup $
哇!这真是太酷了!巨大+1!
$ \ endgroup $
– Phonon
2012年4月4日14:03
$ \ begingroup $
@nikie +1非常好-您关闭关闭过滤器的确切含义是“必须选择大于字体笔划”?字母的宽度或长度?此外,关闭过滤器“确实”在做什么?谢谢!
$ \ endgroup $
–太空
2012年4月4日在16:02
$ \ begingroup $
@Mohammad:我在回答中添加了一些解释。是的,这些是非线性运算。共同的标题是形态图像处理。
$ \ endgroup $
– Niki Estner
2012年4月4日在20:15
$ \ begingroup $
@nikie没关系,白色是最大值,而不是黑色。 :-)
$ \ endgroup $
–太空
2012年4月4日在20:33
$ \ begingroup $
@gdelfino:为了安全起见,我通常尝试使用足够大的遮罩来避免这种情况,并使用Clip [ImageData [white],{eps,Infinity}](其中eps很小)来避免这种情况。
$ \ endgroup $
– Niki Estner
2012年11月22日19:53
#2 楼
Nikie的答案似乎最好,而且似乎正在奏效并产生结果。因此,这无疑是赢家。这种技术称为自适应阈值化,它不需要显式学习背景。
本质上,无需寻找最合适的全局阈值-我们可以将图像分区一个本地窗口(例如大约7x7或适当的大小),并找到随窗口移动而变化的阈值。
下面的参考详细介绍了确切的方法。
http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm
此该方法在计算上相对较快。
评论
$ \ begingroup $
这两件事根本不一样吗?是否在阈值化之前估计信号的局部均值?
$ \ endgroup $
– Maurits
2012年4月9日在11:12
$ \ begingroup $
@Maurits看起来主要区别在于排序和使用的统计信息。例如,在打开/关闭运算符(由膨胀和腐蚀组成,但顺序不同)中,对窗口进行光栅扫描并获取最大值。 (除其他事项外)。但是,在自适应阈值中,可以采用平均值/中位数代替最大值。
$ \ endgroup $
–太空
2012年4月9日在23:17
$ \ begingroup $
OP也对SO提出了要求,我回答了。但是原则上,我认为答案之间没有任何区别,一个总是估算本地统计信息。如果您进行自适应阈值化,那么您还将在此过程中了解背景知识。
$ \ endgroup $
– Maurits
2012年10月10日7:54
#3 楼
使用带通滤波器的另一种方法(在MATLAB中)。玩弄高斯参数的差异可能会得到更好的结果。该过程基本上是对图像进行带通滤波,以去除低频背景斑点,并标准化为'graythresh'命令所需的[0,1],阈值图像。 br />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评论
$ \ begingroup $
啊!但是需要图像处理工具箱。 :-/
$ \ endgroup $
–太空
2012年4月9日23:00
$ \ begingroup $
的确如此。对不起,如果您没有它。但是DIPImage是Matlab的免费Image Tolbox。 diplib.org/documentation它提供了几种阈值化方法(检查分段部分),并且您还可以执行所有形态学操作,例如关闭。开发人员还有一个博客cb.uu.se/~cris/blog/index.php/archives/tag/matlab
$ \ endgroup $
– MyCarta
2012年10月10日14:15
#5 楼
我会尝试这种编码。但是我没有正确的答案...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');
评论
$ \ begingroup $
如果要回答这个问题,请说明您在做什么以及原因。
$ \ endgroup $
– Matt L.
15年3月20日在11:37
评论
您可以使用颜色信息代替背景而仅丢弃亮度吗?尊敬的先生/女士。我正在做图像处理项目。我是一个有趣的二值化概念。请检查并纠正编码。另一个是msp中的错误(第31行)k = kittlerMet(g); ..如何解决...请更正编码...