Canny边缘检测算法实现简单的目标检测

参考博客:

https://www.jianshu.com/p/effb2371ea12

https://www.cnblogs.com/nowgood/p/cannyedge.html

简单的目标检测用边缘检测算法就可以识别出来,先展示一下结果:

这里采用Canny边缘检测,首先回顾以下Canny边缘检测算法的原理,一般分为6个部分,下面逐步介绍每一步过程:

1、图像灰度化

      首先将图像转换成灰度图像,可以理解为是一种降维操作,可以减少计算量。

2、使用高斯滤波器,平滑图像,滤除噪声

       在图像中一般都会包含噪声,噪声会造成图像中边缘信息的丢失,因此可以使用高斯平滑来减少噪声。

二维高斯函数的定义如下:

       高斯滤波其实就是:对高斯函数进行离散化,以离散点上的高斯函数值为权值,对我们采集到的灰度矩阵的每个像素点做一定范围邻域内的加权平均,下面是 (2k+1)x(2k+1) 大小的离散高斯函数(高斯卷积核)的计算公式 :

比如k=1,sigma=1,得到3*3大小的高斯卷积核为:

归一化后得到:

然后进行图像卷积操作,如果图像中一个3x3的窗口为A,要滤波的像素点为e,则经过高斯滤波之后,像素点e的像素值的计算具体如下:

3、计算图像中每个像素点的梯度强度和梯度方向

        边缘检测算子(如Roberts,Prewitt,Sobel等)返回像素点在水平Gx和垂直Gy方向的一阶导数值(梯度),这里选择Sobel算子(也可以用其他差分卷积模板)来计算梯度,因为相对于其他边缘算子,Sobel算子得到的边缘粗大明亮。Sobel算子模板在X和Y方向的分别为:

通过将其与图像进行卷积操作,即可得到像素点在X和Y方向的梯度:

 再通过以下计算公式可得出每个像素点的梯度幅值和梯度方向:

4、对梯度幅值应用非极大值抑制,消除边缘检测带来的杂散响应

       仅仅得到全局的梯度并不足以确定边缘,为了确定边缘,必须保留的是局部梯度最大的点,而非极大值抑制,即将非局部极大值点的像素值置零以得到细化的边缘。

(1)将当前像素的梯度幅值与沿着梯度方向线上的两个像素进行比较;但沿着梯度方向线两侧的像素点不一定是存在的,或者说是亚像素点,而不存在的点, 以及其梯度幅值就必须通过对其两侧的点进行线性插值来得到。

比如当前像素P与沿着梯度方向线上的两个像素P1和P2进行比较,P1和P2的梯度幅值可以通过E和NE处的梯度幅值线性插值得到,具体计算如下:

(2)如果当前像素的梯度幅值与另外两个像素相比都要大,则该像素点保留为边缘点,否则该像素点将被抑制,即该像素点的灰度值设为0。

5、应用双阈值来检测真实的和候选的边缘,去除假阳性(双阈值的选取取决于给定输入图像的内容)

(1)如果边缘像素的梯度幅值高于高阈值,则将其标记为强边缘像素;

(2)如果边缘像素的梯度幅值小于高阈值并且大于低阈值,则将其标记为弱边缘像素;

(3)如果边缘像素的梯度幅值小于低阈值,则该边缘像素被抑制。

6、抑制孤立的弱边缘

通过查看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘像素就可以保留为真实的边缘。

代码实现:

import cv2 as cv
image = cv.imread(r'C:\Users\jwsun\Desktop\a.jpg')
gray_image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
canny_image = cv.Canny(gray_image, 80, 160)#Canny的高低阈值设置一般为2:1
cv.imshow("canny_image", canny_image)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (30, 30))
dilated = cv.dilate(canny_image, kernel)
eroded = cv.erode(dilated, kernel)
contours, hierarchy = cv.findContours(eroded, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# print(len(contours))#打印轮廓的数量
for i in range(0, len(contours)):
    x, y, w, h = cv.boundingRect(contours[i])#得出轮廓最小外接矩形左上角坐标及长、宽信息
    cv.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv.imwrite(r'C:\Users\jwsun\Desktop\b.jpg',image)
cv.imshow('detected_image', image)
cv.waitKey(0)
cv.destroyAllWindows()
运动目标检测在计算机视觉,图像处理,模式识别等多领域有着广泛的应用,经历了多年的研究和探索,针对运动目标检测算法层出不穷,我们也积累了许多相关的算法。但是我们还远没有完成对这个充满挑战的领域的探索。本文对运动目标检测的技术进行了一定的研究,实现了基于canny算子和光流法相结合的运动目标检测方法。为了能够准确把握这个行业的动态,本文首先介绍了运动目标检测的三大经典方法:背景相减法,帧差法,光流法。同时比较了各自的优缺点。帧差法具有易实现,计算量小的优点,但是却无法准确的检测出运动目标的完整轮廓。光流法具有对不断运动的运动目标进行目标检测,但是它却有很大的计算量,同时对噪声也比较敏感。为了可以对运动目标进行更好的识别,我们提出了边缘检测算子与光流法相结合的新方法。在对多种边缘检测算子进行了了解之后,我们确定了利用canny算子进行边缘检测,并且结合光流法进行运动目标检测的方法。在用canny算子检测出运动物体边缘之后,借助光流法计算出物体的运动场,同时结合最大类间方差法分辨出运动目标和背景,接着将物体的边缘信息和物体的运动信息进行融合,最后运用数学形态学的方法对结果进行处理,得到最终的运动目标。通过实验,我们发现该方法既克服了帧差法不能准确检测出运动物体轮廓,和光流法抗噪声能力差的缺点,可以准确检测运动目标,对运动目标具有更好的检测效果
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值