[openCV]基于赛道追踪的智能车巡线方案V1

import cv2 as cv
import os
import numpy as np

import time


# 遍历文件夹函数
def getFileList(dir, Filelist, ext=None):
    """
    获取文件夹及其子文件夹中文件列表
    输入 dir:文件夹根目录
    输入 ext: 扩展名
    返回: 文件路径列表
    """
    newDir = dir
    if os.path.isfile(dir):
        if ext is None:
            Filelist.append(dir)
        else:
            if ext in dir[-3:]:
                Filelist.append(dir)

    elif os.path.isdir(dir):
        for s in os.listdir(dir):
            newDir = os.path.join(dir, s)
            getFileList(newDir, Filelist, ext)

    return Filelist


def mid(follow, mask, img):
    height = follow.shape[0]  # 输入图像高度
    width = follow.shape[1]  # 输入图像宽度

    half = int(width / 2)  # 输入图像中线

    # 从下往上扫描赛道,最下端取图片中线为分割线
    for y in range(height - 1, -1, -1):

        if y == height - 1:  # 刚开始从底部扫描时
            left = 0
            right = width - 1
            left_scale = 0.5  # 初始赛道追踪范围
            right_scale = 0.5  # 初始赛道追踪范围
        elif left == 0 and right == width - 1:  # 下层没有扫描到赛道时
            left_scale = 0.25  # 赛道追踪范围
            right_scale = 0.25  # 赛道追踪范围
        elif left == 0:  # 仅左下层没有扫描到赛道时
            left_scale = 0.25  # 赛道追踪范围
            right_scale = 0.2  # 赛道追踪范围
        elif right == width - 1:  # 仅右下层没有扫描到赛道时
            left_scale = 0.2  # 赛道追踪范围
            right_scale = 0.25  # 赛道追踪范围
        else:
            left_scale = 0.2  # 赛道追踪范围
            right_scale = 0.2  # 赛道追踪范围

        # 根据下层左线位置和scale,设置左线扫描范围
        left_range = mask[y][max(0, left - int(left_scale * width)):min(left + int(left_scale * width), width - 1)]
        # 根据下层右线位置和scale,设置右线扫描范围
        right_range = mask[y][max(0, right - int(right_scale * width)):min(right + int(right_scale * width), width - 1)]

        # 左侧规定范围内未找到赛道
        if (left_range == np.zeros_like(left_range)).all():
            left = left  # 取图片最左端为左线
        else:
            left = int(
                (max(0, left - int(left_scale * width)) + np.average(
                    np.where(left_range == 255))) * 0.4 + left * 0.6)  # 取左侧规定范围内检测到赛道像素平均位置为左线

        # 右侧规定范围内未找到赛道
        if (right_range == np.zeros_like(right_range)).all():
            right = right  # 取图片最右端为右线
        else:
            right = int(
                (max(0, right - int(right_scale * width)) + np.average(
                    np.where(right_range == 255))) * 0.4 + right * 0.6)  # 取右侧规定范围内检测到赛道像素平均位置为右线

        mid = int((left + right) / 2)  # 计算中点

        # follow[y, mid] = 255  # 画出拟合中线,实际使用时为提高性能可省略
        # img[y, max(0, left - int(left_scale * width)):min(left + int(left_scale * width), width - 1)] = [0, 0, 255]
        # img[y, max(0, right - int(right_scale * width)):min(right + int(right_scale * width), width - 1)] = [0, 0, 255]

        if y == int((360 / 480) * follow.shape[0]):  # 设置指定提取中点的纵轴位置
            mid_output = mid
    cv.circle(follow, (mid_output, int((360 / 480) * follow.shape[0])), 5, 255, -1)  # opencv为(x,y),画出指定提取中点

    error = (half - mid_output) / width * 640  # 计算图片中点与指定提取中点的误差

    return follow, error, img  # error为正数左转,为负数右转


n = -1
# 存放图片的文件夹路径
path = "./d1"
imglist = getFileList(path, [])
for imgpath in imglist:
    n += 1
    if n < 0:
        continue

    start_time = time.time()

    img = cv.imread(imgpath)

    img = cv.resize(img, (640, 480))

    # HSV阈值分割
    img_hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
    mask = cv.inRange(img_hsv, np.array([43, 60, 90]), np.array([62, 255, 255]))

    follow = mask.copy()

    follow, error, img = mid(follow, mask, img)

    print(n, f"error:{error}")
    end_time = time.time()
    print("time:", end_time - start_time, "s")
    cv.imshow("img", img)
    cv.imshow("mask", mask)
    cv.imshow("follow", follow)
    cv.waitKey(0)

cv.destroyAllWindows()

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
通过引用,我们知道在智能车竞赛中,使用了两套方案来完成巡线任务:一套是基于传统opencv巡线,一套是用paddle搭建神经网络框架。然而,由于时间有限,只能利用假期的闲余时间来继续完善未完成的opencv巡线方案。 引用中提到了利用opencv完成视觉巡线的具体步骤。在白色地面上,通过摄像头检测黑色的车道线,来完成巡线任务。为了保持小车的稳定性,行驶速度被分为四个等级。在直道上,小车会逐渐加速,当加到最高速时保持匀速行驶。当检测到弯道时,小车会立即减速,并根据弯道的程度来调整速度和转向。 然而,在引用中提到了扫线方法在处理锐角时不适用的问题。但是在该赛道上,锐角只会在图片的上方出现,且只会出现左锐角,并且占比较小。因此,可以通过判断锐角的方式来避免扫描锐角的线。 综上所述,通过opencv实现智能车巡线的方法是,在白色地面上通过摄像头检测黑色的车道线,同时根据检测到的弯道和锐角来调整小车的速度和转向,以完成巡线任务。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [基于opencv巡线方案](https://blog.csdn.net/weixin_64583557/article/details/126489522)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [智能小车视觉巡线python代码](https://download.csdn.net/download/LY2996944198/12646227)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [智能车巡线python-opencv](https://blog.csdn.net/m0_58644391/article/details/124382394)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

雕雀桑

感谢支持

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

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

打赏作者

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

抵扣说明:

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

余额充值