【OpenCV + Python】Hough 直线变换

• 理解霍夫变换的概念
• 学习如何在一张图片中检测直线
• 学习函数:cv2.HoughLines(),cv2.HoughLinesP()

霍夫变换在检测各种形状的的技术中非常流行,如果你要检测的形状可以用数学表达式写出,你就可以是使用霍夫变换检测它。即使要检测的形状存在一点破坏或者扭曲也可以使用。我们下面就看看如何使用霍夫变换检测直线。一条直线可以用数学表达式y = mx + c 或者ρ = x cosθ + y sinθ 表示。是从原点到直线的垂直距离,θ是直线的垂线与横轴顺时针方向的夹角(如果你使用的坐标系不同方向也可能不同,我是按OpenCV 使用的坐标系描述的)。如下图所示:在这里插入图片描述
在霍夫变换中我们常用公式:
ρ = xcosθ + ysinθ
θ是直线与水平线所成的角度(0~180°),确定了它们,也就确定一条直线了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上图转自网址:https://www.cnblogs.com/hellcat/p/9896426.html#_label0
在这里插入图片描述

lines  =  cv2.HoughLines(edges,1,np.pi/180,200)

cv2.HoughLines(),它返回(ρ, θ)值的序列,ρ单位像素,θ单位弧度(lines: lines[i][0]为第i条直线的rho,lines[i][1]表示第i条直线的theta)。第一个参数,输入的图片是一个二进制图片,在使用hough变换之前,应用阈值或使用canny边缘检测。第二和第三个参数分别是ρ(rho:像素精度,一般设置为1;)和θ的精度(theta:角度精度,一般设置为CV_PI/180),第4个参数是阈值,指可以被认为是一个线条的最小计数值。由于计数值的多少取决于线上的点数(threshold:表示累计的像素达到多少才能形成直线),所以这代表了可以被识别为线的最小长度。

void HoughLinesP( InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double minLineLength = 0, double maxLineGap = 0 );

lines:lines[i]为Vec4i类型,若令L=lines[i],则Point(L[0],L[1])为第一个点坐标,Point(L[2],L[3])为第二个点坐标
rho、theta及threshold解释同上
minLineLength:最小的线段长度,感觉与threshold意思差不多
maxLineGap:两条线的间隔如果小于这个值为一条线

实例( cv2.HoughLines):

import cv2
import numpy as np
def line_detecte(img):
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,100,150,apertureSize=3)
lines = cv2.HoughLines(edges,1,np.pi/180,178)
print(lines)
result_img = img.copy()
for line in lines:
rho,theta = line[0] # 第一个元素是距离rho
#theta = line[1] # 第二个元素是角度theta
if (theta < (np.pi / 4.)) or (theta > (3. * np.pi / 4.0)): # 垂直直线
# 该直线与第一行的交点
pt1 = (int(rho / np.cos(theta)), 0)
# 该直线与最后一行的焦点
pt2 = (int((rho - result_img.shape[0] * np.sin(theta)) / np.cos(theta)), result_img.shape[0])
# 绘制一条白线
cv2.line(result_img, pt1, pt2, (255),3)
else: # 水平直线
# 该直线与第一列的交点
pt1 = (0, int(rho / np.sin(theta)))
# 该直线与最后一列的交点
pt2 = (result_img.shape[1], int((rho - result_img.shape[1] * np.cos(theta)) / np.sin(theta)))
# 绘制一条直线
cv2.line(result_img, pt1, pt2, (255), 3)
cv2.namedWindow(“img”, 0)
cv2.namedWindow(“edges”, 0)
cv2.namedWindow(“result_img”, 0)
cv2.resizeWindow(“img”, 400, 480)
cv2.resizeWindow(“edges”, 400, 480)
cv2.resizeWindow(“result_img”, 400, 480)
cv2.imshow(“img”, img)
cv2.imshow(“edges”, edges)
cv2.imshow(“result_img”, result_img)

img=cv2.imread(‘6.jpg’,1)
line_detecte(img)
cv2.waitKey()

在这里插入图片描述

实例( cv2.HoughLinesP):
给出的结果是线段,可用来测距等应用

import cv2
import numpy as np


def line_detecte_poss(img):
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray,100,150,apertureSize=3)
    lines = cv2.HoughLinesP(edges,1,np.pi/180,250,5)
    print(lines)
    result_img = img.copy()
    for line in lines:
        x1,y1,x2,y2 = line[0]  # 第一个元素是距离rho
        #theta = line[1]  # 第二个元素是角度theta
        cv2.line(result_img, (x1,y1), (x2,y2), (255), 3)
        cv2.namedWindow("img", 0)
        cv2.namedWindow("edges", 0)
        cv2.namedWindow("result_img", 0)
        cv2.resizeWindow("img", 400, 480)
        cv2.resizeWindow("edges", 400, 480)
        cv2.resizeWindow("result_img", 400, 480)
        cv2.imshow("img", img)
        cv2.imshow("edges", edges)
        cv2.imshow("result_img", result_img)


img=cv2.imread('6.jpg',1)
line_detecte_poss(img)
cv2.waitKey()

在这里插入图片描述
步骤:

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,100,150,apertureSize=3)

前两步之后进行检测直线。

当使用OpenCV-Python进行直线检测时,通常会使用Hough直线变换算法。Hough直线变换算法可以检测出图像中所有的直线,不过有时候需要筛选出需要的直线。 以下是使用OpenCV-Python进行直线检测的基本步骤: 1. 读取图像,将其转换为灰度图像。 ```python import cv2 img = cv2.imread('image.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ``` 2. 对图像进行边缘检测,例如使用Canny算子。 ```python edges = cv2.Canny(gray,50,150,apertureSize = 3) ``` 3. 进行Hough直线变换,检测出所有直线。 ```python lines = cv2.HoughLines(edges,1,np.pi/180,200) ``` 4. 可以根据需要筛选出需要的直线,并将其绘制在原图像上。 ```python for line in lines: rho,theta = line[0] if theta > np.pi/180*30 and theta < np.pi/180*150: 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)) cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2) ``` 在以上代码中,`lines`是通过Hough直线变换得到的所有直线。对于每一条直线,可以通过其极坐标表示方式中的角度`theta`来判断其是否为需要的直线。例如,可以筛选出与水平方向夹角在30度到150度之间的直线。 对于需要绘制的直线,可以通过其极坐标表示方式计算出其两个端点的坐标,然后使用`cv2.line()`函数在原图像上绘制出来。 以上是使用OpenCV-Python进行直线检测的基本步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胖子工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值