赞
踩
Canny算子边缘检测(原理)
Canny算子边缘检测是一种经典的图像处理算法,由John F. Canny于1986年提出,用于精确、可靠地检测数字图像中的边缘特征。该算法设计时考虑了三个关键目标:低错误率(即尽可能多地检测真实的边缘,同时避免误报)、边缘定位的准确性(确保检测到的边缘位置与实际边缘位置紧密对应)以及边缘的单响应性(确保图像中的每一个边缘只被检测一次,避免重复或断裂)。Canny算子通过以下五个核心步骤实现这些目标:
图像灰度化:
高斯滤波(高斯模糊):
计算梯度幅值和方向:
非极大值抑制:
双阈值检测与边缘连接:
Canny算子通过一系列精心设计的步骤,实现了对图像边缘的稳健、精确检测,即使在存在噪声干扰的情况下也能保持较高的性能。由于其出色的综合性能,Canny算子在计算机视觉、图像分析、机器视觉等领域中被广泛应用,特别是在需要精确边缘信息的应用场景中,如物体轮廓检测、运动目标跟踪、图像分割等。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
边缘检测是基于灰度突变来分割图像的常用方法,其实质是提取图像中不连续部分的特征。目前常见边缘检测算子有差分算子、 Roberts 算子、 Sobel 算子、 Prewitt 算子、 Log 算子以及 Canny 算子等。
其中, Canny 算子是由计算机科学家 John F. Canny 于 1986 年提出的一种边缘检测算子,是目前理论上相对最完善的一种边缘检测算法。
Canny 算子在 MATLAB 、 OpenCV 等常用图像处理工具中已有内置的 API。
在 OpenCV 中, Canny 算子使用的函数是 Canny() ,它的原函数如下:
def Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
接下来,接着操作我们之前的马里奥,对马里奥做一次边缘检测看下效果:
- import cv2 as cv
- from matplotlib import pyplot as plt
-
- # 图像读入
- img = cv.imread('maliao.jpg', 0)
- edges = cv.Canny(img, 100, 200)
-
- # 显示结果
- titles = ['Original Img', 'Edge Img']
- images = [img, edges]
-
- # matplotlib 绘图
- for i in range(2):
- plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
- plt.title(titles[i])
- plt.xticks([]),plt.yticks([])
-
- plt.show()

图像转化原因:边缘检测最关键的部分是计算梯度,颜色难以提供关键信息,并且颜色本身非常容易受到光照等因素的影响,所以只需要灰度图像中的信息就足够了。并且灰度化后,简化了矩阵,提高了运算速度。
原理:将彩色图像(Color Image)转换为灰度图(Gray Scale Image),即从三通道RGB图像转为单通道图像。
实现:我们实现彩图转化为灰度图需要用到opencv库中的cv.cvtColor函数,需要用到两个参数:src——输入图片,code——颜色转换代码,代码如下:
- # 灰度图转换
- def grayscale(num_img):
- for i in range(num_img):
- filename = 'img' + str(i) + '.jpg'
- img = cv2.imread(filename)
- img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
- filename = 'img_gray' + str(i) + '.jpg'
- cv2.imwrite(filename, img_gray)
代码如下:
- # 生成感兴趣区域即Mask掩模
- def region_of_interest(image, vertices):
- mask = np.zeros_like(image) # 生成图像大小一致的zeros矩
-
- # 填充顶点vertices中间区域
- if len(image.shape) > 2:
- channel_count = image.shape[2]
- ignore_mask_color = (255,) * channel_count
- else:
- ignore_mask_color = 255
-
- # 填充函数
- cv2.fillPoly(mask, vertices, ignore_mask_color)
- masked_image = cv2.bitwise_and(image, mask)
- return masked_image
Hough变换是一种使用表决方式的参数估计技术,其原理是利用图像空间和Hough参数空间的线-点对偶性,把图像空间中的检测问题转换到参数空间中进行。
基于霍夫变换的直线检测
用到的是Opencv封装好的函数cv.HoughLinesP函数,使用到的参数如下:
image:输入图像,通常为canny边缘检测处理后的图像
rho:线段以像素为单位的距离精度
theta:像素以弧度为单位的角度精度(np.pi/180较为合适)
threshold:霍夫平面累加的阈值
minLineLength:线段最小长度(像素级)
maxLineGap:最大允许断裂长度
具体代码如下:
- def hough_lines(img, rho, theta, threshold, min_line_len, max_line_gap):
-
- # rho:线段以像素为单位的距离精度
- # theta : 像素以弧度为单位的角度精度(np.pi/180较为合适)
- # threshold : 霍夫平面累加的阈值
- # minLineLength : 线段最小长度(像素级)
- # maxLineGap : 最大允许断裂长度
- lines = cv.HoughLinesP(img, rho, theta, threshold, np.array([]), minLineLength=min_line_len, maxLineGap=max_line_gap)
- return lines
高斯滤波
高斯滤波算法是一种去除高频噪声的常用方式,通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值都是由其本身和邻域内的其他像素值经过加权平均后得到的。高斯滤波的原理是根据待滤波的像素点及其邻域点的灰度值按照高斯公式生成的参数规则进行加权平均。
我们这一步需要用到opencv库中的cv.GaussianBlur函数,其中使用到的参数为:src——输入图像,kernel_size——高斯核的大小,sigma——高斯标准差(一般默认为0),具体代码如下:
- # 高斯滤波
- def gaussian_blur(image, kernel_size):
- return cv.GaussianBlur(image, (kernel_size, kernel_size), 0)
绘制高斯滤波后的效果图:
图像融合
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。