欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十年的编程经验分享给大家,希望对您有所帮助,文章中不足之处也请海涵。Python系列整体框架包括基础语法10篇、网络爬虫30篇、可视化分析10篇、机器学习20篇、大数据分析20篇、图像识别30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的关注、点赞和转发就是对秀璋最大的支持,知识无价人有情,希望我们都能在人生路上开心快乐、共同成长。
该系列文章主要讲解Python OpenCV图像处理和图像识别知识,前期主要讲解图像处理基础知识、OpenCV基础用法、常用图像绘制方法、图像几何变换等,中期讲解图像处理的各种运算,包括图像点运算、形态学处理、图像锐化、图像增强、图像平滑等,后期研究图像识别、图像分割、图像分类、图像特效处理以及图像处理相关应用。
第一部分作者介绍了图像处理基础知识,第二部分介绍了图像运算和图像增强,接下来第三部分我们将详细讲解图像识别及图像处理经典案例,该部分属于高阶图像处理知识,能进一步加深我们的理解和实践能力。在数字图像处理中,有两个经典的变换被广泛应用——傅里叶变换和霍夫变换。其中,傅里叶变换主要是将时间域上的信号转变为频率域上的信号,用来进行图像除噪、图像增强等处理;霍夫变换主要用来辨别找出物件中的特征,用来进行特征检测、图像分析、数位影像处理等处理。本文主要讲解图像霍夫变换,希望文章对您有所帮助,如果有不足之处,还请海涵。
下载地址:记得点赞喔 O(∩_∩)O
前文赏析:(尽管该部分占大量篇幅,但我舍不得删除,哈哈!)
第一部分 基础语法
第二部分 网络爬虫
第三部分 数据分析和机器学习
第四部分 Python图像处理基础
第五部分 Python图像运算和图像增强
第六部分 Python图像识别和图像高阶案例
第七部分 NLP与文本挖掘
第八部分 人工智能入门知识
第九部分 网络攻防与AI安全
第十部分 知识图谱构建实战
扩展部分 人工智能高级案例
作者新开的“娜璋AI安全之家”将专注于Python和安全技术,主要分享Web渗透、系统安全、人工智能、大数据分析、图像识别、恶意代码检测、CVE复现、威胁情报分析等文章。虽然作者是一名技术小白,但会保证每一篇文章都会很用心地撰写,希望这些基础性文章对你有所帮助,在Python和安全路上与大家一起进步。
霍夫变换(Hough Transform)是一种特征检测(Feature Extraction),被广泛应用在图像分析、计算机视觉以及数位影像处理。 霍夫变换是在1959年由气泡室(Bubble Chamber)照片的机器分析而发明,发明者Paul Hough在1962年获得美国专利。现在广泛使用的霍夫变换是由Richard Duda和Peter Hart在1972年发明,并称之为广义霍夫变换。经典的霍夫变换是检测图片中的直线,之后,霍夫变换不仅能识别直线,也能够识别任何形状,常见的有圆形、椭圆形。1981年,因为Dana H.Ballard的一篇期刊论文“Generalizing the Hough transform to detect arbitrary shapes”,让霍夫变换开始流行于计算机视觉界。
霍夫变换是一种特征提取技术,用来辨别找出物件中的特征,其目的是通过投票程序在特定类型的形状内找到对象的不完美实例。这个投票程序是在一个参数空间中进行的,在这个参数空间中,候选对象被当作所谓的累加器空间中的局部最大值来获得,累加器空间是由计算霍夫变换的算法明确地构建。霍夫变换主要优点是能容忍特征边界描述中的间隙,并且相对不受图像噪声的影响。
最基本的霍夫变换是从黑白图像中检测直线,它的算法流程大致如下:给定一个物件和要辨别的形状的种类,算法会在参数空间中执行投票来决定物体的形状,而这是由累加空间里的局部最大值来决定。假设存在直线公式如(1)所示,其中m表示斜率,b表示截距。
如果用参数空间表示,则直线为(b, m),但它存在一个问题,垂直线的斜率不存在(或无限大),使得斜率参数m值接近于无限。为此,为了更好的计算,Richard O. Duda和Peter E. Hart在1971年4月,提出了Hesse normal form(Hesse法线式),如公式(2)所示,它转换为直线的离散极坐标公式。
其中r是原点到直线上最近点的距离,θ是x轴与连接原点和最近点直线之间的夹角,如图1所示。
对于点(x0, y0),可以将通过这个点的一族直线统一定义为公式(3)。因此,可以将图像的每一条直线与一对参数(r,θ)相关联,相当于每一对(r0,θ)代表一条通过点的直线(x0, y0),其中这个参数(r,θ)平面被称为霍夫空间。
然而在实现的图像处理领域,图像的像素坐标P(x, y)是已知的,而(r,θ)是需要寻找的变量。如果能根据像素点坐标P(x, y)值绘制每个(r,θ)值,那么就从图像笛卡尔坐标系统转换到极坐标霍夫空间系统,这种从点到曲线的变换称为直线的霍夫变换。变换通过量化霍夫参数空间为有限个值间隔等分或者累加格子。
当霍夫变换算法开始,每个像素坐标点P(x, y)被转换到(r,θ)的曲线点上面,累加到对应的格子数据点,当一个波峰出现时候,说明有直线存在。如图2所示,三条正弦曲线在平面相交于一点,该点坐标(r0,θ)表示三个点组成的平面内的直线。这就是使用霍夫变换检测直线的过程,它追踪图像中每个点对应曲线间的交点,如果交于一点的曲线的数量超过了阈值,则认为该交点所代表的参数对(r0,θ)在原图像中为一条直线。
同样的原理,可以用来检测圆,对于圆的参数方程变为如下等式:
其中(a, b)为圆的中心点坐标,r圆的半径。这样霍夫参数空间就变成一个三维参数空间。给定圆半径转为二维霍夫参数空间,变换相对简单,也比较常用。
在OpenCV中,霍夫变换分为霍夫线变换和霍夫圆变换,其中霍夫线变换支持三种不同方法——标准霍夫变换、多尺度霍夫变换和累计概率霍夫变换[3]。
在OpenCV 中,通过函数HoughLines()检测直线,并且能够调用标准霍夫变换(SHT)和多尺度霍夫变换(MSHT),其函数原型如下所示:
下面的代码是调用HoughLines()函数检测图像中的直线,并将所有的直线绘制于原图像中。
# -*- coding: utf-8 -*-
# By: Eastmount
import cv2
import numpy as np
from matplotlib import pyplot as plt
import matplotlib
#读取图像
img = cv2.imread('lines.png')
#灰度变换
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#转换为二值图像
edges = cv2.Canny(gray, 50, 150)
#显示原始图像
plt.subplot(121), plt.imshow(edges, 'gray'), plt.title(u'(a)原始图像')
plt.axis('off')
#霍夫变换检测直线
lines = cv2.HoughLines(edges, 1, np.pi / 180, 160)
#转换为二维
line = lines[:, 0, :]
#将检测的线在极坐标中绘制
for rho,theta in line[:]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
print(x0, y0)
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * (a))
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * (a))
print(x1, y1, x2, y2)
#绘制直线
cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 1)
#设置字体
matplotlib.rcParams['font.sans-serif']=['SimHei']
#显示处理图像
plt.subplot(122), plt.imshow(img, 'gray'), plt.title('(b)结果图像')
plt.axis('off')
plt.show()
输出结果如图3所示,第一幅图为原始图像,第二幅检测出的直线。
使用该方法检测大楼图像中的直线如图4所示,可以发现直线会存在越界的情况。
前面的标准霍夫变换会计算图像中的每一个点,计算量比较大,另外它得到的是整条线(r,θ),并不知道原图中直线的端点。接下来使用累计概率霍夫变换,它是一种改进的霍夫变换,调用HoughLinesP()函数实现。
下面的代码是调用HoughLinesP()函数检测图像中的直线,并将所有的直线绘制于原图像中。
# -*- coding: utf-8 -*-
# By: Eastmount
import cv2
import numpy as np
from matplotlib import pyplot as plt
import matplotlib
#读取图像
img = cv2.imread('judge.png')
#灰度转换
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#转换为二值图像
edges = cv2.Canny(gray, 50, 200)
#显示原始图像
plt.subplot(121), plt.imshow(edges, 'gray'), plt.title(u'(a)原始图像')
plt.axis('off')
#霍夫变换检测直线
minLineLength = 60
maxLineGap = 10
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 30, minLineLength, maxLineGap)
#绘制直线
lines1 = lines[:, 0, :]
for x1,y1,x2,y2 in lines1[:]:
cv2.line(img, (x1,y1), (x2,y2), (255,0,0), 2)
res = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#设置字体
matplotlib.rcParams['font.sans-serif']=['SimHei']
#显示处理图像
plt.subplot(122), plt.imshow(res), plt.title('(b)结果图像')
plt.axis('off')
plt.show()
输出结果如图5所示,图(a)为原始图像,图(b)检测出的直线,它有效地提取了线段的起点和终点。
霍夫圆变换的原理与霍夫线变换很类似,只是将线的(r,θ)二维坐标提升为三维坐标,包括圆心点(x_center,y_center,r)和半径r,其数学形式如公式(5)。
从而一个圆的确定需要三个参数,通过三层循环实现,接着寻找参数空间累加器的最大(或者大于某一阈值)的值。随着数据量的增大,导致圆的检测将比直线更耗时,所以一般使用霍夫梯度法减少计算量。在OpenCV中,提供了cv2.HoughCircles()函数检测圆,其原型如下所示:
下列代码是检测图像中的圆。
# -*- coding: utf-8 -*-
# By: Eastmount
import cv2
import numpy as np
from matplotlib import pyplot as plt
import matplotlib
#读取图像
img = cv2.imread('test.png')
#灰度转换
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#显示原始图像
plt.subplot(121), plt.imshow(gray, 'gray'), plt.title(u'(a)原始图像')
plt.axis('off')
#霍夫变换检测圆
circles1 = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, param2=30)
print(circles1)
#提取为二维
circles = circles1[0, :, :]
#四舍五入取整
circles = np.uint16(np.around(circles))
#绘制圆
for i in circles[:]:
cv2.circle(img, (i[0],i[1]), i[2], (255,0,0), 5) #画圆
cv2.circle(img, (i[0],i[1]), 2, (255,0,255), 10) #画圆心
#设置字体
matplotlib.rcParams['font.sans-serif']=['SimHei']
plt.subplot(122), plt.imshow(img), plt.title('(b)结果图像')
plt.axis('off')
plt.show()
输出结果如图6所示,图(a)为原始图像,图(b)检测出的圆形,它有效地提取了圆形的圆心和轮廓。
使用下面的函数能有效提取人类眼睛的轮廓,核心函数如下:
circles1 = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20,
param1=100, param2=30,
minRadius=160, maxRadius=300)
输出结果如图7所示,它提取了三条圆形接近于人体的眼睛。
图7中显示了三条曲线,通过不断优化最大半径和最小半径,比如将minRadius设置为160,maxRadius设置为200,将提取更为精准的人体眼睛,如图8所示。
本章主要讲解霍夫变换。霍夫变换主要用来辨别找出物件中的特征,包括提取图像中的直线和圆,调用cv2.HoughLines()、cv2.HoughLinesP()和cv2.HoughCircles()实现。希望对大家有所帮助,这也将为后续图像识别和目标检测提供帮助。
感谢在求学路上的同行者,不负遇见,勿忘初心。图像处理系列主要包括三部分,分别是:
转眼就过年了,2022年简单总结:很多遗憾,很多不足,勉强算是分秒必争,只争朝夕,但愧对家人,陪伴太少,论文、科研、分享和家庭都做得不好,这一年勉强给个65分吧。最最感恩的永远是女神,回家的感觉真好,平平淡淡,温温馨馨,虽然这辈子科研、事业和职称上没有太大的追求,和大佬们的差距如鸿沟,但能做自己喜欢的事,爱自己喜欢的人,每天前进一小步(人生勿比),一家人健康幸福,足矣。小珞珞是真的逗,陪伴的感觉真好,女神是真的好,爱你们喔,晚安娜继续加油!
参考文献: