飞道的博客

图像分割 - 孤立点的检测

403人阅读  评论(0)

目录

1. 介绍

2. 代码实现


1. 介绍

因为,一阶导数通常会产生粗边缘。二阶导数对精细细节(细线、孤立点、噪声)有更强的响应。

所以,检测孤立点应该以二阶导数为基础,而二阶导数的差分计算为:

这个差分计算可以通过一个 系数和为零 的kernel去完成

于是,如果滤波器的响应超过一个规定的阈值,那我们就认为在kernel的中心找到了一个点。将找到的点记作1,其他的点看作0,于是就得到了一副二值图像

直观上看,这个概念是孤立点的灰度完全不同于其周围像素的灰度

孤立点是那些灰度差超过某个阈值T,被认为是孤立点的像素点

为了更好的探测8邻域的灰度差值,将滤波器的权重换成下面类型的:

1 1 1
1 -8 1
1 1 1

2. 代码实现

代码为:


  
  1. import numpy as np
  2. import cv2
  3. def point_detect( img):
  4. canvas = np.zeros(img.shape, dtype=np.uint8) # 拷贝图像
  5. kernel = np.array([[ 1, 1, 1], [ 1, - 8, 1], [ 1, 1, 1]]) # 定义卷积核
  6. laplacian = cv2.filter2D(img, cv2.CV_16S, kernel) # 拉普拉斯变换
  7. img_lap = cv2.convertScaleAbs(laplacian) # 拉普拉斯图像
  8. cv2.imshow( 'laplacian',img_lap)
  9. T = 0.9 * np. abs(laplacian). max() # 阈值 T
  10. for i in range(img.shape[ 0]): # 遍历图像,寻找孤立点
  11. for j in range(img.shape[ 1]):
  12. if (laplacian[i, j] > T) or (laplacian[i, j] < -T): # 绝对值大于阈值的点
  13. canvas[i, j] = 255 # 二值处理
  14. cv2.circle(canvas, (j, i), 10, 255) # 绘制圆
  15. return canvas
  16. img = cv2.imread( 'img.tif', 0)
  17. ret = point_detect(img)
  18. cv2.imshow( 'img',np.hstack((img,ret)))
  19. cv2.waitKey()
  20. cv2.destroyAllWindows()

处理的结果为:

原图、检测孤立点的二值图像

原图的拉普拉斯图像为:

 


 这里对孤立点检测函数的代码做简单讲解:

1. 首先,建立一个全零的图片canvas,后面将检测的孤立点改为255,这样canvas就是二值图像了

2. filter2D 里面的ddepth 是CV_16S ,因为做差会出现负数,不能采用无符号的形式

 3. 如果为了打印拉普拉斯图像,需要将图像转换成uint8,并且灰度值在0-255之间。这里用的是convertScaleAbs函数,就是取绝对值,然后超过255的都取255。

如果采用norm的形式是这个样子的,代码为:

img_norm = cv2.normalize(laplacian,None,0,255,norm_type=cv2.NORM_MINMAX,dtype=cv2.CV_8U)

4. 这里不管用convert还是norm的形式都要取对应的阈值T,最后就是遍历图像,将大于T的找出来,赋值为255就行了。为了方便观察,以孤立点绘制出一个圆弧,注:圆心的坐标是反过来的


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