目录
前言
目标
• 理解霍夫变换的概念
• 学习如何在一张图片中检测直线
• 学习函数:cv2.HoughLines(),cv2.HoughLinesP()
正文
OpenCV 的Hough变换
效果图
流程图
code
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
src = cv.imread("../../images/sudoku.jpg")
gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)
canny = cv.Canny(gray,30,70,apertureSize=3)
houghLines = cv.HoughLines(canny,1,np.pi/180,200)
for line in houghLines:
rho,theta = line[0]
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0+1000*(-b))
y1 = int(y0+1000*(a))
x2 = int(x0-1000*(-b))
y2 = int(y0-1000*(a))
cv.line(gray,(x1,y1),(x2,y2),(0,255,0),2)
cv.imshow("houghlines3.jpg", gray)
cv.imshow("src",src)
cv.waitKey(0)
OpenCV的HoughLinesP
效果图
code
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
src = cv.imread("../../images/sudoku.jpg")
cv.imshow("src",src)
gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)
canny = cv.Canny(gray,50,150,apertureSize=3)
minLineLength = 100##这是最小的线的长度
maxLineGap = 10 #这是最小的线与线之间的距离,当线与线之间的距离大于100的话,那么认为是同一条线
lines = cv.HoughLinesP(canny,1,np.pi/180,100,minLineLength,maxLineGap)
for line in lines:
x1, y1, x2, y2 = line[0]
cv.line(src, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv.imshow('houghLinesP',src)
cv.waitKey(0)
HoughCircle圆变换
效果图
code
import cv2 as cv
import numpy as np
src = cv.imread("../../images/OpenCV_Logo_with_text.png")
cv.imshow("src",src)
src = cv.medianBlur(src,5)
gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)
circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=0, maxRadius=0)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv.circle(gray,(i[0],i[1]),i[2],(0,255,0),2)
cv.circle(gray,(i[0],i[1]),2,(0,0,255),3)
cv.imshow("gray",gray)
cv.waitKey(0)
cv.destroyAllWindows()
函数
cv.HoughLines()
- 二值化图像,或是进行Canny算法图像处理的图像。
- 第二,第三代表的
- 第4个参数是阈值,只有高于这个阈值才被认为是直线。
cv.Canny()
void cvCanny( const CvArr* image, CvArr* edges, double threshold1,
double threshold2, int aperture_size=3 );
image
单通道输入图像.
edges
单通道存储边缘的输出图像
threshold1
第一个阈值
threshold2
第二个阈值
aperture_size
Sobel 算子内核大小 (见 cvSobel).
注释:threshold1和threshold2 当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割。
高阈值比较严格,求的边缘很少,认为高阈值的边缘都是有效。低阈值宽松,求的边缘很多(一般包括了高阈值求到的边缘),其中不少是无效的边缘(反正不想要的)。
先用高阈值求边缘。canny求得的边缘希望是连在一起的(通常是封闭的),但高阈值求的边缘一般断断续续。断开的地方如果低阈值求的边缘存在,就用低阈值的边缘接上去,目的让边缘尽量都连在一起。其它情况下低阈值的边缘是不用的。
第一步:灰度化
第二步:高斯滤波
第三步:计算梯度值和方向
第四步:非极大值抑制
第五步:双阈值的选取
第六步:边缘检测
cv.HoughCircles()
CvSeq* cvHoughCircles( CvArr* image, void* circle_storage, int method, double dp, double min_dist, double param1=100, double param2=100, int min_radius=0, int max_radius=0 );
参数:
image: 8位,单通道图像。如果使用彩色图像,请先转换为灰度。
method:定义检测图像中的圆的方法。目前,唯一实现的方法是cv2.HOUGH_GRADIENT对应于Yuen等。纸。
dp:该参数是累加器分辨率与图像分辨率的反比(详见Yuen等人)。实质上,dp获取越大,累加器数组越小。
minDist:检测到的圆的中心(x,y)坐标之间的最小距离。如果minDist太小,则可能(错误地)检测到与原始相邻的多个圆。如果minDist太大,那么一些圈子根本就不会被检测到。
param1: Yuen等人用于处理边缘检测的梯度值 方法。
param2:该cv2.HOUGH_GRADIENT方法的累加器阈值。阈值越小,检测到的圈子越多(包括虚假圈子)。阈值越大,可能会返回的圈数越多。
minRadius:半径的最小大小(以像素为单位)。
maxRadius:半径的最大大小(以像素为单位)。
“”"