Python opencv图像处理基础总结(六) 直线检测 圆检测 轮廓发现

简介: 我还有改变的可能性一想起这一点我就心潮澎湃

一、直线检测


使用霍夫直线变换做直线检测,前提条件:边缘检测已经完成


# 标准霍夫线变换cv2.HoughLines(image, rho, theta, threshold, lines=None, srn=None, stn=None, min_theta=None, max_theta=None)


  • image:经过边缘检测的输出图像,8位,单通道二进制源图像。
  • rho:距离步长
  • theta:角度步长
  • threshold:阈值,只有大于该值的点才有可能被当作极大值,即至少有多少条正弦曲线交于一点才被认为是直线。


# 统计概率霍夫线变换cv2.HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None)


  • 经过边缘检测的输出图像,8位,单通道二进制源图像。
  • rho:参数极径 r ,以像素值为单位的分辨率,这里一般使用 1 像素。
  • theta:参数极角theta, 以弧度为单位的分辨率,这里使用 1 度。
  • threshold:检测一条直线所需最少的曲线交点
  • minLineLength:线的最短长度,比这个线短的都会被忽略。
  • maxLineGap:两条线之间的最大间隔,如果小于此值,这两条线就会被看成一条线。


代码如下:


importcv2importnumpyasnp# 标准霍夫线变换defline_detection_demo(image):
# 灰度图像gray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 提取边缘edges=cv2.Canny(gray, 50, 150, apertureSize=3)
lines=cv2.HoughLines(edges, 1, np.pi/180, 160)
forlineinlines:
rho, theta=line[0]  # line[0]存储的是点到直线的极径和极角,其中极角是弧度表示的a=np.cos(theta)     # theta是弧度b=np.sin(theta)
x0=a*rhoy0=b*rhox1=int(x0+1000* (-b))  # 直线起点横坐标y1=int(y0+1000*a)     # 直线起点纵坐标x2=int(x0-1000* (-b))  # 直线终点横坐标y2=int(y0-1000*a)     # 直线终点纵坐标cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.imshow("image_lines", image)
# 统计概率霍夫线变换defline_detect_possible_demo(image):
gray=cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY)
edges=cv2.Canny(gray, 50, 150, apertureSize=3)
lines=cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=50, maxLineGap=10)
forlineinlines:
x1, y1, x2, y2=line[0]
cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.imshow("line_detect_possible", image)
if__name__=="__main__":
src=cv2.imread(r"./test/041.png")
cv2.imshow("image", src)
line_detection_demo(src)
line_detect_possible_demo(src)
cv2.waitKey(0)
cv2.destroyAllWindows()


运行效果如下:



二、圆检测


  • 霍夫圆变换的基本原理和霍夫线变换原理类似,只是点对应的二维极径、极角空间被三维的圆心和半径空间取代。在标准霍夫圆变换中,原图像的边缘图像的任意点对应的经过这个点的所有可能圆在三维空间用圆心和半径这三个参数来表示,其对应一条三维空间的曲线。对于多个边缘点,点越多,这些点对应的三维空间曲线交于一点的数量越多,那么他们经过的共同圆上的点就越多,类似的我们也就可以用同样的阈值的方法来判断一个圆是否被检测**到,这就是标准霍夫圆变换的原理, 但也正是在三维空间的计算量大大增加的原因,**标准霍夫圆变化很难被应用到实际中。
  • OpenCV实现的是一个比标准霍夫圆变换更为灵活的检测方法——霍夫梯度法,该方法运算量相对于标准霍夫圆变换大大减少。其检测原理是依据圆心一定是在圆上的每个点的模向量上,这些圆上点模向量的交点就是圆心,霍夫梯度法的第一步就是找到这些圆心,这样三维的累加平面就又转化为二维累加平面。第二步是根据所有候选中心的边缘非 0 像素对其的支持程度来确定半径。注:模向量即是圆上点的切线的垂直线。


cv2.HoughCircles(image, method, dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None)


  • image:输入图像,8位单通道灰度图像。
  • method:圆检测方法
  • dp:参数表示累加器与原始图像相比的分辨率的反比参数。例如,如果dp = 1,则累加器具有与输入图像相同的分辨率。如果dp=2,累加器分辨率是元素图像的一半,宽度和高度也缩减为原来的一半。
  • minDist:检测到的两个圆心之间的最小距离。如果参数太小,除了真实的一个圆圈之外,可能错误地检测到多个相邻的圆圈。如果太大,可能会遗漏一些圆圈。
  • circles:检测到的圆的输出向量,向量内第一个元素是圆的横坐标,第二个是纵坐标,第三个是半径大小。
  • param1:Canny边缘检测的高阈值,低阈值会被自动置为高阈值的一半。
  • param2:圆心检测的累加阈值,参数值越小,可以检测越多的假圆圈,但返回的是与较大累加器值对应的圆圈。
  • minRadius:检测到的圆的最小半径
  • maxRadius:检测到的圆的最大半径


代码如下:


importcv2ascvimportnumpyasnp# 霍夫圆检测defdetect_circles_demo(image):
# 霍夫圆检测对噪声敏感  边缘保留滤波EPF  消除噪声dst=cv.pyrMeanShiftFiltering(image, 10, 105)  # 均值偏移滤波cimage=cv.cvtColor(dst, cv.COLOR_RGB2GRAY)
# 输入图像 方法 走步长 最小距离 边缘提取的低值circles=cv.HoughCircles(cimage, cv.HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=0, maxRadius=0)
circles=np.uint16(np.around(circles))     # 把circles包含的圆心和半径的值变成整数foriincircles[0, :]:
cv.circle(image, (i[0], i[1]), i[2], (0, 0, 255), 2)  # 画圆cv.circle(image, (i[0], i[1]), 2, (255, 0, 0), 2)     # 画圆心cv.imshow("circles", image)
if__name__=="__main__":
src=cv.imread(r"./test/035.png")
cv.imshow('input_image', src)
detect_circles_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()


运行效果如下:


三、轮廓发现


"""    cv2.findContours(image, mode, method, contours, hierarchy, offset)        参数:            1 要寻找图像的轮廓 只能传入二值图像,不是灰度图像            2 轮廓的检索模式,有四种:                cv2.RETR_EXTERNAL  表示只检测外轮廓                cv2.RETR_LIST      检测的轮廓不建立等级关系                cv2.RETR_CCOMP     建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层                cv2.RETR_TREE      建立一个等级树结构的轮廓            3 轮廓的近似办法                cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1                cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息        返回值:            contours:一个列表,每一项都是一个轮廓,不会存储轮廓所有的点,只存储能描述轮廓的点            hierarchy:一个ndarray, 元素数量和轮廓数量一样,                 每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0] ~hierarchy[i][3],                分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,则该值为负数 """"""        # 函数cv2.drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset)        # 第一个参数是一张图片,可以是原图或者其他。        # 第二个参数是轮廓,也可以说是cv2.findContours()找出来的点集,一个列表。        # 第三个参数是对轮廓(第二个参数)的索引,当需要绘制独立轮廓时很有用,若要全部绘制可设为-1。        # 接下来的参数是轮廓的颜色和线宽"""


代码如下:


# -*- coding: UTF-8 -*-"""@公众号      : AI庭云君@Author     : 叶庭云@CSDN       : https://yetingyun.blog.csdn.net/"""importcv2defcontours_demo(image):
dst=cv2.GaussianBlur(image, (3, 3), 0)
gray=cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
ret, thresh=cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
# 得到修改后的图像,轮廓点集  各层轮廓的索引contours, hierarchy=cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
fori, contourinenumerate(contours):
# 绘制轮廓  第几个  颜色  线宽cv2.drawContours(image, contours, i, (0, 0, 255), -1)
print(i)
cv2.imshow("detect contours", image)
if__name__=="__main__":
img=cv2.imread(r"./test/042.png")
cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)
cv2.imshow("input image", img)
contours_demo(img)
cv2.waitKey(0)
cv2.destroyAllWindows()


运行效果如下:


绘制轮廓时,线宽设置为-1,实现填充,效果如下:



通过Canny算法获取二值图像,再进行轮廓发现


# -*- coding: UTF-8 -*-"""@公众号      : AI庭云君@Author     : 叶庭云@CSDN       : https://yetingyun.blog.csdn.net/"""importcv2defedge_demo(image):
# 高斯模糊  降低噪声blurred=cv2.GaussianBlur(image, (3, 3), 0)
# 转为灰度图像gray=cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
# 计算x y 方向梯度grad_x=cv2.Sobel(gray, cv2.CV_16SC1, 1, 0)
grad_y=cv2.Sobel(gray, cv2.CV_16SC1, 0, 1)
edge_output=cv2.Canny(grad_x, grad_y,  50, 100)
returnedge_outputdefcontours_demo(image):
binary=edge_demo(image)
# 得到修改后的图像,轮廓点集  各层轮廓的索引contours, hierarchy=cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
fori, contourinenumerate(contours):
# 绘制轮廓  第几个  颜色  线宽cv2.drawContours(image, contours, i, (0, 0, 255), 2)
print(i)
cv2.imshow("detect contours", image)
if__name__=="__main__":
img=cv2.imread(r"./test/036.png")
cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)
cv2.imshow("input image", img)
contours_demo(img)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行效果如下:

目录
相关文章
|
2月前
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
104 7
基于qt的opencv实时图像处理框架FastCvLearn实战
|
1月前
|
计算机视觉
Opencv学习笔记(八):如何通过cv2读取视频和摄像头来进行人脸检测(jetson nano)
如何使用OpenCV库通过cv2模块读取视频和摄像头进行人脸检测,并提供了相应的代码示例。
82 1
|
7天前
|
计算机视觉 开发者 Python
利用Python进行简单的图像处理
【10月更文挑战第36天】本文将引导读者理解如何使用Python编程语言和其强大的库,如PIL和OpenCV,进行图像处理。我们将从基本的图像操作开始,然后逐步深入到更复杂的技术,如滤波器和边缘检测。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供新的视角和技能,让你能够更好地理解和操作图像数据。
|
1月前
|
机器学习/深度学习 计算机视觉
目标检测笔记(六):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
本文介绍了如何使用OpenCV进行特定区域的目标检测,包括人脸检测实例,展示了两种实现方法和相应的代码。
62 1
目标检测笔记(六):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
|
1月前
|
计算机视觉 Python
python利用pyqt5和opencv打开电脑摄像头并进行拍照
本项目使用Python的PyQt5和OpenCV库实现了一个简单的摄像头应用。用户可以通过界面按钮打开或关闭摄像头,并实时预览视频流。点击“拍照”按钮可以捕捉当前画面并保存为图片文件。该应用适用于简单的图像采集和处理任务。
100 0
python利用pyqt5和opencv打开电脑摄像头并进行拍照
|
1月前
|
机器学习/深度学习 算法 计算机视觉
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
68 2
|
2月前
|
机器学习/深度学习 计算机视觉 Python
opencv环境搭建-python
本文介绍了如何在Python环境中安装OpenCV库及其相关扩展库,包括numpy和matplotlib,并提供了基础的图像读取和显示代码示例,同时强调了使用Python虚拟环境的重要性和基本操作。
|
1月前
|
算法 计算机视觉 Python
圆形检测算法-基于颜色和形状(opencv)
该代码实现了一个圆检测算法,用于识别视频中的红色、白色和蓝色圆形。通过将图像从RGB转换为HSV颜色空间,并设置对应颜色的阈值范围,提取出目标颜色的区域。接着对这些区域进行轮廓提取和面积筛选,使用霍夫圆变换检测圆形,并在原图上绘制检测结果。
64 0
|
1月前
|
算法 数据可视化 计算机视觉
Python中医学图像处理常用的库
在Python中,医学图像处理常用的库包括:ITK(及其简化版SimpleITK)、3D Slicer、Pydicom、Nibabel、MedPy、OpenCV、Pillow和Scikit-Image。这些库分别擅长图像分割、配准、处理DICOM和NIfTI格式文件、图像增强及基础图像处理等任务。选择合适的库需根据具体需求和项目要求。
46 0
|
1月前
|
数据挖掘 计算机视觉 Python
基于Python的简单图像处理技术
【10月更文挑战第4天】在数字时代,图像处理已成为不可或缺的技能。本文通过Python语言,介绍了图像处理的基本方法,包括图像读取、显示、编辑和保存。我们将一起探索如何使用PIL库进行图像操作,并通过实际代码示例加深理解。无论你是编程新手还是图像处理爱好者,这篇文章都将为你打开一扇新窗,让你看到编程与创意结合的无限可能。