边缘检测与霍夫变换检测圆教程(学习笔记)

边缘检测与霍夫变换检测圆教程(学习笔记,仅供参考)

1、简介

边缘检测是计算机视觉中的一项基础技术,用于识别图像中物体的边界。霍夫变换是一种特征提取技术,能够从复杂背景中识别几何形状,如直线、圆形等。本教程将介绍边缘检测的基本概念和霍夫变换检测圆的数学原理,并提供Python代码示例,帮助新手理解和实践这两种技术。

2、边缘检测

边缘检测的目的是在图像中识别出显著的边缘,这些边缘通常表示物体的轮廓。常用的边缘检测算法包括Sobel、Canny等。这些算法通过计算图像中像素点的梯度来识别边缘。

3、霍夫变换

霍夫变换是一种用于检测几何形状的技术。它通过将图像空间转换到参数空间来识别特定的形状。

3.1、数学原理

霍夫变换利用事实:在图像空间中的一条直线可以在参数空间中表示为一个点。相应地,一个圆可以由三个参数表示:圆心的x坐标、y坐标以及半径。

霍夫变换检测圆的过程可以简化为:

  1. 对于图像中的每个边缘点,根据可能的半径值在参数空间中画出一系列圆或直线。
  2. 在参数空间中,多个圆或直线交点处的累积值较高,这些点对应于图像空间中的圆形。

3.2、检测圆的步骤

3.2.1、已知半径–步骤(第1种情况):
  1. 应用边缘检测算法,识别图像中的边缘
  2. 对于每个边缘点,根据已知的半径,在参数空间中画圆
  3. 在参数空间中寻找累积值高的点,这些点对应的参数即为图像中圆的位置和大小。
3.2.2、已知半径(第1种情况

左图的圆边上点(x,y)-----> 对应右图的圆心(x,y)
左图的圆心点(a,b)-----> 对应右图的圆边上点(a,b)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.3、不知道知半径(第2种情况):
  1. 应用边缘检测算法,识别图像中的边缘
  2. 对于每个边缘点,根据不同的半径,在三维参数空间画直线
  3. 在三维参数空间中寻找累积值高的点,这些点对应的参数即为图像中圆的位置和大小。
3.2.4、不知道半径(第2种情况

思路:
1、面临的问题是:不知道图片的任意一点是否某个圆边上的点
2、但知道一个事实:如果某个点是圆边上的点,那么对应的圆心必在这个点的梯度方向上,如下图所示

在这里插入图片描述
3、由2这个事实知道:圆心在梯度方向这条直线上,如下图所示

在这里插入图片描述
4、对应到霍夫空间:梯度方向这条直线上的所有点可以表示为可能的圆心,每个可能的圆心对应3个可能的参数(a,b,r)
如下图所示,因此对应到霍夫空间就是一条斜线,以此类推,在霍夫空间可以画出很多条斜线,最后,
霍夫空间中斜线相交最越多的点就越可能是圆

在这里插入图片描述

4、Python演示代码

以下是使用OpenCV库进行霍夫变换检测圆的Python代码示例:

import cv2
import numpy as np

# 加载图像
image = cv2.imread('your_image_path.jpg', 0)
# 应用Canny边缘检测
# image:输入图像,应为灰度图。
# 50:低阈值(low threshold)。如果像素梯度小于此值,它不会被认为是边缘。
# 150:高阈值(high threshold)。如果像素梯度高于此值,它一定会被认为是边缘。
# apertureSize=3:Sobel算子的大小,它用于计算图像梯度。此参数可选,默认值为3。它必须是1, 3, 5, 或 7中的一个。
edges = cv2.Canny(image, 50, 150, apertureSize=3)

# 应用霍夫变换检测圆
# edges:输入图像,通常是使用Canny算法预处理过的边缘检测结果。
# cv2.HOUGH_GRADIENT:检测方法。这是实现霍夫圆变换的唯一方法。
# 1:dp,图像分辨率与累加器分辨率的比值。如果dp=1,则累加器具有与输入图像相同的分辨率。如果dp=2,累加器的分辨率是输入图像的一半。
# 20:minDist,圆心之间的最小距离。如果参数太小,可能会错误地将多个相邻的圆检测为一个圆。如果太大,可能会错过一些圆。
# param1=50:高阈值(由Canny边缘检测器使用)。通常与前面的Canny边缘检测的高阈值一致。
# param2=30:累加器阈值。它是检测到圆的累加器阈值。值越小,检测到的假圆的可能性越大。值越大,可能会错过一些圆。
# minRadius=0:圆的最小半径。默认为0。
# maxRadius=0:圆的最大半径。默认为0,表示最大半径不限。
circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=0, maxRadius=0)

# 画出检测到的圆
if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        # 画圆
        cv2.circle(image, (i[0], i[1]), i[2], (0, 255, 0), 2)
        # 画圆心
        cv2.circle(image, (i[0], i[1]), 2, (0, 0, 255), 3)

# 显示结果图像
cv2.imshow('Detected Circles', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码效果
在这里插入图片描述
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值