天天看点

OpenCV 直线和圆检测直线检测圆检测

OpenCV3计算机视觉Python语言实现- 直线和圆检测

  • 直线检测
    • 代码
    • 运行结果
    • 使用到的函数分析
      • 1.概率霍夫变换-cv2.HoughLinesP
  • 圆检测
    • 代码
    • 运行结果
    • 使用到的函数分析
      • 1.霍夫圆变换-cv2.HoughCircles

本文根据《OpenCV3计算机视觉Python语言实现第二版》,进行代码编写,感谢本书作者的辛勤付出!

直线检测

代码

import cv2
import numpy as np
#直线检测
img = cv2.imread("../image/test2.jpg")       #读取照片
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #图像二值画
edges = cv2.Canny(gray,50,120)  #获取图像边缘
minLineLength =20
maxLineGap =5
 # 概率霍夫变换 Probabilistic_Hough_Transform
lines =cv2.HoughLinesP(edges,1,np.pi/180,100,minLineLength,maxLineGap)
for line in lines: #遍历所有直线
    for x1,y1,x2,y2 in line: #其中一条直线
        cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)  #画出直线
        print(lines)
cv2.imshow("edges",edges)
cv2.imshow("lines",img)
cv2.waitKey()
cv2.destroyWindow()
           

运行结果

OpenCV 直线和圆检测直线检测圆检测

使用到的函数分析

1.概率霍夫变换-cv2.HoughLinesP

# 概率霍夫变换 Probabilistic_Hough_Transform
lines =cv2.HoughLinesP(edges,1,np.pi/180,100,minLineLength,maxLineGap) 
           

输入参数:

  • 1.edges :需要处理的图像(必须是二值图像,推荐使用canny边缘检测的结果图像;)
  • 2.rho:线段以像素为单位的距离精度,double类型的,推荐用1.0;
  • 3.线段的几何表示 一般取1和np.pi/180(线段以弧度为单位的角度精度,推荐用numpy.pi/180;)
  • 4.阈值:低于该阈值的直线会被忽略。霍夫变换可以理解为投票箱和投票数之间的关系,每个投票箱代表一条直线,投票数达到阈值会被保留,其余会被删除。(累加平面的阈值参数,int类型,超过设定阈值才被检测出线段,值越大,基本上意味着检出的线段越长,检出的线段个数越少。根据情况推荐先用100试试;)

    -5. minLineLength - 线的最短长度。比这个短的线都会被忽略。(线段以像素为单位的最小长度,根据应用场景设置;)

    -6. maxLineGap - 两条线段之间的最大间隔,如果小于此值,这两条直线就被看成是一条直线。(同一方向上两条线段判定为一条线段的最大允许间隔(断裂),超过了设定值,则把两条线段当成一条线段,值越大,允许线段上的断裂越大,越有可能检出潜在的直线段。)

返回值:

  • 返回值就是直线的起点和终点

说明:

仅仅是一条直线都需要两个参数,这需要大量的计算。 Probabilistic_Hough_Transform 是对霍夫变换的一种优化。它不会对每一个点都进行计算,而是从一幅图像中随机选取一个点集进行计算,对于直线检测来说这已经足够了。但是使用这种变换我们必须要降低阈值

圆检测

代码

import cv2
import numpy as np
planets = cv2.imread("../image/test3.jpg")
gray_img = cv2.cvtColor(planets,cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(gray_img,5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,120,param1=100,param2=30,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles)) #近似函数
for i in circles[0,:]:
    #画外部圆
    cv2.circle(planets,(i[0],i[1]),i[2],(0,255,0),2)
    #画圆的中心
    cv2.circle(planets,(i[0],i[1]),2,(0,0,255),3)

# cv2.imwrite("planets_circles.jpg",planets)
cv2.imshow("HoughCirlces",planets)
cv2.waitKey()
cv2.destroyWindow()
           

运行结果

OpenCV 直线和圆检测直线检测圆检测

使用到的函数分析

1.霍夫圆变换-cv2.HoughCircles

circles=cv2.HoughCircles
(img,cv2.HOUGH_GRADIENT,1,120,param1=100,param2=30,minRadius=0,maxRadius=0)
#示例
cv2.HoughCircles(image, method, dp, minDist, circles, param1, param2, minRadius, maxRadius)
           

输入参数:

  • image:为输入图像,需要灰度图
  • method:为检测方法 目前,唯一实现的方法是 CV_HOUGH_GRADIENT,基本上是 21HT
  • dp:为检测内侧圆心的累加器图像的分辨率于输入图像之比的倒数,如dp=1,累加器和输入图像具有相同的分辨率,如果dp=2,累计器便有输入图像一半那么大的宽度和高度
  • minDist:表示两个圆之间圆心的最小距离
  • param1:有默认值100,它是method设置的检测方法的对应的参数,对当前唯一的方法霍夫梯度法cv2.HOUGH_GRADIENT,它表示传递给canny边缘检测算子的高阈值,而低阈值为高阈值的一半
  • param2:有默认值100,它是method设置的检测方法的对应的参数,对当前唯一的方法霍夫梯度法cv2.HOUGH_GRADIENT,它表示在检测阶段圆心的累加器阈值,它越小,就越可以检测到更多根本不存在的圆,而它越大的话,能通过检测的圆就更加接近完美的圆形了
  • minRadius:有默认值0,圆半径的最小值
  • maxRadius:有默认值0,圆半径的最大值

返回值:

  • 找到的圆的输出向量。每个向量被编码为3元素的浮点向量 (x,y,半径)。

这里输出结果只有一组代表只有一个圆