opencv目标检测之canny算法

canny

canny的目标有3个

  • 低错误率 检测出的边缘都是真正的边缘
  • 定位良好 边缘上的像素点与真正的边缘上的像素点距离应该最小
  • 最小响应 边缘只能标识一次,噪声不应该标注为边缘

canny分几步

  • 滤掉噪声 比如高斯滤波
  • 计算梯度 比如用索贝尔算子算出梯度
  • 非极大值抑制
    上一步算出来的边缘可能比较粗糙,假设边缘是一条很细的线的话,上面处理完的结果你可以理解为得到一条比较粗的线条,所谓非极大值抑制,就是要在局部像素点中找到变换最剧烈的一个点,这样就得到了更细的边缘.
  • 双阈值检测和连接边缘

前面2步我们应该很熟悉了,不熟悉的参考https://www.cnblogs.com/sdu20112013/p/11608469.htmlhttps://www.cnblogs.com/sdu20112013/p/11600436.html

非极大值抑制

在求解梯度这一步,我们可以得到梯度的模长和方向

这一步为我们下面做nms(非极大值抑制)打下了基础,索贝尔算子处理后的图像得到的边缘可能是很粗糙的,反映到图像上也就是边缘比较宽,我们采用nms把非极大值的点的灰度都置为0,这样就可以滤掉很多非边缘的像素点.

如下图所示,C表示为当前非极大值抑制的点,g1-4为它的8连通邻域点,图中蓝色线段表示上一步计算得到的角度图像C点的值,即梯度方向,第一步先判断C灰度值在8值邻域内是否最大,如是则继续检查图中梯度方向交点dTmp1,dTmp2值是否大于C,如C点大于dTmp1,dTmp2点的灰度值,则认定C点为极大值点,置为1,因此最后生成的图像应为一副二值图像,边缘理想状态下都为单像素边缘.

这一步里有一点需要注意的就是dTmp1,dTmp2,这两个像素点是不存在的,是通过双线性插值法算出来的. 在John Canny提出的Canny算子的论文中,非最大值抑制就只是在0、90、45、135四个梯度方向上进行的,每个像素点梯度方向按照相近程度用这四个方向来代替.实际检测过程里,为了更准确地过滤出属于边缘的像素点,会做双线性插值得到dTmp1,dTmp2.再去做前面所说的nms过程去判断一个像素点是否属于边缘.
推荐2篇讲的比较好的:https://blog.csdn.net/kezunhai/article/details/11620357 https://www.cnblogs.com/techyan1990/p/7291771.html

关于如何得到梯度方向的像素点,如下图所示

这样的话就达到了将"粗大的边缘"过滤地更加细腻.

这一步之后,得到的边缘还包含很多由噪声及其他原因造成的假边缘.

双阈值检测和边缘连接

经过nms以后,已经很接近真实边缘了.但还是有一些由于噪声或者别的一些原因造成的假的边缘.我们通过2个阈值来作进一步的过滤.

Hysteresis: The final step. Canny does use two thresholds (upper and lower): - If a pixel gradient is higher than the upper threshold, the pixel is accepted as an edge .If a pixel gradient value is below the lower threshold, then it is rejected.If the pixel gradient is between the two thresholds, then it will be accepted only if it is connected to a pixel that is above the upper threshold.
Canny recommended a upper:lower ratio between 2:1 and 3:1.

  • 对于梯度大于高阈值的点,认为是真的边缘上的像素点.
  • 对于梯度小于低阈值的点,认为是假的边缘像素点,是噪声造成的,去掉这些点.
  • 对于梯度介于高低阈值之间的点,如果它周围的邻域像素点有"真边缘点"(也就是梯度大于高阈值的点),则认为这点也是"真边缘点".
    推荐的高低阈值比在2:1到3:1之间

实际工程里,这两个参数要针对你自己的图像数据去调整,太低有可能造成假边缘太多,太高有可能造成想要保留的边缘也被滤掉了.
canny api

参数3,4表示低阈值和高阈值,L2gradient默认false,表示是否用开平方的方式计算梯度的大小.

opencv示例

from __future__ import print_function
import cv2 as cv
import argparse
max_lowThreshold = 100
window_name = 'Edge Map'
title_trackbar = 'Min Threshold:'
ratio = 3
kernel_size = 3
def CannyThreshold(val):
    low_threshold = val
    #img_blur = cv.blur(src_gray, (3,3))
    detected_edges = cv.Canny(src_gray, low_threshold, low_threshold*ratio, kernel_size)
    mask = detected_edges != 0
    dst = src * (mask[:,:,None].astype(src.dtype))
    cv.imshow(window_name, dst)

src = cv.imread("/home/sc/disk/keepgoing/opencv_test/sidetest.jpeg")
src = cv.GaussianBlur(src, (3, 3), 0)
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
cv.namedWindow(window_name)
cv.createTrackbar(title_trackbar, window_name , 0, max_lowThreshold, CannyThreshold)
CannyThreshold(0)
cv.waitKey()

注意阈值的不同造成的影响,可以看到阈值很低的时候线条更多,当然"伪边缘"更多,当阈值很高的时候,"伪边缘"减少了,但也丢失了更多的细节.所以需要根据自己实际的图片数据去调参.

原文地址:https://www.cnblogs.com/sdu20112013/p/11614059.html

时间: 2024-07-31 08:02:58

opencv目标检测之canny算法的相关文章

openCV目标检测学习笔记(一)

最近在研究一些基于openCV的目标检测算法,由浅入深,今天是第一天. 首先网上下载了一份较简单的来对视频中运动物体进行二值显示的代码进行学习,以下是我的理解,初学者会犯一些错希望大家予以指正. #include<cv.h>#include "cxcore.h"#include<highgui.h> int main(int argc,unsigned char* argv[]) { CvCapture* capture = cvCreateFileCaptur

第二十八节,目标检测算法之R-CNN算法详解

Girshick, Ross, et al. "Rich feature hierarchies for accurate object detection and semantic segmentation." Proceedings of the IEEE conference on computer vision and pattern recognition. 2014. R-CNN的全称是Region-CNN,它可以说是第一个成功将深度学习应用到目标检测上的算法.后面要讲到的

5. 目标检测算法之R-CNN算法详解(转)

5. 目标检测算法之R-CNN算法详解(转) 原文链接:https://www.cnblogs.com/zyly/p/9246221.html 目录 一 R-CNN思路 二 算法简述 三 训练步骤 四 优缺点 Girshick, Ross, et al. "Rich feature hierarchies for accurate object detection and semantic segmentation." Proceedings of the IEEE conferenc

第三十六节,目标检测之yolo源码解析

在一个月前,我就已经介绍了yolo目标检测的原理,后来也把tensorflow实现代码仔细看了一遍.但是由于这个暑假事情比较大,就一直搁浅了下来,趁今天有时间,就把源码解析一下.关于yolo目标检测的原理请参考前面一篇文章:第三十五节,目标检测之YOLO算法详解 在讲解源码之前,我们需要做一些准备工作: 下载源码,本文所使用的yolo源码来源于网址:https://github.com/hizhangp/yolo_tensorflow 下载训练所使用的数据集,我们仍然使用以VOC 2012数据集

R-CNN系列目标检测博文汇总

R-CNN [深度学习]R-CNN 论文解读及个人理解 [目标检测]RCNN算法详解 R-CNN论文翻译解读 总之,R-CNN取得成功的两个关键因素:1:在候选区域上自下而上使用大型卷积神经网络(CNNs),用以定位和分割物体.2:当带标签的训练数据不足时,先针对辅助任务进行有监督预训练,再进行特定任务的调优,就可以产生明显的性能提升 简单来说,RCNN使用以下四步实现目标检测: a. 在图像中确定约1000-2000个候选框 b. 对于每个候选框内图像块,使用深度网络提取特征 c. 对候选框中

opencv 检测图像边缘 Canny算法应用

图解边缘检测 opencv 应用Canny算法进行边缘检测 import cv2 as cv import numpy as np img = cv.imread('baby_g.jpg', 0) # 二值化图像处理后,边缘检测效果更好 _, thresh = cv.threshold(img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU) # canny边缘检测,60以下置为0,180以上置为255,第2.3参数的作用可查看本文最后一部分内容 edges

目标检测程序开发(二)——Boosting算法简介

本文主要参考了OpenCV的官方文档 http://docs.opencv.org/modules/ml/doc/boosting.html boosting算法是一个监督式机器学习算法,它解决的是一个二元分类问题.本文包括对算法思想的理解,不包含算法的数学推导. 目标检测就是用这个分类算法,把只含有目标的图片作为一类,不含有目标的作为另一类,然后训练分类器,进行检测的时候,输入一张图片,用一个窗口扫描这个图片,对每个窗口应用分类器,返回是目标的类别时,就检测到了目标. 监督式机器学习目标是找到

一文带你学会使用YOLO及Opencv完成图像及视频流目标检测(上)|附源码

计算机视觉领域中,目标检测一直是工业应用上比较热门且成熟的应用领域,比如人脸识别.行人检测等,国内的旷视科技.商汤科技等公司在该领域占据行业领先地位.相对于图像分类任务而言,目标检测会更加复杂一些,不仅需要知道这是哪一类图像,而且要知道图像中所包含的内容有什么及其在图像中的位置,因此,其工业应用比较广泛.那么,今天将向读者介绍该领域中表现优异的一种算算法--"你只需要看一次"(you only look once,yolo),提出该算法的作者风趣幽默可爱,其个人主页及论文风格显示了其性

深度学习之目标检测常用算法原理+实践精讲 YOLO / Faster RCNN / SSD / 文本检测 / 多任务网络

深度学习之目标检测常用算法原理+实践精讲 YOLO / Faster RCNN / SSD / 文本检测 / 多任务网络 资源获取链接:点击这里 第1章 课程介绍 本章节主要介绍课程的主要内容.核心知识点.课程涉及到的应用案例.深度学习算法设计通用流程.适应人群.学习本门课程的前置条件.学习后达到的效果等,帮助大家从整体上了解本门课程的整体脉络. 1-1 课程导学 第2章 目标检测算法基础介绍 本章节主要介绍目标检测算法的基本概念.传统的目标检测算法.目前深度学习目标检测主流方法(one-sta