2019-04-11 by 崔斐然
先展示效果,看看是不是和你的需求一致:
边缘检测的一般步骤:
1、滤波——消除噪声
2、增强——使边阔更为明显
3、检测——选出边缘点
边缘检测步骤:使用高斯滤波器对图像进行去噪、计算梯度、在边缘上使用非最大抑制(NMS)、在检测到的边缘上使用双(double)阈值去除假阳性,最后分析所有的边缘及其之间的连接,以保留真正的边缘并消除不明显的边缘。
使用的函数主要有CV2.GaussianBlur,cv2.cvtColor, cv2.Canny
首先加载需要转换的图像
src = cv2.imread(' <path>')
如果图片比较大的话可以使用cv2.resize函数对图像缩放
img=cv2.resize(img, (int(width*0.12), int(height*0.12)));
色彩基础
灰度色彩空间是通过去除彩色信息来将其转换成灰阶,灰度色彩空间对中间处理特别有效,比如人脸检测。
BGR即蓝-绿-红色彩空间,每一个像素点都由一个三元数组来表示,分别代表蓝、绿、红三种颜色。
HSV,H(Hue)是色调, S(Saturation)是饱和度, V(Value)表示黑暗的程度(或光谱另一端的明亮程度)
作者:深思海数_willschang
链接:https://www.jianshu.com/p/bfd5dd2566bb
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
这些滤滤函数会将非边缘区域转为黑色,将边缘区域转为白色或其他饱和的颜色。但它们又很容易将噪声错误地识别为边缘。解决方案就是在找到边缘之前对图像进行模糊处理。OpenCV提供的模糊滤波函数,如blur(),medianBlur()以及GaussianBlur()。
高斯滤波
cv2.GaussianBlur
blurred = cv2.GaussianBlur(image, (3, 3), 0)
高斯滤波参数说明如下
InputArray src-----源图像
OutputArray dst-----目标图像
Size ksize----高斯内核大小,其中ksize.width和ksize.height可以不同,但是必须为正数
和奇数,也可为零,均有sigma计算而来。
double sigmaX----表示高斯函数在X方向的标准偏差
double sigmaY---- 表示高斯函数在Y方向的标准偏差
若sigma为零,就将它设为sigmaX,如果两者均为零,就由ksize.width
和ksize.height计算出来。
int borderType -----用于推断图像外部像素的某种边界模式。
默认值 BORDER_DEFAULT */
灰度化处理
gray = cv2.cvtColor(blurred, cv2.COLOR_RGB2GRAY)
cv2.cvtColor参数见:https://www.aiuai.cn/aifarm365.html
Canny边缘检测
Canny边缘检测算法被很多人推崇为当今最优秀的边缘检测算法。
edge_output = cv2.Canny(gray, 50, 150)
canny的参数:
第一个参数是输入图像,第二个和第三个参数是minVal和maxVal
函数原型是这样的
关于阀值
4.滞后阈值: 最后一步,Canny 使用了滞后阈值,滞后阈值需要两个阈值(高阈值和低阈值):
a. 如果某一像素位置的幅值超过 高 阈值, 该像素被保留为边缘像素。
b. 如果某一像素位置的幅值小于 低 阈值, 该像素被排除。
c. 如果某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于 高 阈值的像素时被保留。
Canny 推荐的 高:低 阈值比在 2:1 到3:1之间。
最终代码
#Canny边缘提取
import cv2
def edge_demo(image):
blurred = cv2.GaussianBlur(image, (3, 3), 0)
gray = cv2.cvtColor(blurred, cv2.COLOR_RGB2GRAY)
edge_output = cv2.Canny(gray, 50, 150)
# cv2.resizeWindow("Canny Edge", 600, 600);
cv2.imshow("Canny Edge", edge_output)
# 添加遮罩层
dst = cv2.bitwise_and(image, image, mask= edge_output)
# cv2.resizeWindow("Color Edge", 600, 600);
# cv2.namedWindow('input_image', 0)
# 显示边缘
cv2.imshow("Color Edge", dst)
if __name__ == '__main__':
src = cv2.imread('cannytest.jpg')
height, width = src.shape[:2]
src=cv2.resize(src, (int(width*0.12), int(height*0.12)));
cv2.imshow("src", src)
# 设置为WINDOW_NORMAL可以任意缩放
# cv2.namedWindow('input_image', cv2.WINDOW_NORMAL)
# cv2.resizeWindow("input_image", 600, 600);
# cv2.imshow('input_image', src)
edge_demo(src)
cv2.waitKey(0)
cv2.destroyAllWindows()