第十章 图像分割(10.1-10.3)

来源:互联网 发布:linux双网卡桥接 编辑:程序博客网 时间:2024/06/01 18:31

  • 第十章 图像分割
    • 点线和边缘检测
      • 点检测
      • 线检测
      • 使用函数edge检测边缘
    • 使用霍夫变换进行线检测
    • 阈值处理
      • 基础知识
      • 全局全局阈值处理
      • 局部阈值处理

第十章 图像分割

点,线和边缘检测

点检测

  • 在利用下图的模板时,若|R| ≧ T(R为模板在图像中任意一点的响应,T是一个非负阈值),则在模板中心处检测到了一个孤立点。这种方法可用函数imfilter实现。
>> f = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch10\test_pattern_with_single_pixel).tif');>> w = [-1 -1 -1; -1 8 -1; -1 -1 -1]; % 检测模板>> g = abs(imfilter(tofloat(f), w)); % 计算滤波后的图像>> T = max(g(:)); % T被选定为g中的最大值>> g = g >= T; % 把滤波后的图像与T比较>> subplot(121), imshow(f), title('原图')>> subplot(122), imshow(g), title('检测到的点') % 放大后才能看清

这里写图片描述

  • 在所有大小为m×n的邻域中,找到其最大像素值和最小像素值的差大于指定T值的点。使用函数ordfilt2可实现这一方法。
>> n = 3; m = n;>> g = ordfilt2(f, m * n, ones(m, n)) - ordfilt2(f, 1, ones(m, n));>> T = max(g(:));>> g = g >= T;>> imshow(g)

这里写图片描述

线检测

线检测每个模板的优先方向都用一个比其他可能方向要大的系数加权。每个模板的系数之和为零,表明恒定灰度区域中模板的响应为零。下图为示例模板:
这里写图片描述

>> f = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch10\wirebond_mask.tif');>> w = [2 -1 -1; -1 2 -1; -1 -1 2];>> g = imfilter(tofloat(f), w);>> gtop = g(1:120, 1:120); %获取图片左上角区域>> gtop = pixeldup(gtop, 4); %扩大图片>> gbot = g(end - 119:end, end - 119:end); %获取图片右下角>> gbot = pixeldup(gbot, 4); >> g1 = abs(g);>> T = max(g1(:));>> g2 = g1 >= T;>> subplot(321), imshow(f), title('原图')>> subplot(322), imshow(g), title('滤波后的图像')>> subplot(323), imshow(g), title('原图左上角放大')>> subplot(324), imshow(gbot), title('原图右上角放大')>> subplot(325), imshow(g1), title('g的绝对值')>> subplot(326), imshow(g2), title('检测后的图像')

这里写图片描述

使用函数edge检测边缘

语法:[g, t] = edge(f, ‘method’, ‘parameters’)
其中,f是输入图像,method是下表中所列出的方法。g是一个逻辑数组,在f中检测到边缘点的位置,数组元素为1,其他位置数组元素为0。
这里写图片描述

  • Sobel边缘检测器
    Sobel边缘检测器使用一个3×3邻域的行列之间的离散差来计算梯度,其中,每行或每列的中心像素用2来加权,以提供平滑效果。
    通用语法: [g, t] = edge(f, ‘sobel’, T, dir)
    其中,f是输入图像,T是一个指定的阈值,dir指定所检测边缘的首选方向:’horizontal’, ‘vertical’或’both’(默认值)。
>> f = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch10\building.tif');>> [gv, t] = edge(f, 'sobel', 'vertical'); %主要边缘是垂直边缘>> subplot(321), imshow(f), title('原图')>> subplot(322), imshow(gv), title('自动确定阈值')>> gv = edge(f, 'sobel', 0.15, 'vertical'); %提高阀值清除较弱边缘>> subplot(323), imshow(gv), title('指定阈值')>> gboth = edge(f, 'sobel', 0.15); %主要显示垂直边缘和水平边缘>> subplot(324), imshow(gboth), title('指定阈值默认方向')>> wneg45 = [-2 -1 0; -1 0 1; 0 1 2];>> gneg45 = imfilter(tofloat(f), wneg45, 'replicate'); %计算-45度方向边缘>> T = 0.3 * max(abs(gneg45(:)));>> gneg45 = gneg45 >= T; >> subplot(325), imshow(gneg45), title('加上-45度方向边缘')>> wpos45 = [0 1 2; -1 0 1; -2 -1 0];>> gneg45 = imfilter(tofloat(f), wpos45, 'replicate'); %计45度方向边缘>> T = 0.3 * max(abs(gneg45(:)));>> gneg45 = gneg45 >= T;>> subplot(326), imshow(gneg45), title('加上45度方向边缘')
![这里写图片描述](http://img.blog.csdn.net/20170704184735015?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
  • Prewitt边缘检测器

    调用语法:[g, t] = edge(f, ‘sobel’, T, dir)
    该函数参数和Sobel的参数相同Prewitt检测器与Sobel检测器相比,计算简单一些但产生的结果噪声会稍大一些

  • Roberts边缘检测器

    调用语法:[g, t] = edge(f, ‘roberts’, T, dir)
    该函数参数和Sobel的参数相同。是数字图像处理最古老简单的检测器之一。其功能有限,但是经常用在硬件实现方面。

  • LoG边缘检测器

    调用语法:[g, t] = edge(f, ‘log’, T, sigma)
    其中,sigma是标准差(默认值为2),其他参数与上述相同。将T设为0产生封闭的轮廓。

  • 零交叉检测器

    调用语法:[g, t] = edge(f, ‘zerocross’, T, H)

  • Canny边缘检测器

    调用语法:[g, t] = edge(f, ‘canny’, T, sigma)
    其中,T是一个向量,T = [T1, T2],它包含两个阈值;sigma是平滑滤波器的标准差(默认值为1)。

  • 功能比较
>> f = tofloat(f);>> [gSobel_default, ts] = edge(f, 'sobel');>> [gLoG_default, tlog] = edge(f, 'log');>> [gCanny_default, tc] = edge(f, 'canny');>> subplot(321), imshow(gSobel_default), title('Sobel检测器默认结果')>> subplot(323), imshow(gLoG_default), title('LoG检测器默认结果')>> subplot(325), imshow(gCanny_default), title('Canny检测器默认结果')>> gSobel_best = edge(f, 'sobel', 0.05);>> gLoG_best = edge(f, 'log', 0.003, 2.25);>> gCanny_best = edge(f, 'canny', [0.04 0.10], 1.5);>> subplot(322), imshow(gSobel_best), title('Sobel检测器减少不相关细节')>> subplot(324), imshow(gLoG_best), title('LoG检测器减少不相关细节')>> subplot(326), imshow(gCanny_best), title('Canny检测器减少不相关细节')

这里写图片描述
由以上测试可知Canny边缘检测器效果最好。

使用霍夫变换进行线检测

  • 函数hough
    默认语法:[H, theta, rho] = hough(f)
    完整语法:[H, theta, rho] = hough(f, ‘ThetaRes’, val1, ‘RhoRes’, val2)
    其中,H是霍夫变换矩阵,theta(单位为度)和rho是ρθ的向量,霍夫变换矩阵是在这些值上生成的。输入f是一幅二值图像;val1是值在0~90之间的一个标量,它指定了沿θ轴的霍夫变换容器(默认为1),val2是范围0
>> f = zeros(101, 101);>> f(1, 1) = 1; f(101, 1) = 1; f(1, 101) = 1;>> f(101, 101) = 1; f(51, 51) = 1;>> subplot(121), imshow(f), title('测试图像')>> H = hough(f);>> subplot(122), imshow(H, []), title('霍夫变换')
![这里写图片描述](http://img.blog.csdn.net/20170704195827652?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
>> [H, theta, rho] = hough(f);>> figure, imshow(H, [], 'XData', theta, 'YData', rho, 'InitialMagnification', 'fit')>> axis on, axis normal>> xlabel('\theta'), ylabel('\rho')
![这里写图片描述](http://img.blog.csdn.net/20170704200534376?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
  • 函数houghpeaks

    默认语法:peaks = houghpeaks(H, NumPeaks)
    完整语法:peaks = houghpeaks(…, ‘Threshold’, val1, ‘NHoodSize’, val2)
    该过程基本概念是通过把找到峰值的邻域中的霍夫变换设置为零来清理峰值。

  • 函数houghlines

    默认语法:lines = houghlines(f, theta, rho, peaks)
    完整语法:lines = houghlines(…, ‘FillGap’, val1, ‘MinLength’, val2)
    其中,输出lines是一个结构数组。

>> f = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch10\building.tif');>> f = tofloat(f);>> gCanny_best = edge(f, 'canny', [0.04 0.10], 1.5);>> [H, theta, rho] = hough(gCanny_best, 'ThetaResolution', 0.2);>> imshow(H, [], 'XData', theta, 'YData', rho, 'InitialMagnification', 'fit')>> axis on, axis normal>> xlabel('\theta'), ylabel('\rho')

这里写图片描述

>> peaks = houghpeaks(H, 5);>> hold on>> plot(theta(peaks(:, 2)), rho(peaks(:, 1)), 'linestyle', 'none', 'marker', 's', 'color', 'w')

这里写图片描述

>> lines = houghlines(gCanny_best, theta, rho, peaks);>> figure, imshow(gCanny_best), hold on>> for k = 1:length(lines)xy = [lines(k).point1 ; lines(k).point2];plot(xy(:,1), xy(:,2), 'LineWidth', 4, 'Color', [.8 .8 .8]);end

这里写图片描述

阈值处理

基础知识

灰度阈值处理的成功与分隔直方图模式的峰谷的宽度和深度直接相关。因此,影响峰谷性质的关键因素是:(1)峰间的可分性(峰分得越开,分离模式的机会越好);(2)图像中的噪声内容(模式随噪声增加而加宽)(3)物体和背景的相对大小;(4)光源的均匀性;(5)图像反射特性的均匀性

全局全局阈值处理

迭代步骤:
这里写图片描述

>> f = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch10\scanned-text-grayscale.tif');>> T = 0.5 * (double(min(f(:))) + double(max(f(:))));>> done = false;>> while ~done    g = f > T;    Tnext = 0.5 * (mean(f(g)) + mean(f(~g)));    done = abs(T - Tnext) < 0.5;    T = Tnext;end>> T2 = graythresh(f);>> g2 = im2bw(f, T2);>> subplot(131), imshow(f)>> subplot(132), imshow(g)>> subplot(133), imshow(g2)

这里写图片描述

局部阈值处理

  • 函数stdfilt计算局部标准差

    语法:g = stdfilt(f, nhood)
    其中,f是输入图像,nhood是由0和1组成的数组,其中非零元素指定用于计算局部标准差所用的邻域。nhood的尺寸在每个维度上必须是奇数,默认值是ones(3)。
    计算局部均值的自定义函数:localmean

  • 全局和局部阈值处理比较

>> f = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch10\Fig1022(a)(gel-image).tif');>> [TGlobal] = graythresh(f);>> gGlobal = im2bw(f, TGlobal);>> subplot(221), imshow(f), title('原图')>> subplot(222), imshow(gGlobal), title('Ostu方法')>> g = localthresh(f, ones(3), 50, 1.5, 'gloal');>> g = localthresh(f, ones(3), 50, 0.5, 'gloal');>> SIG = stdfilt(f, ones(3));>> subplot(223), imshow(SIG, []), title('局部标准差')>> subplot(224), imshow(g), title('局部阈值处理')

这里写图片描述

原创粉丝点击