图像直线检测

图像直线检测,顾名思义,就是检测图像中的直线或者直线段。

OpenCV中的HoughLines和HoughLinesP函数可以完成直线检测

(1)HoughLines函数:使用的是标准的Hough变换

函数原型:HoughLines(image, lines,rho, theta, threshold, srn=0, stn=0, min_theta = 0,max_theta = CV_PI )

参数说明:

image:输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。

lines:经过调用HoughLines函数后储存了霍夫线变换检测到线条的输出矢量。每一条线由具有两个元素的矢量表示,其中,是离坐标原点((0,0)(也就是图像的左上角)的距离。 是弧度线条旋转角度(0~垂直线,π/2~水平线)。

rho:以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。PS:Latex中/rho就表示 。

theta:以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度。

threshold:累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。

srn:默认值0。对于多尺度的霍夫变换,这是第三个参数进步尺寸rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho,而精确的累加器进步尺寸为rho/srn。

stn:默认值0,对于多尺度霍夫变换,srn表示第四个参数进步尺寸的单位角度theta的除数距离。且如果srn和stn同时为0,就表示使用经典的霍夫变换。否则,这两个参数应该都为正数。

min_theta:对于标准和多尺度Hough变换,检查线条的最小角度。必须介于0和max_theta之间。

max_theta:对于标准和多尺度Hough变换,检查线条的最大角度。必须介于min_theta和CV_PI之间.

 

(2)HoughLinesP函数:使用概率Hough变换,即只通过分析点的子集并估计这些点都属于一条直线的概率,这在计算速度上更快。

函数原型:HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None)

参数说明:

image:必须是二值图像,推荐使用canny边缘检测的结果图像;

rho:线段以像素为单位的距离精度,double类型的,推荐用1.0;

theta:线段以弧度为单位的角度精度,推荐用numpy.pi/180;

threshold:累加平面的阈值参数,int类型,超过设定阈值才被检测出线段,值越大,基本上意味着检出的线段越长,检出的线段个数越少。根据情况推荐先用100试试;

lines:这个参数的意义未知,发现不同的lines对结果没影响,但是不要忽略了它的存在;

minLineLength:线段以像素为单位的最小长度,根据应用场景设置;

maxLineGap:同一方向上两条线段判定为一条线段的最大允许间隔(断裂),超过了设定值,则把两条线段当成一条线段,值越大,允许线段上的断裂越大,越有可能检出潜在的直线段。
 

 

代码奉上:

#直线检测
#霍夫直线变换介绍
    #霍夫直线变换用来做直线检测
    #前提条件-边缘检测已经完成
    #平面空间到极坐标空间转换
#相关api代码演示

import cv2
import numpy as np

def line_detection(image):#给出的是直线  HoughLines
    gray= cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)   #转为灰度图
    canny=cv2.Canny(gray, 50, 150, apertureSize=3)  #边缘进行canny检测
    lines=cv2.HoughLines(canny, 1, np.pi/180,200)   #霍夫直线变换
    for line in lines:  #遍历获取到的霍夫直线
        print(type(lines))
        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)
        cv2.line(image,(x1,y1),(x2,y2),(0,0,255),1)  #在图像上画线
    cv2.imshow("image-lines",image)

def line_detect_possible_demo(image):#一般常用这一种,给出的是线段
    gray= cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)   #转灰度图
    canny=cv2.Canny(gray, 50, 150, apertureSize=3)  #canny边缘检测
    lines=cv2.HoughLinesP(canny, 1, np.pi/180, 100, minLineLength=50, maxLineGap=10)   #霍夫直线转换
    for line in lines:  #遍历
        print(type(line))
        x1,y1,x2,y2=line[0]
        cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 1)    #在图像上画线
    cv2.imshow("image-lines-detect", image)


print("-------hello world--------")
src=cv2.imread("line.png")
cv2.imshow("source_image",src)
line_detection(src)
line_detect_possible_demo(src)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

原图:

Python怎么显示Line图显示不出来 linewidth python_直线检测

HoughLines转换的图

Python怎么显示Line图显示不出来 linewidth python_边缘检测_02

 

HoughLinesP转换的图

Python怎么显示Line图显示不出来 linewidth python_opencv_03