飞道的博客

【计算机视觉】图像分割与特征提取——基于Roberts、Prewitt、Sobel算子的图像分割实验

337人阅读  评论(0)

个人简介: 

> 📦个人主页:赵四司机
> 🏆学习方向:JAVA后端开发 
> ⏰往期文章:SpringBoot项目整合微信支付
> 🔔博主推荐网站:牛客网 刷题|面试|找工作神器
> 📣种一棵树最好的时间是十年前,其次是现在!
> 💖喜欢的话麻烦点点关注喔,你们的支持是我的最大动力。

前言:

实验中要求能够自行评价各主要算子在无噪声条件下和噪声条件下的分割性能。能够掌握分割条件(阈值等)的选择。完成规定图像的处理并要求正确评价处理结果,能够从理论上作出合理的解释。通过实验体会一些主要的分割算子对图像处理的效果,以及各种因素对分割效果的影响。

目录

一:相关概念

1.什么是边缘

2.边缘检测算法

(1)一阶梯度算子

(2)二阶导数

二:使用Roberts算子进行分割

1.实验原理

2.代码实现

3.实验分析

三:使用Prewitt算子进行分割 

1.实验原理

2.代码实现

3.实验分析

四: 使用Sobel算子进行分割

1.实验原理

2.代码实现

3.实验分析


一:相关概念

1.什么是边缘

        什么是边缘?相信很多人都能说出什么是边缘或者指出一幅图片中哪些是边缘,但是如何用计算机视觉相关概念描述出来呢?首先我们先观察一下边缘有什么特点,你会发现所有边缘与其相邻的区域有很大的颜色/灰度越变,我们就可以通过这个特点将边缘区分出来,进而就可以做到对图像的分割。

        对灰度图像的分割常可基于像素灰度值的2个性质:不连续性和相似性。 区域内部的像素一般具有灰度相似性,而在区域之间的边界上一般具有灰度不连续性。

2.边缘检测算法

(1)一阶梯度算子

  • Sobel算子
  • Prewitt算子
  • Roberts算子

(2)二阶导数

  • 拉普拉斯算子(对噪音敏感)

  • 高斯-拉普拉斯算子(LOG)(对图像先进行滤波再求导数)

二:使用Roberts算子进行分割

1.实验原理

        调入并显示图像room.tif(或room.png)中图像;使用Roberts 算子对图像进行边缘检测处理; Roberts 算子为一对模板:

        相应的矩阵为:rh = [0 1;-1 0]; rv = [1 0;0 -1];这里的rh 为水平Roberts 算子,rv为垂直Roberts 算子。分别显示处理后的水平边界和垂直边界检测结果;用“欧几里德距离”和“街区距离”方式计算梯度的模,并显示检测结果;对于检测结果进行二值化处理,并显示处理结果;

        提示:先做检测结果的直方图,参考直方图中灰度的分布尝试确定阈值;应反复调节阈值的大小,直至二值化的效果最为满意为止。分别显示处理后的水平边界和垂直边界检测结果;将处理结果转化为“白底黑线条”的方式;给图像加上零均值的高斯噪声;对于噪声图像重复以上步骤。

2.代码实现


  
  1. function Roberts(I_in)
  2. figure( 1),subplot( 121),imshow(I_in),title( '原图');
  3. [ row,col] = size(I_in);
  4. I = double(I_in);
  5. I(:, size(I_in, 2) + 1) = 195;
  6. I(size(I_in, 1) + 1, :) = 195;
  7. g = zeros( row,col);
  8. g_x =zeros( row,col); % 水平方向
  9. g_y =zeros( row,col); % 垂直方向
  10. for i = 1: row
  11. for j = 1:col
  12. x = abs(I(i + 1,j + 1) -I(i,j));
  13. y = abs(I(i + 1,j) -I(i,j + 1));
  14. sum =x +y;
  15. g(i,j) = sum;
  16. g_x(i,j) =x;
  17. g_y(i,j) =y;
  18. end
  19. end
  20. NumPixel = zeros( 1, 400); % 建立一个 256列的行向量,以统计各灰度级的像素个数
  21. for i = 1 : row
  22. for j = 1 : col
  23. k = g(i,j); % k是像素点(i,j)的灰度值
  24. NumPixel(k + 1) = NumPixel(k + 1) + 1; % 对应灰度值像素点数量加 1
  25. end
  26. end
  27. figure( 2),bar(NumPixel); % 灰度图像的直方图
  28. figure( 1),subplot( 122),imshow(g,[]),title( '卷积结果');
  29. I2 =g;
  30. for i = 1 : row
  31. for j = 1 : col
  32. if I2(i,j) < 80
  33. I2(i,j) = 1;
  34. else
  35. I2(i,j) = 0;
  36. end
  37. end
  38. end
  39. figure( 3),subplot( 121),imshow(g_x,[]),title( '水平边界检测结果');
  40. figure( 3),subplot( 122),imshow(g_y,[]),title( '垂直边界检测结果');
  41. figure,imshow(I2),title( '二值化图像');
  42. end

3.实验分析

图3.1-1 灰度分布直方图

图3.1-2 水平边界与垂直边界检测结果

图3.1-3 room原图与卷积结果

图3.1-4 结果二值化

图3.1-5 加入高斯噪声后灰度分布直方图

图3.1-6 水平边界与垂直边界检测结果

图3.1-7 room加入高斯噪声原图与卷积结果

图3.1-8 卷积结果二值化

分析:

        可以看到,进行卷积后得到的图像灰度值大多集中在0-25之间,这是因为图像中边缘部分占的信息比较少,而平滑部分信息较多,当在梯度较小的区域做梯度幅值计算时,得到的结果会接近于0。从水平边界检测和垂直边界检测结果来看(见图3.1-2),可以看到Roberts算子对正45度和负45度的边缘检测效果较明显,其中水平方向检测正45度方向,垂直方向检测负45度方向。要注意的是,实验中发现当用uint8类型的矩阵来存储结果时,由于uint8类型存储的是0-255之间的值,而计算结果会大于255,此时会将大于255的值置为255,会造成一些信息丢失,得到的结果也不明显。对于水平和垂直的边缘,两个方向的检测结果都基本一致。

        在对卷积结果进行二值化处理时,从灰度分布图中可以得到大概的最小值阈值(即该阈值往后的灰度分布较少),但是将这个值作为阈值得到的图像会有较多非边缘部分信息(如房顶部分),此时就需要增大阈值,以过滤这些非边缘信息。

        加入高斯噪声之后,可以看到灰度值分布呈现很明显的正态分布,得到的卷积结果不理想,无论怎么调整阈值,噪声都会造成很大的影响。假如阈值过小,噪声会覆盖掉边缘信息,噪声过大则会将边缘部分过滤。罗伯特算法对于噪声较多的图片处理效果较差。

三:使用Prewitt算子进行分割 

1.实验原理

Prewitt算子的模板大小为3*3,其X方向和Y方向偏导数分别为:

梯度计算公式:

2.代码实现


  
  1. function Prewitt(I_in)
  2. figure( 1),subplot( 121),imshow(I_in),title( '原图');
  3. [ row,col] = size(I_in);
  4. I =ones( row + 2,col + 2);
  5. for i = 2: row + 1
  6. for j = 2:col + 1
  7. I(i,j) =I_in(i -1,j -1);
  8. end
  9. end
  10. g = zeros( row,col);
  11. g_x =zeros( row,col); % 水平方向
  12. g_y =zeros( row,col); % 垂直方向
  13. for i = 2: row + 1
  14. for j = 2:col + 1
  15. x = abs(I(i -1,j -1) +I(i,j -1) +I(i + 1,j -1) -(I(i -1,j + 1) +I(i,j + 1) +I(i + 1,j + 1)));
  16. y = abs(I(i -1,j -1) +I(i -1,j) +I(i -1,j + 1) -(I(i + 1,j -1) +I(i + 1,j) +I(i + 1,j + 1)));
  17. sum =x +y;
  18. g(i -1,j -1) = sum;
  19. g_x(i -1,j -1) =x;
  20. g_y(i -1,j -1) =y;
  21. end
  22. end
  23. g( 1,:) = 1;
  24. g( row,:) = 1;
  25. g(:, 1) = 1;
  26. g(:,col) = 1;
  27. NumPixel = zeros( 1, 1000); % 建立一个 256列的行向量,以统计各灰度级的像素个数
  28. for i = 1 : row
  29. for j = 1 : col
  30. k = g(i,j); % k是像素点(i,j)的灰度值
  31. NumPixel(k + 1) = NumPixel(k + 1) + 1; % 对应灰度值像素点数量加 1
  32. end
  33. end
  34. figure( 2),bar(NumPixel); % 灰度图像的直方图
  35. figure( 1),subplot( 122),imshow(g,[]),title( '卷积结果');
  36. I2 =g;
  37. for i = 1 : row
  38. for j = 1 : col
  39. if I2(i,j) < 100
  40. I2(i,j) = 1;
  41. else
  42. I2(i,j) = 0;
  43. end
  44. end
  45. end
  46. figure( 3),subplot( 121),imshow(g_x,[]),title( '水平边界检测结果');
  47. figure( 3),subplot( 122),imshow(g_y,[]),title( '垂直边界检测结果');
  48. figure,imshow(I2),title( '二值化图像');
  49. end

3.实验分析

图3.2-1 灰度值分布图

图3.2-2 水平与垂直边界检测结果

图3.2-3 原图与卷积结果

图3.2-4 卷积结果二值化

图3.2-5 加入高斯噪声后卷积结果灰度分布图

图3.2-6 加入高斯噪声后水平边界和垂直边界检测结果

图3.2-7 加入高斯噪声后原图及卷积结果

图3.2-8 卷积结果二值化

分析:

        相较于Roberts算子,Prewitt算子采用的是3*3的模板,因此需要处理图像边界问题,在Roberts算子中我处理边界的方式是在最后一列和最后一行添加一个普遍像素值195,在Prewitt算子中由于选取得是模板中心位置,所以需要再图像像素矩阵四周添加像素点,我选择的是在四周添加1。在横向和纵向的边缘检测Prewitt算子要比Roberts算子要强,从图3.2-2中可以看到,Prewitt算子的x方向检测主要检测纵向边缘信息,y方向主要检测横向边缘信息,对于斜边的检测两个方向基本一致。从图3.2-4中可以看到,Prewitt算子的边缘检测能力要比Roberts算子要强,在一些细节方面Prewitt算子保留得更到位,Roberts算子会造成一些边缘信息的丢失,特别是灰度变化梯度较小的区域。

        在处理带噪声的图片上,由于Prewitt算子采用了3*3的模板,其对噪声的处理能力也更强,相较于图3.1-8,图3.2-8的处理效果更好,在去除了部分的噪声后边缘信息仍能看出来,但是噪声还是很明显。

四: 使用Sobel算子进行分割

1.实验原理

Sobel算子考察它上下、左右邻点灰度的加权差。与之接近的邻点的权重:

用卷积模板来实现:

Sobel算子结合了高斯平滑和微分求导,相当于先做了平滑再做边缘提取,有抑制噪声的作用。

另一个角度:Sobel算子在Prewitt算子的基础上增加了权重的概念认为相邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越大,从而实现图像锐化并突出边缘轮廓。 

2.代码实现


  
  1. function Sobel(I_in)
  2. figure( 1),subplot( 121),imshow(I_in),title( '原图');
  3. [ row,col] = size(I_in);
  4. I =ones( row + 2,col + 2);
  5. for i = 2: row + 1
  6. for j = 2:col + 1
  7. I(i,j) =I_in(i -1,j -1);
  8. end
  9. end
  10. g = zeros( row,col);
  11. g_x =zeros( row,col); % 水平方向
  12. g_y =zeros( row,col); % 垂直方向
  13. for i = 2: row + 1
  14. for j = 2:col + 1
  15. x = abs(I(i -1,j -1) + 2 *I(i,j -1) +I(i + 1,j -1) -(I(i -1,j + 1) + 2 *I(i,j + 1) +I(i + 1,j + 1)));
  16. y = abs(I(i -1,j -1) + 2 *I(i -1,j) +I(i -1,j + 1) -(I(i + 1,j -1) + 2 *I(i + 1,j) +I(i + 1,j + 1)));
  17. sum =x +y;
  18. g(i -1,j -1) = sum;
  19. g_x(i -1,j -1) =x;
  20. g_y(i -1,j -1) =y;
  21. end
  22. end
  23. g( 1,:) = 1;
  24. g( row,:) = 1;
  25. g(:, 1) = 1;
  26. g(:,col) = 1;
  27. NumPixel = zeros( 1, 1500); % 建立一个 256列的行向量,以统计各灰度级的像素个数
  28. for i = 1 : row
  29. for j = 1 : col
  30. k = g(i,j); % k是像素点(i,j)的灰度值
  31. NumPixel(k + 1) = NumPixel(k + 1) + 1; % 对应灰度值像素点数量加 1
  32. end
  33. end
  34. figure( 2),bar(NumPixel); % 灰度图像的直方图
  35. figure( 1),subplot( 122),imshow(g,[]),title( '卷积结果');
  36. I2 =g;
  37. for i = 1 : row
  38. for j = 1 : col
  39. if I2(i,j) < 280
  40. I2(i,j) = 1;
  41. else
  42. I2(i,j) = 0;
  43. end
  44. end
  45. end
  46. figure( 3),subplot( 121),imshow(g_x,[]),title( '水平边界检测结果');
  47. figure( 3),subplot( 122),imshow(g_y,[]),title( '垂直边界检测结果');
  48. figure,imshow(I2),title( '二值化图像');
  49. end

3.实验分析

图3.3-1 Sobel算子处理结果灰度分布直方图

图3.3-2 水平边界和垂直边界检测结果

图3.3-3 room原图及Robel算子处理结果

图3.3-4 二值化结果

图3.3-5 加入高斯噪声后图像灰度分布图

图3.3-6 加入高斯噪声后水平及垂直边界检测结果

图3.3-7 加入高斯噪声后原图及卷积化结果

图3.3-8 二值化结果

分析:

        对于Sobel算子,其原理与Prewitt算子基本一致,不同的是Sobel算子Sobel算子在Prewitt算子的基础上增加了权重的概念认为相邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越大,从而实现图像锐化并突出边缘轮廓。其结合了高斯平滑和微分求导,相当于先做了平滑再做边缘提取,有抑制噪声的作用。在不添加噪声的情况下,可以看到Sobel算子的处理效果与Prewitt算子基本一致,但是加入高斯噪声之后,可以看到明显的差别,Sobel算子对噪声具有平滑作用,其边缘信息相较于Prewitt算子更清晰。


转载:https://blog.csdn.net/weixin_45750572/article/details/127471131
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场