专栏首页唐国梁Tommy笔记分享 : OpenCV中的常用边缘检测算法

笔记分享 : OpenCV中的常用边缘检测算法

哈喽,大家好,我们今天了解一下OpenCV中的边缘检测功能实现。在一些案例中,我们需要对物体进行边缘检测,而且是越精准越好。那么,OpenCV提供了哪些边缘检测的方法呢?

我们先看一个例子,看看到底什么是边缘检测,效果又是如何?

import cv2
import numpy as np 
from scipy import ndimage # 提供了基础的图像处理功能
# 3x3的卷积核,卷积核里的参数或权重加起来等于0
kernel_3x3 = np.array([[-1,-1,-1],[-1,6,-1],[-1,-1,-1]])
# 5x5的卷积核,卷积核里的参数或权重加起来等于0
kernel_5x5 = np.array( [[-1,-1,-1,-1,-1], 
                        [-1,1,2,1,-1],
                        [-1,2,4,2,-1], 
                       [-1,1,2,1,-1],
                       [-1,-1,-1,-1,-1]])
img = cv2.imread('02.jpg', cv2.IMREAD_GRAYSCALE) # 读取图片,灰度
k3 = ndimage.convolve(img, kernel_3x3) # 卷积运算
# 关于 ndimage.convolve(),参考: https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.ndimage.convolve.html
k5 = ndimage.convolve(img, kernel_5x5)
blurred = cv2.GaussianBlur(img, (17,17), 0) # (17,17)高斯内核大小,标准差为0
hpf = img - blurred # HPF是一种算法,不需要深究
cv2.imshow('gray_img', img) # 原始灰度图
cv2.imshow('3x3', k3) # 经过3x3卷积后的图
cv2.imshow('5x5', k5) # 经过5x5卷积后的图
cv2.imshow('blurred', blurred) # 经过高斯运算后的图
cv2.imshow('hpf',hpf) # 经过HPS后的图
cv2.waitKey()
cv2.destroyAllWindows()

运算结果如下:

① 原始灰度图

② 经过3x3卷积后的图

③ 经过5x5卷积后的图

④ 经过高斯运算后的图

⑤ 经过HPS后的图

或许同学们对代码中涉及到的一些算法有些疑惑,这里简述一下"高斯滤波"算法。

高斯滤波是一种线性平滑滤波,对于除去高斯噪声有很好的效果。高斯算法在官方文档给出的解释是高斯滤波是通过对输入数组的每个点与输入的高斯滤波模板执行卷积计算然后将这些结果一块组成了滤波后的输出数组,通俗的讲就是高斯滤波是对整幅图像进行加权平均的过程,每一个像素点的值都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

Canny 边缘检测算法(使用比较频繁)

1. 该算法比较复杂,不过,实现起来共5步,我们看一下:

① 首先用Gaussian滤波对图片进行降噪;

② 计算梯度;

③ 在边缘使用NMS(非极大值抑制)【关于该算法的讲解,后续我会分享】,筛选出最优的边缘检测;

④ 对所有检测到的边缘应用双阈值(比如下面案例中写的200和300);

⑤ 分析所有边缘以及彼此之间的连接,保留真正的边缘,丢弃弱边缘。

2. Canny算法案例:

# Canny 算法
import cv2
import numpy as np 

img = cv2.imread('test.jpg', cv2.IMREAD_GRAYSCALE) # 读取图片,转换为灰度
cv2.imwrite('test_canny.jpg', cv2.Canny(img, 200, 300)) # Canny边缘检测,然后保存新图片
cv2.imshow('Canny', cv2.imread('test_canny.jpg')) # 显示新图片
cv2.waitKey(0)
cv2.destroyAllWindows()

输入图像:

输出图像:

轮廓检测案例:

import cv2
import numpy as np 

img = np.zeros((200, 200), dtype=np.uint8) # 黑色
img[50:150, 50:150] = 255 # 这个区域内的像素值更新为255,白色

ret, thresh = cv2.threshold(img, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
"""方法解析:
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])  

参数:
第一个参数是寻找轮廓的图像;
第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):
    cv2.RETR_EXTERNAL     表示只检测外轮廓
    cv2.RETR_LIST                检测的轮廓不建立等级关系
    cv2.RETR_CCOMP          建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
    cv2.RETR_TREE            建立一个等级树结构的轮廓。

第三个参数method为轮廓的近似办法
    cv2.CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
    cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
    cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 使用teh-Chinl chain 近似算法

返回值
cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。
"""
color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
img = cv2.drawContours(color, contours, -1, (0, 255, 0), 2)
"""方法解析:
cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
参数:
第一个参数是指明在哪幅图像上绘制轮廓;image为三通道才能显示轮廓
第二个参数是轮廓本身,在Python中是一个list;
第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。
第四个参数指定轮廓颜色;
第五个参数表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。
"""
cv2.imshow('contours', color)
cv2.waitKey()
cv2.destroyAllWindows()

输出结果:

本文分享自微信公众号 - 唐国梁Tommy(TangGuoLiangAI),作者:唐国梁Tommy

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-05-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++ OpenCV检测并提取数字华容道棋盘

    一直关注我的朋友应该知道前段时间使用OpenCV做了数字华容道的游戏及AI自动解题,相关文章《整活!我是如何用OpenCV做了数字华容道游戏!(附源码)》《趣玩...

    Vaccae
  • 24K纯干货:OpenCV入门教程

    OpenCV是计算机视觉中最受欢迎的库,最初由intel使用C和C ++进行开发的,现在也可以在python中使用。该库是一个跨平台的开源库,是免费使用的。Op...

    AI算法与图像处理
  • 基于OpenCV的简单边缘检测模型

    本期我们一起看看如何进行图像边缘的检测。边缘检测通常用于理解图像中的对象,帮助机器做出更好的预测。编写边缘检测程序是了解机器如何看待外界的好方法。现在就让我们使...

    小白学视觉
  • CV学习笔记(十四):边缘检测

    在这一篇文章里我们将去学习在计算机视觉中边缘检测的知识,并且去使用OpenCV来实现Canny边缘检测算法。

    云时之间
  • 【从零学习OpenCV 4】Canny算法

    本节中最后介绍的边缘检测算法是Canny算法,该算法不容易受到噪声的影响,能够识别图像中的弱边缘和强边缘,并结合强弱边缘的位置关系,综和给出图像整体的边缘信息。...

    小白学视觉
  • 【计算机视觉处理一】OpenCV入门

    OpenCV是一个跨平台且开源的计算机视觉和机器学习库,全称Open Source Computer Vision Library 。由Intel公司开源。其中...

    ZackSock
  • UWP 手绘视频创作工具技术分享系列 - 位图的绘制

    前面我们针对 SVG 的解析和绘制做了介绍,SVG 是图片的一种形式,而另一种很重要的图片是:位图,包括 png、jpeg、bmp 等格式。位图的基本规则是,组...

    Shao Meng
  • C++ OpenCV三种图像卡通化方法对比

    最近想学习一下深度学习框架,由于是小白,所以先搜集了一下由哪个入门,最终选择了Pytorch,以前一直不想碰还有一个原因是笔记本资源有限,加上个人的业余时间有限...

    Vaccae
  • 【算法随记一】Canny边缘检测算法实现和优化分析。

      以前的博文大部分都写的非常详细,有很多分析过程,不过写起来确实很累人,一般一篇好的文章要整理个三四天,但是,时间越来越紧张,后续的一些算法可能就以随记的方式...

    用户1138785
  • 计算机视觉 OpenCV Android | 特征检测与匹配之角点检测——Harris角点检测与Shi-Tomasi角点检测

    Harris角点检测与Shi-Tomasi角点检测都是经典的角点特征提取算法, 但两者在API的使用上有出入(详见文中代码或GitHub项目);

    凌川江雪
  • 基于OpenCV的图像卡通化

    本期将创建一个类似于Adobe Lightroom的Web应用程序,使用OpenCV和Streamlit实现图像的卡通化

    小白学视觉
  • 在OpenCV中基于深度学习的边缘检测

    分析了Canny的优劣,并给出了OpenCV使用深度学习做边缘检测的流程,文末有代码链接。

    AI算法与图像处理
  • Canny边缘检测算法(基于OpenCV的Java实现)

    Canny边缘检测于1986年由JOHN CANNY首次在论文《A Computational Approach to Edge Detection》中提出,就...

    gyro永不抽风
  • 使用OpenCV检测坑洼

    坑洼是道路的结构性指标,事先发现坑洼地可以延长高速公路的使用寿命,防止事故的发生,同时降低死亡率。

    小白学视觉
  • 使用OpenCV检测坑洼

    坑洼是道路的结构性指标,事先发现坑洼地可以延长高速公路的使用寿命,防止事故的发生,同时降低死亡率。

    OpenCV学堂
  • C++ OpenCV中Canny边缘检测

    Canny边缘检测算子是一种多级检测算法。1986年由John F. Canny提出,同时提出了边缘检测的三大准则:

    Vaccae
  • 使用OpenCV进行模糊检测(拉普拉斯算子)

    这只超可爱、超活跃家养小猎犬可能是有史以来拍照次数最多的狗。从8周大我们得到它的时候,到现在,不到3年的时间,我们已经收集了6000多张狗狗的照片。

    周旋
  • CV学习笔记(十四):边缘检测

    在这一篇文章里我们将去学习在计算机视觉中边缘检测的知识,并且去使用OpenCV来实现Canny边缘检测算法。

    云时之间
  • 你会绘制椭圆吗?

    圆特征在测量领域中应用广泛,比如:相机标定、位姿估计、目标跟踪等方面。圆经过透视投影,当成像平面与圆平面不平行时,圆经过透视投影为椭圆,圆心的透视投影点与椭圆的...

    3D视觉工坊

扫码关注云+社区

领取腾讯云代金券