目录
0.1原始图像1
0.2 原始图像2
41-43 Canny边缘检测
Canny边缘检测是从不同视觉对象中提取有用的结构信息并大大减少要处理的数据量的一种技术,目前已广泛应用于各种计算机视觉系统。边缘检测的一般标准包括:
1.以低的错误率检测边缘,也即意味着需要尽可能准确的捕获图像中尽可能多的边缘。
2.检测到的边缘应精确定位在真实边缘的中心。
3. 图像中给定的边缘应只被标记一次,并且在可能的情况下,图像的噪声不应产生假的边缘。
在目前常用的边缘检测方法中,Canny边缘检测算法是具有严格定义的,可以提供良好可靠检测的方法之一。由于它具有满足边缘检测的三个标准和实现过程简单的优势,成为边缘检测最流行的算法之一。
一个很清楚的canny算法解析
Canny边缘检测算法可以分为以下5个步骤:
1.使用高斯滤波器,以平滑图像,滤除噪声。
2.计算图像中每个像素点的梯度强度和方向。
3.应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
4.应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
5. 通过抑制孤立的弱边缘最终完成边缘检测。
41. 高斯滤波+求边缘梯度和强度
- 将图像进行灰度化处理理;
- 将图像进行高斯滤波(5*5 ,s=1.4是一个不错的参数 );
- 图像中的边缘可以指向各个方向,因此Canny算法使用四个算子来检测图像中的水平、垂直和对角边缘。边缘检测的算子(如Roberts,Prewitt,Sobel等)返回水平Gx和垂直Gy方向的一阶导数值,由3-2便可以确定像素点的梯度edge和方向tan 。
边缘可以划分为垂直、水平、45°、135°4个方向,同样,梯度反向也为四个方向(与边缘方向正交)。因此为了进行非极大值,将所有可能的方向量化为4个方向。可使用以下公式将梯度方向量化
42.边缘细化-边缘梯度非极大值抑制
非极大值抑制是对除去非极大值以外的值的操作的总称。非极大值抑制则可以帮助将局部最大值之外的所有梯度值抑制为0,
在这里,我们比较我们我们所关注的地方梯度的法线方向邻接的三个像素点的梯度幅值,如果该点的梯度值不比其它两个像素大,那么这个地方的值设置为0。反之,该像素点保留为边缘点
我们在注意梯度幅值edge(x,y) 的时候,可以根据下式由梯度方向angle(x,y)来变换
43.双阈值检测
在施加非极大值抑制之后,剩余的像素可以更准确地表示图像中的实际边缘。然而,仍然存在由于噪声和颜色变化引起的一些边缘像素。为了解决这些杂散响应,必须用弱梯度值过滤边缘像素,并保留具有高梯度值的边缘像素,可以通过选择高低阈值,来将梯度幅值二值化。阈值的大小需要边看结果边调整.
对于弱边缘像素来说,通过查看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘点就可以保留为真实的边缘。否则置为0
即:
1 如果梯度幅值 大于高阈值的话,令edge(x,y)=255 ;
2 如果梯度幅值 小于低阈值的话,令edge(x,y)=0 ;
3 如果梯度幅值 介于高阈值和低阈值之间并且周围8邻域内有比高阈值高的像素点存在,令edge(x,y)=255
代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
def Canny(img):
###41题:灰度化+高斯滤波+获取边缘梯度和方向
##1.灰度化
def Gray(img):
b=img[:, :, 0].copy()
g=img[:, :, 1].copy()
r=img[:,:,2].copy()
out=0.2126 * r + 0.7152 * g + 0.0722 * b
out=out.astype(np.uint8)
return out
#2.高斯滤波平滑噪声
def gaussian_filter(img, k_size,sigma):
H,W=img.shape
##填充图像边缘(根据k_size)
pad=k_size//2
out=np.zeros((H+2*pad, W+2*pad),dtype=np.float32)
out[pad:pad+H, pad:pad+W]=img.copy().astype(np.float32)
#构建高斯算子
k=np.zeros((k_size,k_size),dtype=np.float32)
for x in range(-pad,-pad+k_size):
for y in range(-pad,-pad+k_size):
k[x+pad, y+pad]=np.exp(-(x**2+y**2)/(2*sigma*sigma))
k /=(2*np.pi*sigma*sigma)
#归一化
k /=k.sum()
##卷积过程
temp=out.copy()
for y in range(H):
for x in range(W):
out[pad+y,pad+x]=np.sum