OpenCV学习笔记--以车道线检测入门

这篇具有很好参考价值的文章主要介绍了OpenCV学习笔记--以车道线检测入门。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本笔记gitee源代码:
https://gitee.com/hongtao-jiang/opencv_lanedetect.git

2023.8.5

1、OpenCV安装

conda管理虚拟环境与否看自己
pip install opencv

import cv2
print(cv2.__version__)

查看该库是否安装成功

2、图片的读入、保存

import cv2

img=cv2.imread('img.jpg',cv2.IMREAD_GRAYSCALE) #此为以灰度图格式读入,彩色读入则shape是3通道
print(type(img)) #<class 'numpy.ndarray'>
print(img.shape) #(368, 640)

cv2.imshow('image',img)#一闪而逝
#cv2.waitKey(0)#延时阻塞 0一直阻直到键入  单位毫秒
#k=cv2.waitKey(0)
#print(k)  #输出键入的ASCII值

cv2.imwrite('img_gray.jpg',img)#灰度图重组到文件里,图片要指定后缀,cv以此确定压缩格式

3、Canny算法边缘检测

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
求取每个像素点周边梯度,对比变化,以确定是否为边缘
对于B,C点,不处于边缘,求梯度无明显变化,但是处在边缘的A来说,梯度变化会很大,就可能是边缘点
以上是理想例子,沿着边缘法向求梯度求,实际上情况更复杂,例如:
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
1是左右边缘,3上下左右都有,360°计算运算成本高,Canny算法则是选取4个梯度方向(有正负所以说4个),
(1)应用高斯滤波器,平滑图像,滤除噪声。
边缘检测易受噪声影响,所以平滑图像,降低噪声点
(2)计算图像每个像素点的梯度大小和方向。
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
(3)非极大值抑制,消除边缘检测带来的不利影响
遍历图像中所有的像素点,判断当前像素点是否是周围像素点中具有相同方向梯度的最大值
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
保留黄色背景像素点,其他的归0

(4)应用双阈值检测确定真实和潜在的边缘
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python先设置高、低两个阈值(一般高阈值是低阈值的2~3倍),遍历整个灰度矩阵,若某点的梯度高于高阈值,则在结果中置1,若该点的梯度值低于低阈值,则在结果中置0,若该点的梯度值介于高低阈值之间,则需要进行如下判断:检查该点(将其视为中心点)的8邻域点,看是否存在梯度值高于高阈值的点,若存在,则说明该中心点和确定的边缘点相连接,故在结果中置1,否则置0。

(5)抑制孤立的弱边缘完成边缘检测

双阈值检测确定真是和潜在的边缘

原图:OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
边缘轮廓:
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
阈值:edge_img=cv2.Canny(img,50,100)
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
阈值:edge_img=cv2.Canny(img,70,120)
相比前面面的图,边缘线少了

import cv2

img=cv2.imread('img.jpg',cv2.IMREAD_GRAYSCALE)

edge_img=cv2.Canny(img,70,120)

cv2.imshow('edges',edge_img)
cv2.waitKey(0)
cv2.imwrite('edge_img.jpg',edge_img)

附一段可动态调节阈值的实时检测效果代码:

import cv2

cv2.namedWindow('edge_detection')
cv2.createTrackbar('minThreshold','edge_detection',50,1000,lambda x: x)
cv2.createTrackbar('maxThreshold','edge_detection',100,1000,lambda x: x)

img=cv2.imread('img.jpg',cv2.IMREAD_GRAYSCALE)
while True:
    minThreshold=cv2.getTrackbarPos('minThreshold', 'edge_detection')
    maxThreshold = cv2.getTrackbarPos('maxThreshold', 'edge_detection')
    edges = cv2.Canny(img, minThreshold, maxThreshold)
    cv2.imshow('edge_detection', edges)
    cv2.waitKey(10)

效果如下:
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
用以选择合适阈值

4、ROI mask

region of interest 感兴趣区域

· 数组切片
· 布尔运算(AND与运算)

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
原图以矩阵np.array形式存储在内存
zeros_like生成一个大小一致的全0矩阵
fillpoly填充掩码部分,留作与操作

cv2.fillPoly(mask,np.array([[[0,368],[240,210],[300,210],[640,368]]]),color=255)

这部分是将四个顶点包住的梯形填充,255为灰度值,纯白色

import cv2
import numpy as np

edge_img=cv2.imread('edge_img.jpg',cv2.IMREAD_GRAYSCALE)

mask=np.zeros_like(edge_img)
cv2.fillPoly(mask,np.array([[[0,368],[240,210],[300,210],[640,368]]]),color=255)
cv2.imshow('mask',mask)
cv2.waitKey(0)

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python

import cv2
import numpy as np

edge_img=cv2.imread('edge_img.jpg',cv2.IMREAD_GRAYSCALE)

mask=np.zeros_like(edge_img)
mask=cv2.fillPoly(mask,np.array([[[0,368],[240,210],[300,210],[640,368]]]),color=255)
#cv2.imshow('mask',mask)
#cv2.waitKey(0)
mask_edge_img=cv2.bitwise_and(edge_img,mask)
cv2.imshow('mask_edge_img.jpg',mask_edge_img)
#cv2.imwrite('mask_edge_img.jpg',mask_edge_img)
cv2.waitKey(0)

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
有点偏,多了杂点,往右挪一挪

np.array([[[0, 368], [300, 210], [340, 210], [640, 368]]]),
                    color=255)

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python

5、霍夫变换

找直线用
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
笛卡尔坐标系中的一条线,在霍夫空间中是个点;
霍夫空间中的一条线,代表笛卡尔系中所有经过某点的直线;

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
!!!
所以,经过这样一个对应变换的思路,霍夫空间中的一个点作为参数可以确定笛卡尔空间中多数点确定的一条直线
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
右图是极坐标系对应霍夫空间交线图

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python

如图,两条直线,右图两个两点,说明相交次数多,根据这两个点的坐标参数,确定直线

api:
返回值是一个列表,代表线段起点和终点的坐标值
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
opencv中霍夫变换要在灰度图中进行,读取图片必须注意格式
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python

在控制台逐行输入

import cv2

import numpy as np

img=cv2.imread('lines.jpg',cv2.IMREAD_GRAYSCALE)

lines = cv2.HoughLinesP(img, 1, np.pi / 180, 15, minLineLength=40,
                        maxLineGap=20)

lines
len(lines)

我们直观感受到的2条线,发现输出会有32条直线
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
其实是因为我们所处理的原图,直线有宽度,粗了
看参数,其中有很多线起点终点坐标相差不大,就是一条线段

为了先验获得两条,我们得进行分类,按斜率分为两组

import cv2
import numpy as np


def calculate_slope(line):
    """
    计算线段line的斜率
    :param line: np.array([[x_1, y_1, x_2, y_2]])
    :return:
    """
    x_1, y_1, x_2, y_2 = line[0]
    return (y_2 - y_1) / (x_2 - x_1)


edge_img = cv2.imread('mask_edge_img.jpg', cv2.IMREAD_GRAYSCALE)
# 获取所有线段
lines = cv2.HoughLinesP(edge_img, 1, np.pi / 180, 15, minLineLength=40,
                        maxLineGap=20)
# 按照斜率正负分成车道线
left_lines = [line for line in lines if calculate_slope(line) > 0]
right_lines = [line for line in lines if calculate_slope(line) < 0]

注意,opencv中,坐标原点在左上角

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python

6、离群值过滤

上节根据斜率分为左右两组线,但实际因为误差,噪点,会误识别为车道线,我们要进一步剔除一部分,我们知道,落在车道线上的线占大多数,与之斜率差别大的我们过滤掉

import cv2
import numpy as np

def calculate_slope(line):
    """
    计算线段line的斜率
    :param line: np.array([[x_1, y_1, x_2, y_2]])
    :return:
    """
    x_1, y_1, x_2, y_2 = line[0]
    return (y_2 - y_1) / (x_2 - x_1)

edge_img = cv2.imread('mask_edge_img.jpg', cv2.IMREAD_GRAYSCALE)
# 获取所有线段
lines = cv2.HoughLinesP(edge_img, 1, np.pi / 180, 15, minLineLength=40, maxLineGap=20)
# 按照斜率分成车道线
left_lines = [line for line in lines if calculate_slope(line) > 0]
right_lines = [line for line in lines if calculate_slope(line) < 0]

def reject_abnormal_lines(lines, threshold):
    """
    剔除斜率不一致的线段
    :param lines: 线段集合, [np.array([[x_1, y_1, x_2, y_2]]),np.array([[x_1, y_1, x_2, y_2]]),...,np.array([[x_1, y_1, x_2, y_2]])]
    """
    slopes = [calculate_slope(line) for line in lines]#建个斜率列表
    while len(lines) > 0:
        mean = np.mean(slopes)#计算斜率平均值
        diff = [abs(s - mean) for s in slopes]#计算每个斜率和平均值的差值
        idx = np.argmax(diff)# 获取array中数值最大的 找差值最大线段的索引
        if diff[idx] > threshold:#和阈值比一下,差得多不,超标就滚蛋
            slopes.pop(idx)#斜率列表中删掉
            lines.pop(idx)#从线段列表中删掉
        else:
            break
    return lines


print('before filter:')
print('left lines number=')
print(len(left_lines))
print('right lines number=')
print(len(right_lines))

reject_abnormal_lines(left_lines, threshold=0.2)
reject_abnormal_lines(right_lines, threshold=0.2)


print('after filter:')
print('left lines number=')
print(len(left_lines))
print('right lines number=')
print(len(right_lines))

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python

7、最小二乘拟合

将所有认为是左或右车道的线拟合为一条

np.ravel :将高维数组拉成一维数组
np.polyfit: 多项式拟合
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python

np.polyval:多项式求值,第一个参数是多项式系数,第二参数是任意X

def least_squares_fit(lines):
    """
    将lines中的线段拟合成一条线段
    :param lines: 线段集合, [np.array([[x_1, y_1, x_2, y_2]]),np.array([[x_1, y_1, x_2, y_2]]),...,np.array([[x_1, y_1, x_2, y_2]])]
    :return: 线段上的两点,np.array([[xmin, ymin], [xmax, ymax]])
    """
    # 1. 取出所有坐标点
    x_coords = np.ravel([[line[0][0], line[0][2]] for line in lines])
    y_coords = np.ravel([[line[0][1], line[0][3]] for line in lines])
    # 2. 进行直线拟合.得到多项式系数
    poly = np.polyfit(x_coords, y_coords, deg=1)
    # 3. 根据多项式系数,计算两个直线上的点,用于唯一确定这条直线
    point_min = (np.min(x_coords), np.polyval(poly, np.min(x_coords)))
    point_max = (np.max(x_coords), np.polyval(poly, np.max(x_coords)))
    return np.array([point_min, point_max], dtype=int)


print("left lane")
print(least_squares_fit(left_lines))
print("right lane")
print(least_squares_fit(right_lines))

在上节代码后加入这段处理
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
两点练成一条线

8、直线绘制

cv2.line
添加如下代码

left_line = least_squares_fit(left_lines)
right_line = least_squares_fit(right_lines)

img = cv2.imread('img.jpg', cv2.IMREAD_COLOR)
cv2.line(img, tuple(left_line[0]), tuple(left_line[1]), color=(0, 255, 255), thickness=5)
cv2.line(img, tuple(right_line[0]), tuple(right_line[1]), color=(0, 255, 255), thickness=5)

cv2.imshow('lane', img)
cv2.waitKey(0)

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
为什么左侧车道线肉眼可见的偏移大?
因为在Canny边缘检测阈值调整,和前面ROI mask处掩码区域没有设置好,如下图,左车道线处有车辆的边缘,我没有细心调节阈值,后面掩码区域也没有掩盖掉
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
将梯形块右移,得到新的图取参与绘图:
OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python
所以调整需要看情况

9、视频流读写

OpenCV学习笔记--以车道线检测入门,python,opencv,学习,笔记,计算机视觉,经验分享,python文章来源地址https://www.toymoban.com/news/detail-627080.html

capture = cv2.VideoCapture('video.mp4')
while True:
    ret, frame = capture.read()#ret视频流状况,是否关闭
    frame = show_lane(frame)
    cv2.imshow('frame', frame)
    cv2.waitKey(100)

到了这里,关于OpenCV学习笔记--以车道线检测入门的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深度学习毕设项目 深度学习+opencv+python实现车道线检测 - 自动驾驶

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月04日
    浏览(71)
  • 竞赛项目 车位识别车道线检测 - python opencv

    🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分 工作量:3分 创新点:4分 🧿 更多资料, 项目分享: https://gitee.com

    2024年02月13日
    浏览(43)
  • 竞赛保研 车位识别车道线检测 - python opencv

    🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分 工作量:3分 创新点:4分 🧿 更多资料, 项目分享: https://gitee.com

    2024年01月24日
    浏览(49)
  • python基于opencv的车道线检测左右转弯原理详解

    给定一组棋盘图像计算相机校准矩阵和畸变系数。 对原始图像应用失真校正。 使用颜色变换、渐变等来创建阈值二值图像。 应用透视变换来校正二进制图像(“鸟瞰图”)。 检测车道像素并拟合以找到车道边界。 确认检测到的线与现实和之前的线一致,即它们具有相似的

    2024年02月03日
    浏览(45)
  • 计算机竞赛 深度学习 python opencv 火焰检测识别

    🔥 优质竞赛项目系列,今天要分享的是 🚩 基于深度学习的火焰识别算法研究与实现 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:4分 工作量:4分 创新点:3分 🧿 更多资料, 项目分享: https://gitee.co

    2024年02月07日
    浏览(54)
  • 【计算机视觉—python 】 图像处理入门教程 —— 图像属性、像素编辑、创建与复制、裁剪与拼接【 openCV 学习笔记 005 to 010 and 255】

    OpenCV中读取图像文件后的数据结构符合Numpy的ndarray多维数组结构,因此 ndarray 数组的属性和操作方法可用于图像处理的一些操作。数据结构如下图所示: img.ndim:查看代表图像的维度。彩色图像的维数为3,灰度图像的维度为2。 img.shape:查看图像的形状,代表矩阵的行数(高

    2024年01月19日
    浏览(70)
  • 计算机竞赛 深度学习 python opencv 动物识别与检测

    🔥 优质竞赛项目系列,今天要分享的是 🚩 基于深度学习的动物识别算法研究与实现 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:4分 工作量:4分 创新点:3分 🧿 更多资料, 项目分享: https://gitee.co

    2024年02月07日
    浏览(64)
  • 计算机设计大赛 深度学习疲劳检测 驾驶行为检测 - python opencv cnn

    🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习加驾驶疲劳与行为检测 ** 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:4分 工作量:3分 创新点:5分 🧿 更多资料, 项目分享: https://gitee.com

    2024年03月14日
    浏览(103)
  • 深度学习卫星遥感图像检测与识别 -opencv python 目标检测 计算机竞赛

    🔥 优质竞赛项目系列,今天要分享的是 🚩 **深度学习卫星遥感图像检测与识别 ** 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分 工作量:3分 创新点:5分 🧿 更多资料, 项目分享: https://gitee.com/da

    2024年02月03日
    浏览(71)
  • 《OpenCV 计算机视觉编程攻略》学习笔记(一:图像编程入门)

    参考引用 OpenCV 计算机视觉编程攻略(第3版) 说明 本书结合 C++ 和 OpenCV 3.2 全面讲解计算机视觉编程 所有代码均在 Ubuntu 系统中用 g++ 编译执行 0. 安装 OpenCV 库 在Ubuntu上安装OpenCV及使用 OpenCV 库分为多个模块 ,常见模块如下 opencv_core 模块包含库的核心功能 opencv_imgproc 模块包

    2024年02月09日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包