Python 计算机视觉编程进阶之OpenCV 进行霍夫变换

目录
  • 前言
    • (1)读取图像信息
    • (2)霍夫变换的目的及应用
  • 1. 霍夫变换
  • 2. 霍夫线变换
    • (1)基本概念
    • (2)代码实现
  • 3. 霍夫圆变换
    • (1)基本概念
    • (2)代码实现
  • 4. 将所有图像绘制到一张图中
  • 5. 总体代码
  • 结束语

参考的一些文章以及论文我都会给大家分享出来 —— 链接就贴在原文,论文我上传到资源中去,大家可以免费下载学习,如果当天资源区找不到论文,那就等等,可能正在审核,审核完后就可以下载了。大家一起学习,一起进步!加油!!

前言

(1)读取图像信息

经典操作,不必多说:

"""
Author:XiaoMa
date:2021/11/13
"""
import cv2
import matplotlib.pyplot as plt
import numpy as np

img0 = cv2.imread("E:\From Zhihu\For the desk\cvfourteen1.jpg")
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
h, w = img0.shape[:2]
print(h, w)
cv2.imshow("W0", img0)
cv2.imshow("W1", img1)
cv2.waitKey(delay = 0)

525 787

(2)霍夫变换的目的及应用

经典的霍夫变换是被用来检测图像中的直线,后来扩展到任何形状的检测识别中,多为直线和椭圆。所以利用霍夫变换我们可以提取图像中的直线以及其他形状类型的线条。

1. 霍夫变换

霍夫变换是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体。该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换的结果。

霍夫变换运用两个坐标空间的变换将在一个空间中具有相同形状的曲线或者直线映射到另外一个空间的坐标点上形成峰值,从而把检测任意形状的问题转化为统计峰值的问题。

2. 霍夫线变换

(1)基本概念

我们一般理解的在笛卡尔坐标系中表示直线的方式有点线式和两点式,然而在霍夫变换中,考虑的却是另外一种方式:使用 (r, theta) 表示一条直线,其中 r 代表原点到这条直线的距离,theta 表示该直线的垂线与 x 轴的夹角。

那么我们怎么检测直线呢?首先我们为每一个点假设 n 个方向的直线,一般 n 为180,这样检测直线的角度精度为 1 度,分别计算这 n 条直线的(r, theta)坐标,得到 n 个坐标点。那么判断 N 个坐标点就得到 N*n 个 (r, theta)坐标,其中 theta 是离散的角度,有180个取值。当多个点在同一条直线上时,那么这条直线可以通过这些点中的任意一个点的某一个(r_i, theta_i)表示出来(每一个点取到特定的 theta 时得到的 r 相等或者相近)。比如空间中有三个点,下图表示了判断这三个点共线的方式:

可以看出当 Angel(theta) 为 60 时距离 (r) 大致都为80.7,由此可以判断这三个点都在直线(80.7,60)上。

我们也可以绘制一幅 r-theta 坐标系,每一个点的 theta 为横坐标轴,r 为纵坐标,当不同的点出现交点说明这两个点在同一条直线上:

(2)代码实现

本例中使用到了边缘检测来减少计算,如果有小伙伴对边缘检测不熟悉可以去参考我之前的文章:

Python 计算机视觉编程进阶之OpenCV 图像锐化及边缘检测

如果对函数的参数有疑问的话可以参考官网:OpenCV

对于下面的代码,我都添加注释了,应该讲清楚了,如果有注释的不清楚的地方,可以在评论区指出来,大家一起讨论

#霍夫直线检测
##首先进行边缘检测,来减少空间中其他的点带来的计算量的问题
img2 = cv2.GaussianBlur(img1, (5, 5), 0)   #高斯模糊为边缘检测做准备
img3 = cv2.Canny(img2, 50, 120)            #使用Canny算子进行边缘检测
cv2.imshow("W2", img3)
cv2.waitKey(delay = 0)
rho = 1                    #距离分辨率
theta = np.pi/180          #角度分辨率
threshold = 10             #霍夫空间中多少个曲线相交表示一个正式的交点
min_line_len = 50          #最少需要多少个像素点才构成一条直线
max_line_gap = 50          #线段之间的最大间隔像素点数
lines = cv2.HoughLinesP(img3, rho, theta, threshold, maxLineGap = max_line_gap)    #所以这个函数中的参数都已经在前面赋值时解释过了
img4 = np.zeros_like(img3)
for line in lines:
    for x1, y1, x2, y2 in line:
        cv2.line(img4, (x1, y1), (x2, y2), 255, 1)        #绘制直线
cv2.imshow("W3", img4)
cv2.waitKey(delay = 0)

得到的边缘检测图像为:

得到的霍夫直线检测的图像为:

当然霍夫直线检测用在其他的比如建筑等方面才是好钢用在刀刃上,这里作为示范用了人像。

3. 霍夫圆变换

(1)基本概念

一般来说,表示一个圆需要知道它的半径以及圆心,这样我们需要 (x, y, r) 三个参数,如果只是靠这种方法识别圆,那么对于计算机来说计算效率会下降。

在 OpenCV 中是使用了霍夫梯度的方法,利用边界梯度信息。首先使用 Canny() 进行边缘检测,对边缘的每一个非 0 通过 Sobel() 进行局部梯度计算(Sobel() 算子也在前面的文章中介绍过了),得到的梯度方向就是圆切线的方向,得到3个切线就可以确定圆心了。

(2)代码实现

已添加注释:

#霍夫圆检测
dp = 1              #检测内测圆心的累加器图像的分辨率与输入图像之比的倒数
minDist = 700       #两个圆之间圆心之间的最小距离
param1 = 100        #前面提到过 Canny 边缘检测,这个参数表示传递给边缘检测的高阈值
param2 = 80         #检测阶段圆心的累加器阈值,简单来说该参数越大检测到的圆越完美,但数目越少,反之亦然
minRadius = 10      #最小圆的半径
maxRadius = 20      #最大圆的半径
cirlces = cv2.HoughCircles(img2, cv2.HOUGH_GRADIENT, dp, minDist, param1, param2, minRadius, maxRadius)  #函数的参数前面解释过了
cirlces = np.uint16(np.around(cirlces))
for i in cirlces[0, :]:
    cv2.circle(img0, (i[0], i[1]), i[2], (0, 0, 255), 1)
    cv2.circle(img0, (i[0], i[1]), 2, (0, 0, 255), 1)
cv2.imshow("W4", img0)
cv2.waitKey(delay = 0)

可以看出对人像的检测局限于头部,哈哈哈哈,建议大家多改几次参数进行尝试,会得到不一样的体验,也可以多换几张图进行测试。

4. 将所有图像绘制到一张图中

都是一些常规问题,没啥好注释的

#将所有图像绘制在一张图纸上
img0 = cv2.imread("E:\From Zhihu\For the desk\cvfourteen1.jpg")   #再次读取原图,前面的图像已经进行了变换
plt.rcParams['font.family'] = 'SimHei'       #将全局中文字体改为黑体
imgs = [img0, img1, img2, img3, img4, img5]
title = ['原图', '灰度图', '高斯模糊', '边缘检测', '霍夫直线检测', '霍夫圆检测']
for i in range(6):
    imgs[i] = cv2.cvtColor(imgs[i], cv2.COLOR_BGR2RGB)
    plt.subplot(2, 3, i + 1)
    plt.imshow(imgs[i])
    plt.title(title[i])
    plt.xticks([])
    plt.yticks([])
plt.show()

5. 总体代码

修改图像路径就可以用了,但还是建议小伙伴们一步步来。

"""
Author:XiaoMa
date:2021/11/13
"""
import cv2
import matplotlib.pyplot as plt
import numpy as np

img0 = cv2.imread("E:\From Zhihu\For the desk\cvfourteen1.jpg")
#img0 = cv2.resize(img0, dsize = None, fx = 0.5, fy = 0.5)
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
h, w = img0.shape[:2]
print(h, w)
cv2.imshow("W0", img0)
cv2.imshow("W1", img1)
cv2.waitKey(delay = 0)
#霍夫直线检测
##首先进行边缘检测,来减少空间中其他的点带来的计算量的问题
img2 = cv2.GaussianBlur(img1, (5, 5), 0)   #高斯模糊为边缘检测做准备
img3 = cv2.Canny(img2, 50, 120)            #使用Canny算子进行边缘检测
cv2.imshow("W2", img3)
cv2.waitKey(delay = 0)
rho = 1                    #距离分辨率
theta = np.pi/180          #角度分辨率
threshold = 10             #霍夫空间中多少个曲线相交表示一个正式的交点
min_line_len = 50          #最少需要多少个像素点才构成一条直线
max_line_gap = 50          #线段之间的最大间隔像素点数
lines = cv2.HoughLinesP(img3, rho, theta, threshold, maxLineGap = max_line_gap)    #所以这个函数中的参数都已经在前面赋值时解释过了
img4 = np.zeros_like(img3)
for line in lines:
    for x1, y1, x2, y2 in line:
        cv2.line(img4, (x1, y1), (x2, y2), 255, 1)        #绘制直线
cv2.imshow("W3", img4)
cv2.waitKey(delay = 0)
#霍夫圆检测
dp = 1              #检测内测圆心的累加器图像的分辨率与输入图像之比的倒数
minDist = 700       #两个圆之间圆心之间的最小距离
param1 = 100        #前面提到过 Canny 边缘检测,这个参数表示传递给边缘检测的高阈值
param2 = 80         #检测阶段圆心的累加器阈值,简单来说该参数越大检测到的圆越完美,但数目越少,反之亦然
minRadius = 10      #最小圆的半径
maxRadius = 20      #最大圆的半径
cirlces = cv2.HoughCircles(img2, cv2.HOUGH_GRADIENT, dp, minDist, param1, param2, minRadius, maxRadius)  #函数的参数前面解释过了
cirlces = np.uint16(np.around(cirlces))
img5 = img0
for i in cirlces[0, :]:
    cv2.circle(img5, (i[0], i[1]), i[2], (0, 0, 255), 1)
    cv2.circle(img5, (i[0], i[1]), 2, (0, 0, 255), 1)
cv2.imshow("W4", img5)
cv2.waitKey(delay = 0)
#将所有图像绘制在一张图纸上
img0 = cv2.imread("E:\From Zhihu\For the desk\cvfourteen1.jpg")   #再次读取原图,前面的图像已经进行了变换
plt.rcParams['font.family'] = 'SimHei'       #将全局中文字体改为黑体
imgs = [img0, img1, img2, img3, img4, img5]
title = ['原图', '灰度图', '高斯模糊', '边缘检测', '霍夫直线检测', '霍夫圆检测']
for i in range(6):
    imgs[i] = cv2.cvtColor(imgs[i], cv2.COLOR_BGR2RGB)
    plt.subplot(2, 3, i + 1)
    plt.imshow(imgs[i])
    plt.title(title[i])
    plt.xticks([])
    plt.yticks([])
plt.show()

结束语

本文主要总结了霍夫变换的基本概念和代码实现,包括线变换和圆变换,建议大家多尝试,一些参数什么的多修改多试试。本篇文章主要参考的是《Python计算机视觉》这边书,清华大学出版的,大家感兴趣可以找来看看。

到此这篇关于Python 计算机视觉编程进阶之OpenCV 进行霍夫变换的文章就介绍到这了,更多相关Python OpenCV 霍夫变换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解利用python+opencv识别图片中的圆形(霍夫变换)

    在图片中识别足球 先补充下霍夫圆变换的几个参数知识: dp,用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,且此参数允许创建一个比输入图像分辨率低的累加器.上述文字不好理解的话,来看例子吧.例如,如果dp= 1时,累加器和输入图像具有相同的分辨率.如果dp=2,累加器便有输入图像一半那么大的宽度和高度. minDist,为霍夫变换检测到的圆的圆心之间的最小距离,即让我们的算法能明显区分的两个不同圆之间的最小距离.这个参数如果太小的话,多个相邻的圆可能被错误地检测成了一个重合的圆.反之,这个

  • python+opencv实现霍夫变换检测直线

    本文实例为大家分享了python+opencv实现霍夫变换检测直线的具体代码,供大家参考,具体内容如下 python+opencv实现高斯平滑滤波 python+opencv实现阈值分割 功能: 创建一个滑动条来控制检测直线的长度阈值,即大于该阈值的检测出来,小于该阈值的忽略 注意:这里用的函数是HoughLinesP而不是HoughLines,因为HoughLinesP直接给出了直线的断点,在画出线段的时候可以偷懒 代码: # -*- coding: utf-8 -*- import cv2

  • 如何基于OpenCV&Python实现霍夫变换圆形检测

    简述 基于python使用opencv实现在一张图片中检测出圆形,并且根据坐标和半径标记出圆.不涉及理论,只讲应用. 霍夫变换检测圆形的原理 其实检测圆形和检测直线的原理差别不大,只不过直线是在二维空间,因为y=kx+b,只有k和b两个自由度.而圆形的一般性方程表示为(x-a)²+(y-b)²=r².那么就有三个自由度圆心坐标a,b,和半径r.这就意味着需要更多的计算量,而OpenCV中提供的cvHoughCircle()函数里面可以设定半径r的取值范围,相当于有一个先验设定,在每一个r来说,在

  • Python 计算机视觉编程进阶之OpenCV 进行霍夫变换

    目录 前言 (1)读取图像信息 (2)霍夫变换的目的及应用 1. 霍夫变换 2. 霍夫线变换 (1)基本概念 (2)代码实现 3. 霍夫圆变换 (1)基本概念 (2)代码实现 4. 将所有图像绘制到一张图中 5. 总体代码 结束语 参考的一些文章以及论文我都会给大家分享出来 -- 链接就贴在原文,论文我上传到资源中去,大家可以免费下载学习,如果当天资源区找不到论文,那就等等,可能正在审核,审核完后就可以下载了.大家一起学习,一起进步!加油!! 前言 (1)读取图像信息 经典操作,不必多说: "&

  • Python 计算机视觉编程进阶之OpenCV 图像锐化及边缘检测

    目录 前言 (1)图像锐化 (2)图像边缘检测 a. 图像边缘 b. 边缘检测 1. 一阶微分算算子.二阶微分算子 2. 读取图像信息 3. Sobel 算子 4. Laplacian 算子 5. Scharr 算子 6. Canny 算子 7. 总结 8. 参考论文 参考的一些文章以及论文我都会给大家分享出来 -- 链接就贴在原文,论文我上传到资源中去,大家可以免费下载学习,如果当天资源区找不到论文,那就等等,可能正在审核,审核完后就可以下载了.大家一起学习,一起进步!加油!! 前言 (1)图

  • Python 计算机视觉编程进阶之图像特效处理篇

    前言 图像特效处理一般是对图像的像素点的通道.灰度值值等进行操作,达到想要的结果,下面将会给大家一一呈现一些简单特效的原理以及代码实现,希望能够对大家有一定的帮助. 话不多说,先是本系列文章的经典操作之读取图像信息: """ Author:XiaoMa date:2021/11/16 """ import cv2 import numpy as np import math import matplotlib.pyplot as plt img0

  • python计算机视觉OpenCV库实现实时摄像头人脸检测示例

    目录 设备准备: 实现过程 调用模型库文件 打开摄像头 人脸检测 设置退出机制 程序运行 全部代码 OpenCV 是一个C++库,目前流行的计算机视觉编程库,用于实时处理计算机视觉方面的问题,它涵盖了很多计算机视觉领域的模块.在Python中常使用OpenCV库实现图像处理. 本文将介绍如何在Python3中使用OpenCV实现实时摄像头人脸检测: 设备准备: USB摄像头 接入PC电脑USB口,并调试正常打开视频.如果电脑内置了电脑摄像头,测试一下摄像头能否正常使用. 下载特征分类模型: XM

  • python编程进阶之类和对象用法实例分析

    本文实例讲述了python类和对象用法.分享给大家供大家参考,具体如下: 前面我们都是用python面向过程编程,现在来用python创建类和对象,面向对象编程.类和对象是面向对象编程的两个主要方面.类创建一个新类型,而对象这个类的 实例 .这类似于你有一个int类型的变量,这存储整数的变量是int类的实例(对象).在python中,类和实例中的变量称为域,类和实例中的函数称为方法,域和方法都是类和实例的属性. 类的定义 在定义类或者它的函数的时候,如果没有参数的话,需要把参数写为self,这样

  • python计算机视觉opencv图像金字塔轮廓及模板匹配

    目录 1.图像金字塔 ①高斯金字塔 ②拉普拉斯金字塔 2.图像轮廓 ①寻找轮廓 ②轮廓特征 ③轮廓绘制 3.模板匹配 ①模板匹配 ②匹配框线绘制 ③多对象匹配 4.直方图统计 ①直方图绘制 ②直方图统计 ③直方图的mask操作 ④直方图均衡化 5.傅里叶变换 1.图像金字塔 ①高斯金字塔 向下采样,数据会越来越少,减少的方式是:将偶数行和列删除 向上采样,数据会越来越多,将图像在每个方向上扩大为原来的两倍,新增的行和列用0来填充.使用先前同样的内核与放大后的图像卷积,获得近似值. 上采样之后,图

  • python计算机视觉opencv卡号识别示例详解

    目录 一.模板预处理 1.将模板设置为二值图 2.检测模板的轮廓 3.对模板轮廓排序,并将数字和轮廓一一对应,以字典存储 4.备注 二.图片预处理 1.初始化卷积核 2.图片预处理第一部分 3.图像预处理第二部分 三.轮廓处理 1.大轮廓过滤 2.小轮廓分割 模板图片如下: 需识别的图片如下: 一.模板预处理 1.将模板设置为二值图 2.检测模板的轮廓 3.对模板轮廓排序,并将数字和轮廓一一对应,以字典存储 排序的函数如下: 排序并存储: 4.备注 ①每一个数字对应的是二值图截出来的那个数字图的

  • python计算机视觉opencv矩形轮廓顶点位置确定

    目录 一.问题的引入 二.问题的解决方法 方法一: 方法二 三.一些实现代码 一.问题的引入 opencv在图像处理方面有着非常强大的功能,当我们需要使用opencv进行一些图像的矫正工作时,我们通常需要找到原图的一些关键点,然后计算变换后的图像坐标,最后通过仿射变换或者透视变换获得自己想要的矫正图像,比如将一张拍歪了的纸进行矫正,我们的首要任务就是找到原图的一些关键点,通常的做法就是找纸张的4个顶点. 二.问题的解决方法 第一步我们肯定要找到纸张相应的矩形轮廓,这里可以二值化再找,也可以使用一

  • python计算机视觉OpenCV入门讲解

    目录 前言 一.什么是计算机视觉 二.图片处理基础操作 图片处理:读入图像 图片处理:显示图像 图片处理:图像保存 三.图像处理入门基础 图像成像原理介绍 图像分类 四.灰度图像 五.彩色图像(RGB) 六.像素处理操作 读取像素 修改像素 使用python中的numpy修改像素点 七.获取图像属性 形状 像素数目 图像类型 八.图像ROI 九.通道的拆分与合并 拆分 合并 前言 本专栏将非常细致的讲解相关与计算机视觉OpenCV的相关知识即操作,非常的简单易懂.本文主要讲解相关与计算机视觉的相

随机推荐