飞道的博客

图像分割 - 线检测

338人阅读  评论(0)

目录

1. 介绍

2. 二阶导数符号的问题

3. 线检测


1. 介绍

复杂度更高的是线检测

由于二阶导数有更强的滤波器响应,并且比一阶导数有更细的线。但是二阶导数对噪声点会格外敏感,并且会产生双边缘响应

二阶导的定义:

  • 灰度值恒定的区域必须为零
  • 灰度台阶或者斜坡开始处和结束处必须不为零
  • 灰度斜坡上的点必须为零

二阶导数符号的变化可以判断边缘的过渡是从亮到暗还是暗到亮

二阶导数:符号从 + 变到 - ,说明图像是从 暗区域 变到 亮区域

最后就是,根据滤波器的权重设置,可以检测不同角度的线。

这里:x轴为垂直向下,逆时针方向旋转的角度代表正角度

2. 二阶导数符号的问题

代码为:


  
  1. import numpy as np
  2. import cv2
  3. img = cv2.imread( './img.tif', 0)
  4. kernel = np.array([[ 1, 1, 1], [ 1, - 8, 1], [ 1, 1, 1]])
  5. lap = cv2.filter2D(img,cv2.CV_16S,kernel) # 拉普拉斯变换
  6. img_norm = cv2.normalize(lap, None, 0, 255,norm_type=cv2.NORM_MINMAX,dtype=cv2.CV_8U) # 归一化图像
  7. img_lap = cv2.convertScaleAbs(lap) # 拉普拉斯图像
  8. dst = cv2.filter2D(img,cv2.CV_8U,kernel) # 只包含正值的拉普拉斯图像
  9. cv2.imshow( 'img',np.hstack((img,img_norm)))
  10. cv2.waitKey()
  11. cv2.destroyAllWindows()

首先先观察一下,原图和拉普拉斯归一化的图像

因为,拉普拉斯变换会产生负值,而图像显示是uint8 类型的。所以这里运用了归一化,这样就是把负值映射成0,最大值映射成255等。

所以第二副图片的黑色区域代表负值、灰色的代表0,白色的代表正值

 

观察上面一小部分的区域可以发现,在中间竖着的部分,左半边是亮色,然后黑色。说明拉普拉斯变换的符号是由正到负的,因为原来图像灰度值的变换是由暗区域到亮区域的过渡

下面是:拉普拉斯图像和只保存了正值的图像

 

 

3. 线检测

处理的代码为:


  
  1. import numpy as np
  2. import cv2
  3. img = cv2.imread( './img.tif', 0)
  4. kernel1 = np.array([[- 1, - 1, - 1], [ 2, 2, 2], [- 1, - 1, - 1]]) # 水平
  5. kernel2 = np.array([[ 2, - 1, - 1], [- 1, 2, - 1], [- 1, - 1, 2]]) # +45
  6. kernel3 = np.array([[- 1, 2, - 1], [- 1, 2, - 1], [- 1, 2, - 1]]) # 垂直
  7. kernel4 = np.array([[- 1, - 1, 2], [- 1, 2, - 1], [ 2, - 1, - 1]]) # -45
  8. dst1 = cv2.filter2D(img,cv2.CV_16S,kernel1) # 水平检测
  9. dst1 = cv2.convertScaleAbs(dst1)
  10. dst2 = cv2.filter2D(img,cv2.CV_16S,kernel2) # 45 检测
  11. dst2 = cv2.normalize(dst2, None, 0, 255,norm_type=cv2.NORM_MINMAX,dtype=cv2.CV_8U)
  12. dst = dst2.copy() # 拷贝归一化后的图像
  13. dst[dst2 <= 254] = 0
  14. dst3 = cv2.filter2D(img,cv2.CV_16S,kernel3) # 垂直检测
  15. dst3 = cv2.convertScaleAbs(dst3)
  16. dst4 = cv2.filter2D(img,cv2.CV_16S,kernel4) # -45 检测
  17. dst4 = cv2.convertScaleAbs(dst4)
  18. cv2.imshow( 'img',np.hstack((img,dst2,dst)))
  19. cv2.waitKey()
  20. cv2.destroyAllWindows()

这里只介绍 45° 线检测

图像顺序:原图、拉普拉斯变换归一化的图像、阈值处理后的图像

 对应处理的代码为:

1. 首先,用45° 的kernel 进行滤波处理,因为kernel里面带有负值,所以处理的结果会产生负值。2.对处理后的结果做归一化处理,这里会将负值映射为灰度值很小的黑色,正值映射成为灰度值偏大的白色。上述中间的图像

3. 进行阈值处理,因为只有严格满足45° 的线,它的响应结果是最强的,因此归一化后的结果是255,所以阈值处理将 < 255 的均处理为0,就能找到45° 的线


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