智能车巡线python-opencv

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

背景:2022智能车比赛百度提高组

思路:先拿赛道通过HSV调阈值,然后得到二值化图片,对二值化图像进行巡线;

巡线的思路:从图片最后一行的中央开始往左右两边扫线:分扫左线与扫右线;

以左线为例子:(图片大小为480*640)

图片以最后一行开始往第一行循环作为外循环(设为i),以中线开始往左减一作为内循环(设为j);记录该行的跳变点:即如果该行的该列为白色(255),下一列为黑色(0)则记录其列标(j),如果不满足该条件则说明无跳变点即该行无线,记录为0;记录到一个数组内(采用append的方法)。

右边线一样的思路,只不过如果没有线就记录为右最大列标(639)

赛道元素处理:

赛道有十字,锐角转弯,连着的双十字,以及因为摄像头安装的位置导致的缺角与缺赛道

锐角:

智能车巡线python-opencv

 双十字:

智能车巡线python-opencv

十字: 

智能车巡线python-opencv

缺角等:

 智能车巡线python-opencv

 智能车巡线python-opencv

 ......就不一 一展示了。

处理思路:1.锐角元素:

因为锐角出现,导致扫线方法不适用;然而锐角只会在图片上方出现,要么左锐角,要么右锐角,我们这个赛道只会出现左锐角,且占比较小,所以直接判断锐角,然后不扫锐角的线;

效果:智能车巡线python-opencv

代码:如果当前行的最左边为非车道(0),下一行(往上)为车道(非0),右边线为非车道,则中断循环;因为锐角只会出现在左转,我们赛道十字都出现在左转,所以这样做不会出漏扫(如果十字处右转,则可能会出现漏扫现象)。

2.十字与缺角:

思路:先计算拐点,然后通过拐点来判断补线;补线直接将上下拐点连接起来:斜截式方程。

拐点的计算:计算左(右)边线的跳跃点:从0(黑)变到非0(白)即为左(右)上拐点, 从非0(白)变到0(黑)即为左(右)下拐点。(用四个变量标志记录是否存在拐点,如果有就再用四个变量存拐点坐标)

A.先补拐点,即如果左(右)边只有一个拐点,则另一个拐点就通过该拐点赋值,具体看程序:只有上拐点就把下拐点记为最下面一行同一列的点...

B.通过拐点标志判断如何补线

补线判断:只要出现拐点就补线

效果:智能车巡线python-opencv

智能车巡线python-opencv

智能车巡线python-opencv

 拐点的位置可以通过代码里面的 sm 这个变量调整

代码:(函数里对照片进行展示比较耗时,返回值为巡得的中线数组)

import cv2
import numpy
import numpy as np


def nothing(*arg):
    pass


icol = (18, 0, 196, 36, 255, 255)

#path = "test/cruise/"
# Show the original image.
#frame = path+str(961)+'.jpg'
#frame = cv2.imread(frame)
l = [16, 45, 65]  # [17, 55, 128]#阈值
h = [44, 255, 255]  # [24, 255, 255]#阈值

def zh_ch(string):
    return string.encode("gbk").decode('UTF-8', errors='ignore')

# mm = 320
cap = cv2.VideoCapture(0)
def XunX(img,SX):
    cv2.imshow('frame', img)
    # Blur methods available, comment or uncomment to try different blur methods.
    frameBGR = cv2.GaussianBlur(img, (7, 7), 0)

    hsv = cv2.cvtColor(frameBGR, cv2.COLOR_BGR2HSV)
    # HSV values to define a colour range.

    colorLow = numpy.array([16, 45, 65] )  # [17, 55, 128]
    colorHigh = numpy.array([44, 225, 225])  # [24, 225, 225]
    mask = cv2.inRange(hsv, colorLow, colorHigh)
    # Show the first mask
    cv2.imshow('mask-plain', mask)
    kernal = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernal)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernal)
    cv2.imshow('mask-plain', mask)
    # Find_Line(mask)

    left = np.array([])
    right = np.array([])
    leftb = np.array([])
    rightb = np.array([])
    medim = np.array([])
    # len = []#记录边线丢失
    le = [[]]
    ri = [[]]
    zz = 0  # 记录左缺陷时上一个坐标
    yy = 639
    SX = SX  # 开始扫线时的y坐标
    SXp = np.array([])
    SS = 0
    left_up = left_down = right_up = right_down = 0
    for i in range(480, 1, -1):
        # 扫左线
        for j in range(SX + 1, 0, -1):
            # 中线:319
            if (mask[i - 1][j] == 0) and (mask[i - 1][j - 1] == 255):
                # 记录左跳变点的列值
                left = np.append(left, j)
                leftb = np.append(leftb, j)
                zz = j
                break
            # 现在缺线
            elif (j == 1):
                lk = 0
                left = np.append(left, lk)
                leftb = np.append(leftb, lk)

        # 扫右线
        for j1 in range(SX + 2, 639, 1):
            if (mask[i - 1][j1] == 0) and (mask[i - 1][j1 + 1] == 255):
                # 记录右跳变点的列值
                right = np.append(right, j1)
                rightb = np.append(rightb, j1)
                yy = j1

                break
            # 缺线
            elif (j1 == 638):
                lk = 639
                rightb = np.append(rightb, lk)
                right = np.append(right, lk)
        if (left[480 - i] == 0 and right[480 - i] != 639 and mask[i - 2][0] != 0 ):
                    break
        # if (right[480 - i] == 639 and left[480 - i] != 0 and mask[i - 2][639] != 255 ):
        #             break
        SX = int((left[480 - i] + right[480 - i]) / 2)
        SXp = np.append(SXp, SX)
    # 找拐点
    sm = 30
    for i in range(len(left) - 10):
        if (left[i] == 0 and left[i + 3] == 0 and left[i + 5] > 0 and left[i + 10] > 0):
            left_up = 1
            left_up1 = (i + min(len(left[i+2:]),sm), left[i + min(len(left[i+2:]),sm)])  # 480 - i-sm
        if (left[i] > 0 and left[i + 3] > 0 and left[i + 5] == 0 and left[i + 10] == 0):
            left_down = 1
            left_down1 = (i - min(i,sm), left[i - min(i,sm)])  # 480 - i+sm
        if (right[i] == 639 and right[i + 3] == 639 and right[i + 5] < 639 and right[i + 10] <= 639):
            right_up = 1
            right_up1 = (i + min(len(left[i+2:]),sm), right[i + min(len(left[i+2:]),sm)])
        if (right[i] < 639 and right[i + 3] < 639 and right[i + 5] == 639 and right[i + 10] == 639):
            right_down = 1
            right_down1 = (i - min(i,sm), right[i - min(i,sm)])  # -1
    # 判断元素:补线操作
    print(left_up, left_down, right_up, right_down)
    if (left_up and not left_down):
        left_down1 = (0, left_up1[1])
    elif (not left_up and left_down):
        left_up1 = (479, left_down1[1])
    if (right_up and not right_down):
        right_down1 = (0, right_up1[1])
    elif (not right_up and right_down):
        right_up1 = (479, right_down1[1])
    # 左右的上下拐点同时出现
    #if (left_up and right_up) or (left_down and right_down):
    if (left_up or right_up) or (left_down or right_down):
        # if(right_up1[0] - left_up1[0] <= 20):
        for k in range(len(leftb)):
            if (k >= left_down1[0] and k <= left_up1[0]) or (k <= left_down1[0] and k >= left_up1[0]):
                leftb[k] = ((left_up1[1] - left_down1[1]) / (left_up1[0] -
                                                             left_down1[0])) * (k - left_up1[0]) + left_up1[1]
            if (k >= right_down1[0] and k <= right_up1[0]) or (k <= right_down1[0] and k >= right_up1[0]):
                rightb[k] = ((right_up1[1] - right_down1[1]) / (right_up1[0] -
                                                                right_down1[0])) * (k - right_up1[0]) + right_up1[1]
    # # 同时出现左上下,或右上下:
    # if (left_up and left_down) or (right_up and right_down):
    #     # if(right_up1[0] - left_up1[0] <= 20):
    #     for k in range(len(leftb)):
    #         if (k >= left_down1[0] and k <= left_up1[0]) or (k <= left_down1[0] and k >= left_up1[0]):
    #             leftb[k] = ((left_up1[1] - left_down1[1]) / (left_up1[0] -
    #                                                          left_down1[0])) * (k - left_up1[0]) + left_up1[1]
    #         if (k >= right_down1[0] and k <= right_up1[0]) or (k <= right_down1[0] and k >= right_up1[0]):
    #             rightb[k] = ((right_up1[1] - right_down1[1]) / (right_up1[0] -
    #                                                             right_down1[0])) * (k - right_up1[0]) + right_up1[1]
    # left_up = left_down = right_up = right_down = 0
    #  if

    medim = (leftb + rightb) / 2
    #  img = [mask,mask3,mask4,mask5]
    pl = ['left', 'right', 'l&r', 'no']
    o = 0
    img = mask
    cg = len(left)-1
    print(cg,len(leftb),len(right))
    for k in range(cg, -1, -1):
        point = (int(medim[k]), 479 - k)  # 左
        # point2 = (SXp[k], 478-k)
        point3 = (int(leftb[k]), 479 - k)  # 中
        point1 = (int(rightb[k]), 479 - k)  # 右
        cv2.circle(img, point, 1, (255, 0, 255), 0)
        cv2.circle(img, point1, 1, (255, 0, 255), 0)
        cv2.circle(img, point3, 1, (255, 0, 255), 0)
    cv2.imshow(pl[o], img)
    cv2.waitKey(100000)
    return SX,(leftb + rightb) / 2,SXp

mm = 320#扫线开始的坐标
cap = cv2.VideoCapture(0)
while True:
    test, frame = cap.read()

    print(frame.shape)
    mm,XB,SXp = XunX(frame, mm)
cv2.destroyAllWindows()


效果:

智能车巡线python-opencv

智能车巡线python-opencv

附录(阈值调试代码与文章):

https://blog.csdn.net/qq_35831978/article/details/106988028?spm=1001.2014.3001.5506

 持续更新文章来源地址https://www.toymoban.com/news/detail-442297.html

到了这里,关于智能车巡线python-opencv的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • python-opencv

    python_opencv安装使用笔记 链接: OpenCV——基于Python开发的OpenCV安装教程 链接: Python使用pip安装库时WARNING: You are using pip version 21.3.1; however, version 22.3.1 is available.的解决办法 链接: Opencv中的图像相加,相减,相除,相乘(python实现) 链接: opencv-python识别魔方特定颜色方块,并输

    2024年02月01日
    浏览(48)
  • python-opencv划痕检测

    这次实验,我们将对如下图片进行划痕检测,其实这个比较有难度,因为清晰度太差了。 我们做法如下: (1)读取图像为灰度图像,进行自适应直方图均衡化处理,增强图片对比度 (2)然后进行三次图像去噪 - 高斯滤波 (3)然后我们再进行一次直方图均衡操作增强图片

    2024年02月03日
    浏览(44)
  • 【python-opencv】硬币检测

    使用 python3.8.x,opencv 使用图像处理技术,从照片中识别硬币的个数,并判断总价值。 使用颜色特征,识别出5角硬币 使用半径大小,判断出1角和1元硬币。 具体操作 将图片转换为HSV颜色模型 部分代码 提取轮廓信息 cv2.findContours() 拟合椭圆,提取ROI cv2.fitEllipse() 模板匹配 cv

    2024年02月02日
    浏览(44)
  • ROS+Python-opencv(1)

    #!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright (c) 2021 PS-Micro, Co. Ltd. # # SPDX-License-Identifier: Apache-2.0 # #该python文件可以当作节点放在工作空间中启动 import time import rospy import cv2 from cv_bridge import CvBridge, CvBridgeError from sensor_msgs.msg import Image import numpy as np from math import * from geometry_

    2024年03月19日
    浏览(67)
  • python-opencv划痕检测-续

    这次划痕检测,是上一次划痕检测的续集。 处理的图像如下: 这次划痕检测,我们经过如下几步: 第一步:读取灰度图像 第二步:进行均值滤波 第三步:进行图像差分 第四步:阈值分割 第五步:轮廓检测 第六步:绘制轮廓,并将过滤面积较小的轮廓,且进行轮廓填充 代码

    2024年01月17日
    浏览(43)
  • Python-OpenCV 图像的基础操作

    首先读入一副图像: 获取像素值及修改的更好方法: img = cv2.imread(‘./resource/image/1.jpg’, cv2.IMREAD_COLOR) img.shape: 图像的形状(包括行数,列数,通道数的元组) img.size : 图像的像素数目 img.dtype :图像的数据类型 ROI(regionofinterest),感兴趣区域。机器视觉、图像处理中,从被

    2024年02月14日
    浏览(46)
  • python-opencv车牌检测和定位

    第一章 python-opencv-图片导入和显示 第二章 python-opencv图像简单处理 第三章 python-opencv图像mask掩膜处理 第四章 python-opencv图像马赛克 第五章 python-opencv人脸马赛克 第六章 python-opencv人脸检测 第七章 python-opencv图像张贴 第八章 python-opencv轮廓绘制 第九章 python-opencv边缘检测 第十

    2024年02月07日
    浏览(53)
  • python-opencv对极几何 StereoRectify

    函数介绍 函数参数 双目标定 参考博客 OpenCV相机标定全过程 [OpenCV实战]38 基于OpenCV的相机标定 opencv立体标定函数 stereoCalibrate() 主要使用的函数 代码 将打印的结果保存到标定文件中即可 极线校正 参考博客 机器视觉学习笔记(8)——基于OpenCV的Bouguet立体校正 小白视角之B

    2024年02月13日
    浏览(46)
  • 相机标定原理与实战【python-opencv】

    相机的功能就是将真实的三维世界拍摄形成二维的图片。所以可以将相机成像的过程看做一个函数,输入是一个三维的场景,输出是二维的图片。但是,当我们想将二维的图片反映射成三维场景时,很明显,我们无法仅通过一张二维图来得到真实的三维场景。也就是说,上述

    2024年02月09日
    浏览(63)
  • Python-Opencv图像处理的小坑

            最近在做一点图像处理的事情,在做处理时的cv2遇到一些小坑,希望大家遇到的相关的问题可以注意!!           cv2.imwrite(filename, img, [params]) filename :需要写入的文件名,包括路径和文件名,以及期望的扩展名(例如,.jpg,.png,.bmp等)。 img :需要保存的

    2024年02月04日
    浏览(52)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包