Robocom比赛中使用opencv-python进行轨道线识别(附带python源码+讲解)

1.前言:

此代码是本人参加Robocom比赛中完成其中一个要求模块使用的代码。主要功能是根据给定的图片,识别出黑色轨道线的线条在图片中的大致位置。如下图所示:

比赛要求:编写代码,从200张图片中随机选出20张图像,标出图像中 黑色线条的位置,并在终端中以文字形式输出机器人下一步应该如何调 整姿态(直行,向右前方调整方向,向左前方调整方向)。

2.源码

import cv2
import numpy as np
import random
import os, random, shutil

file_Dir = 'mydata/平安城市测试集/轨道线识别/'   #源图片文件夹路径
tar_Dir = 'mydata/test3/'    #移动到新的文件夹路径

def moveFile(file_Dir):
          

        pathDir = os.listdir(file_Dir)    #取图片的原始路径
        filenumber=len(pathDir)
        rate=0.1    #自定义抽取图片的比例,比方说100张抽10张,那就是0.1
        picknumber=int(filenumber*rate) #按照rate比例从文件夹中取一定数量图片
        sample = random.sample(pathDir, picknumber)  #随机选取picknumber数量的样本图片
        print (sample)
        for name in sample:
                shutil.copy(file_Dir+name, tar_Dir+name)
        return

if __name__ == '__main__':

    moveFile(file_Dir) #移动选取的文件

    for filename in os.listdir('mydata/test3'): #遍历路径下所有图片
        print(filename)
        image= cv2.imread('mydata/test3'+'/'+filename) 
        image = cv2.resize(image,(600,600)) 

        gs_frame = cv2.GaussianBlur(image, (11, 11), 0) # 高斯滤波获取轮廓
        gray = cv2.cvtColor(gs_frame,cv2.COLOR_BGR2GRAY)   # 原彩色图片转换成灰度图
        ret, binary = cv2.threshold(gray,145,255,cv2.THRESH_BINARY_INV)  # 二值化
        kernel = np.ones((40, 40), dtype=np.uint8) # 膨胀图像
        dilate = cv2.dilate(binary, kernel, 1) # 1:迭代次数,也就是执行几次膨胀操作
        # 进行腐蚀
        kernel = np.ones((20, 20), dtype=np.uint8)
        erosion = cv2.erode(dilate, kernel, iterations=1)
        contours, hierarchy = cv2.findContours(erosion,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#轮廓检测,寻找边框
        area = []
        area_num = []
        for i in range(len(contours)):
            a = cv2.contourArea(contours[i], True)
            area.append(abs(a))
        if len(area) > 1:
            for i in range(len(area)):
                area_num.append(i)
            area_num.remove(area.index(max(area)))
            for i in range(len(area_num)):
                erosion = cv2.drawContours(erosion, contours, area_num[i], 0, cv2.FILLED)
        # 查询角点
        points_hang = []
        points_lie = []
        for i in range(600):
            for j in range(600):
                if erosion[i, j] != 0:
                    points_hang.append(i)
                    points_lie.append(j)
        c1 = min(points_hang)
        c2 = max(points_hang)
        c3 = min(points_lie)
        c4 = max(points_lie)
        if erosion[c1,c3] == 255 and erosion[c2,c3] == 0:
            print('left')
        if erosion[c1,c4] == 255 and erosion[c2,c4] == 0:
            print('right')
        if erosion[c1,c3] == 0 and erosion[c1,c4] == 0:
            print('Go straight')
        # 绘制图框
        cv2.rectangle(image, (c3,c1), (c4,c2), (0,255,0), 2)
        cv2.imshow("result", image)
        cv2.waitKey(0)

3.总结

以上就是我的代码,希望能够帮助大家。有什么问题大家也可以在评论区进行讨论交流。

  • 10
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值