Python - opencv (一) 边缘检测

本文开始Python - opencv的学习,因为有一些图像基础,图形学的基础部分(包括图像基本知识、环境部署、灰度直方图和二值化、图像缩放、腐蚀膨胀、开闭运算)跳过,直接从常用处理和机器学习开始。

本文记录opencv的边缘检测应用。

一. Sobel算子

sobel算子的思想,Sobel算子认为,邻域的像素对当前像素产生的影响不是等价的,所以距离不同的像素具有不同的权值,对算子结果产生的影响也不同。一般来说,距离越远,产生的影响越小。

sobel算子的原理,对传进来的图像像素做卷积,卷积的实质是在求梯度值,或者说给了一个加权平均,其中权值就是所谓的卷积核;然后对生成的新像素灰度值做阈值运算,以此来确定边缘信息。

 

原图中的作用点像素值通过卷积之后为:

可以简化成:

比如,一下矩阵为原图中的像素点矩阵,带入上式中的A,最终得到的G或者|G|是下面(x,y)处的像素值,可以自己去搜索下卷积的含义来理解。

 

另外,卷积核也可以旋转,用与查找不与x,y轴平行或垂直的方向上的边缘。

一般来说,对图像分别进行x和y两个方向的sobel运算再求和,比先进行一个方向,再进行另一个方向效果要好很多。

例子:

原图:

 

代码:

 1 import cv2
 2 
 3 if __name__ == '__main__':
 4     img = cv2.imread('../pics/1.jpg', cv2.IMREAD_GRAYSCALE)
 5     cv2.imshow('img', img)
 6     sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
 7     sobel_x = cv2.convertScaleAbs(sobel_x)
 8     sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
 9     sobel_y = cv2.convertScaleAbs(sobel_y)
10     sobel_xy = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)
11     cv2.imshow('img', sobel_xy)
12     cv2.waitKey()
13     cv2.destroyAllWindows()

这里convertScaleAbs函数是一个位深转化函数,可将任意类型的数据转化为CV_8UC1。具体数据处理方式如下:

(1). 对于src*alpha+beta的结果如果是负值且大于-255,则直接取绝对值;

(2). 对于src*alpha+beta的结果如果大于255,则取255;

(3). 对于src*alpha+beta的结果是负值,且小于-255,则取255;

(4). 对于src*alpha+beta的结果如果在0-255之间,则保持不变;

对于单方向sobel以后,卷积乘到的赋值进行一个变换,可以实现两个方向分别求卷积

效果:

人的轮廓基本上能分割出来

 

二. Scharr算子和Laplacian算子

 

特点:对边界识别度更高,缺点是对噪声很敏感

两者算法和Sobel很像,都是求卷积

代码:

 1 import cv2
 2 import numpy as np
 3 
 4 if __name__ == '__main__':
 5     img = cv2.imread('../pics/1.jpg', cv2.IMREAD_GRAYSCALE)
 6 
 7     scharr_x = cv2.Scharr(img, cv2.CV_64F, 1, 0)
 8     scharr_x = cv2.convertScaleAbs(scharr_x)
 9     scharr_y = cv2.Scharr(img, cv2.CV_64F, 0, 1)
10     scharr_y = cv2.convertScaleAbs(scharr_y)
11     scharr_xy = cv2.addWeighted(scharr_x, 0.5, scharr_y, 0.5, 0)
12 
13     laplacian = cv2.Laplacian(img, cv2.CV_64F)
14     laplacian = cv2.convertScaleAbs(laplacian)
15 
16     res = np.hstack((scharr_xy, laplacian))
17     cv2.imshow('img', res)
18     cv2.waitKey()

效果:

 

三. Canny算法

Canny算法包括下列步骤:

  1. 滤波消除噪声(Gauss)
  2. 计算每个像素点的梯度强度和方向
  3. 非极大值抑制,消除杂散效应
  4. 双阈值确定边缘
  5. 抑制过滤的弱边缘,完成检测

非极大值抑制的两种方法:

1.

 

 

 

2.

 

 

双阈值检测

梯度值 > max : 处理为边界

min < 梯度值 < max:有边界则保留,否则删除

梯度值 < min: 删除

 

 

代码:

canny = cv2.Canny(img, 60, 120) # param2 and param3 are threshold

 

效果:阈值越大,选取边界范围越小

 

posted @ 2021-07-05 21:56  Asp1rant  阅读(457)  评论(0编辑  收藏  举报