您的位置:首页 > 其它

边缘改进全局阈值处理

2014-04-22 15:13 996 查看
对于边界明显的图像,但是整体灰度值相近,不易用otsu直接找出正确的阈值,可以使用边缘改进的阈值处理。

具体算法过程如下:

1.用一种边缘查找方式计算图像的模版值。

2.通过百分比指定阈值。由于计算的边缘模板值中有很多噪声。所以可以将计算值排序,并选择百分比相对高的值(大于百分下的值的阈值)作为阈值。

3.根据指定的阈值,对第一步的图像边缘值进行选择。使高于阈值的像素点值为1,反之为零。由此选择出部分边缘点的二值图像(模板)。

4.用刚才计算出来的模板与原图像相乘,获得一幅新的图像。

5.对新的图像使用otsu进行分割。

matlab实现如下:

1.计算各个点的sobel模板值,并将所有值存入lap_tmp中;

pic = imread('road_outside_2_24.bmp'); % 井盖
pic_gray = rgb2gray(pic);
pic_smooth = medfilt2(pic_gray,[3,3]);

[height,width]=size(pic_smooth);
sobel1=[-1 -2 -1;0 0 0;1 2 1];
sobel2=[-1 0 1;-2 0 2;-1 0 1];
lap_tmp = abs(imfilter(pic_smooth,sobel1))+abs(imfilter(pic_smooth,sobel2));
2.去掉边界值,因为边界是用相关运算做的,会自动补零,造成值过大的情况。
lap = uint8(zeros(height,width));
for i=2:height-1
for j=2:width-1
lap(i,j) = lap_tmp(i,j);
end
end
3.计算百分比阈值。
value = thres_return( lap,0.99 );


value是自定义函数。参数分别代表原图像和需要的百分比。具体实现代码如下:

function [ Value ] = thres_return( A,B )
[height,width]=size(A);
tmp = sort(A(:));
Value = tmp(round(height * width * B));
end4.将lap根据计算出来的阈值二值化。并与原图像相乘,获得新的待otsu的图像。
lap = lap >= value;
img = immultiply(lap,pic_smooth);5.对新的图像进行otsu分割,注意要将灰度为零的点去除。
[counts]= imhist(img);
counts(1)=0;
level_A = otsuthresh( counts );
pic_ostu_A = im2bw(pic_smooth,level_A);
其中otsuthresh为自定义函数。用灰度直方矩阵计算ostu的最佳值。代码如下
function [T] = otsuthresh( h )
%UNTITLED3 Summary of this function goes here
% Detailed explanation goes here
h = h/sum(h);%probability
L =256;
for i=1 : L %显示第一个有像素的灰度i
if ( h(i) ~= 0 )
st = i -1;
break;
end
end
for i=L :-1:1 %显示最后一个有像素的灰度i
if ( h(i) ~= 0 )
nd = i -1;
break;
end
end
f = h(st+1 : nd +1);%实际有像素的灰度的概率
p=st;q=nd -st;
u=0;
for i=1:q %计算累积均值ua(i)
u = u+f(i)*(p+i-1); %计算全局均值
ua(i) = u;
end

for i=1:q %计算累积概率
w(i)=sum(f(1:i));
end
d=(u*w - ua).^2./(w.*(1-w));
[y,tp] = max(d);
T=(tp+p)/L;
到此,整个过程结束。可以比较一下与直接使用otsu的区别。
原始图片



使用边缘改进otsu得到的图像:



直接使用otsu得到图像:



可以看出otsu只是基于灰度的分割方法,当关注点为边缘时,此方法将得到错误的结论。使用改进法将得到近似正确的结论。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: