Python OpenCV Hough直线检测算法的原理实现

目录
  • 直线检测原理
  • OpenCV实现

直线检测原理

核心要点:图像坐标空间、参数空间、极坐标参数空间 -> (极坐标)参数空间表决

给定一个点,我们一般会写成y=ax+b的形式,这是坐标空间的写法;我们也可以写成b=-xa+y的形式,这是参数空间的写法。也就是说,给定一个点,那么经过该点的直线的参数必然满足b=-xa+y这一条件,也就是必然在参数空间中b=-xa+y这条直线上。如果给定两个点,那么这两点确定的唯一的直线的参数,就是参数空间中两条参数直线的交点。

由于上述写法不适合处理水平或垂直的直线,我们可以使用极坐标的形式描述直线,即ρ=xcosθ+ysinθ,其中ρ是从原点到直线的垂直距离,θ是由这条垂直线和水平轴形成的角度(以逆时针方向测量),

如下图所示:

因此,任何垂直线θ=0,水平线θ=90°。那么极坐标参数空间中的曲线交点就是由两个点确定的一条直线,如下图所示。

现在让我们看看Hough变换是如何处理直线的。任何一条线都可以用这两个参数来表示(ρ,θ)。

  • 首先创建一个二维数组,即累加器,用来保存两个参数的值,然后最初将其设置为全0。让行表示ρ,列表示θ。数组的尺寸取决于所需的精度。假设希望角度的精度为1度,则需要180列,枚举0°-179°的所有情况。对于ρ,可能的最大距离是图像的对角线长度。因此,以一个像素的精度计算,行数可以是图像的对角线长度。
  • 枚举所有的点,对于每一个点,将所有经过这一点的直线对应的参数(ρ,θ)在参数空间中找到对应位置,令该位置的累加器加1,即投票。这一过程如下图所示。

枚举完成所有点之后,累加器中值最大的(若干个)参数组合(ρ,θ)就是经过点最多的(若干条)直线,如下图所示,两条直线对应累加器中最亮的两个点。

总的来说,对于多个点,我们可以用(离散)参数空间表决的方法,记录每个点对应的允许的参数组合,求得那些被允许次数最多的参数组合,就是最多点经过的直线。

在图像矫正任务中,我们经过Canny算子检测出了若干边缘点,这些点主要集中在四个边界上,因此我们只需要使用Hough直线检测,求出四条直线,就能确定四个边界。

OpenCV实现

cv.HoughLines()封装了上述步骤,该函数原型为:

cv.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]]) -> lines

参数:

  • lines:数组,每一个元素都是一条直线对应的(ρ, θ),ρ以像素为单位,θ以弧度为单位。
  • image:输入图像,需要是二值图像,所以在应用hough变换之前应用阈值或canny边缘检测。
  • rho:ρ的精度。
  • theta:θ的精度。
  • threshold:阈值,得票数高于该值的线才被认为是线,由于投票数取决于线上的点数,所以它代表了应该被检测到的线的最小点数。

下面是具体代码:

def hough_detect(image_path):
    # 读取图像并转换为灰度图像
    image = cv2.imread(image_path)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 使用Canny算子检测边缘
    edges = canny_detect(image_path, False)
    # 使用Hough检测直线
    lines = cv2.HoughLines(edges, 1, np.pi/180, 200)
    # 绘制直线
    for line in 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), 2)
    cv2.imshow('line,jpg', image)
    cv2.waitKey()
hough_detect('images/2.jpeg')

效果:

后面需要调整一下超参数。

到此这篇关于Python OpenCV Hough直线检测算法的原理实现的文章就介绍到这了,更多相关Python OpenCV Hough 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python下opencv使用hough变换检测直线与圆

    在数字图像中,往往存在着一些特殊形状的几何图形,像检测马路边一条直线,检测人眼的圆形等等,有时我们需要把这些特定图形检测出来,hough变换就是这样一种检测的工具. Hough变换的原理是将特定图形上的点变换到一组参数空间上,根据参数空间点的累计结果找到一个极大值对应的解,那么这个解就对应着要寻找的几何形状的参数(比如说直线,那么就会得到直线的斜率k与常熟b,圆就会得到圆心与半径等等). 关于hough变换,核心以及难点就是关于就是有原始空间到参数空间的变换上.以直线检测为例,假设有一条直线L,

  • python opencv检测直线 cv2.HoughLinesP的实现

    cv2.HoughLines()函数是在二值图像中查找直线,cv2.HoughLinesP()函数可以查找直线段. cv2.HoughLinesP()函数原型: HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None) image: 必须是二值图像,推荐使用canny边缘检测的结果图像: rho: 线段以像素为单位的距离精度,double类型的,推荐用1.0 theta:

  • Python OpenCV Hough直线检测算法的原理实现

    目录 直线检测原理 OpenCV实现 直线检测原理 核心要点:图像坐标空间.参数空间.极坐标参数空间 -> (极坐标)参数空间表决 给定一个点,我们一般会写成y=ax+b的形式,这是坐标空间的写法:我们也可以写成b=-xa+y的形式,这是参数空间的写法.也就是说,给定一个点,那么经过该点的直线的参数必然满足b=-xa+y这一条件,也就是必然在参数空间中b=-xa+y这条直线上.如果给定两个点,那么这两点确定的唯一的直线的参数,就是参数空间中两条参数直线的交点. 由于上述写法不适合处理水平或垂直的

  • python opencv实现直线检测并测出倾斜角度(附源码+注释)

    由于学习需要,我想要检测出图片中的直线,并且得到这些直线的角度.于是我在网上搜了好多直线检测的代码,但是没有搜到附有计算直线倾斜角度的代码,所以我花了一点时间,自己写了一份直线检测并测出倾斜角度的代码,希望能够帮助到大家! 注:这份代码只能够检测简单结构图片的直线,复杂结构的图片还需要设置合理的参数 下面展示 源码. import cv2 import numpy as np def line_detect(image): # 将图片转换为HSV hsv = cv2.cvtColor(image

  • 详解在Python中使用OpenCV进行直线检测

    目录 1.引言 2.霍夫变换 3.举个栗子 3.1读入图像进行灰度化 3.2执行边缘检测 3.3进行霍夫变换 补充 1. 引言 在图像处理中,直线检测是一种常见的算法,它通常获取n个边缘点的集合,并找到通过这些边缘点的直线.其中用于直线检测,最为流行的检测器是基于霍夫变换的直线检测技术. 2. 霍夫变换 霍夫变换是图像处理中的一种特征提取方法,可以识别图像中的几何形状.它将在参数空间内进行投票来决定其物体形状,通过检测累计结果找到一极大值所对应的解,利用此解即可得到一个符合特定形状的参数. 在使

  • python+opencv实现霍夫变换检测直线

    本文实例为大家分享了python+opencv实现霍夫变换检测直线的具体代码,供大家参考,具体内容如下 python+opencv实现高斯平滑滤波 python+opencv实现阈值分割 功能: 创建一个滑动条来控制检测直线的长度阈值,即大于该阈值的检测出来,小于该阈值的忽略 注意:这里用的函数是HoughLinesP而不是HoughLines,因为HoughLinesP直接给出了直线的断点,在画出线段的时候可以偷懒 代码: # -*- coding: utf-8 -*- import cv2

  • Python OpenCV实现图形检测示例详解

    目录 1. 轮廓识别与描绘 1.1 cv2.findComtours()方法 1.2 cv2.drawContours() 方法 1.3 代码示例 2. 轮廓拟合 2.1 矩形包围框拟合 - cv2.boundingRect() 2.2圆形包围框拟合 - cv2.minEnclosingCircle() 3. 凸包 绘制 4. Canny边缘检测 - cv2.Canny() 4.1 cv2.Canny() 用法简介 4.2 代码示例 5. 霍夫变换 5.1 概述 5.2 cv2.HoughLin

  • Python+OpenCV实现分水岭分割算法的示例代码

    目录 前言 1.使用分水岭算法进行分割 2.Watershed与random walker分割对比 前言 分水岭算法是用于分割的经典算法,在提取图像中粘连或重叠的对象时特别有用,例如下图中的硬币. 使用传统的图像处理方法,如阈值和轮廓检测,我们将无法从图像中提取每一个硬币,但通过利用分水岭算法,我们能够检测和提取每一个硬币. 在使用分水岭算法时,我们必须从用户定义的标记开始.这些标记可以通过点击手动定义,或者我们可以使用阈值和/或形态学操作等方法自动或启发式定义它们. 基于这些标记,分水岭算法将

  • Python OpenCV调用摄像头检测人脸并截图

    本文实例为大家分享了Python OpenCV调用摄像头检测人脸并截图的具体代码,供大家参考,具体内容如下 注意:需要在python中安装OpenCV库,同时需要下载OpenCV人脸识别模型haarcascade_frontalface_alt.xml,模型可在OpenCV-PCA-KNN-SVM_face_recognition中下载. 使用OpenCV调用摄像头检测人脸并连续截图100张 #-*- coding: utf-8 -*- # import 进openCV的库 import cv2

  • python opencv角点检测连线功能的实现代码

    原始图 角点检测 points = cv2.goodFeaturesToTrack(gray, 100, 0.01, 10) points = np.int0(points).reshape(-1,2) for point in points: x, y = point.ravel() cv2.circle(img, (x, y), 10, (0, 255, 0), -1) 连线 cv2.line(img, (0, y1), (1000, y1), (0, 255, 0), thickness=

  • OpenCV实现直线检测并消除

    本文实例为大家分享了OpenCV实现直线检测并消除的具体代码,供大家参考,具体内容如下 很简单,代码如下 #include<iostream> #include<opencv.hpp> using namespace cv; using namespace std; int main() { Mat img, dst, img_gary, img_bin, temp, r_line, c_line, kernel; char INPUT[] = "input";

  • OpenCV实现直线检测

    本文实例为大家分享了OpenCV实现直线检测的具体代码,供大家参考,具体内容如下 1 介绍 本文主要介绍OpenCV自带的直线检测函数HoughLines()的用法,这个函数的第一个参数是一个二值化图像,所以在进行霍夫变换之前要首先进行二值化,或者进行Canny 边缘检测.第二和第三个值分别代表β 和 θ 的精确度.第四个参数是阈值,只有累加其中的值高于阈值时才被认为是一条直线,也可以把它看成能检测到的直线的最短长度(以像素点为单位).返回值就是(β; θ).β 的单位是像素,θ的单位是弧度.

随机推荐