智能车搜集数据集代码理解

先上代码:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import time
import cv2
import config
from serial_port import Serial
from camera import Camera
from detectors import SignDetector,TaskDetector
import threading
import numpy as np
class run:
    def __init__(self):
        self.front_camera = Camera(config.front_cam, [640, 480]) #前摄像头初始化
        #config.front_cam 参数指定了要读
        # 取的摄像头的设备编号或地址,而 [640, 480] 参数指定了读取的图像的尺寸。
        self.com=Serial() #串口初始化
        self.front_camera.start() #开启前摄像头线程
        #程序会调用 Camera 类中的 run() 方法,在其中循环
        # 读取摄像头图像,并将其保存在 self.front_image 中。
        self.td = TaskDetector() #侧图标模型初始化
        self.stopped = False #停止识别标志位

    def front_start(self): #前图标模型线程
        threading.Thread(target=self.front_updata, args=()).start()
        print('front model start')
##############################################front
    def front_updata(self):
        k=0
        while True:
            if self.stopped:
                print('front model stop')
                break
            self.x=1000
            self.y=1000
            self.front_image = self.front_camera.read()
            if k <5:
                k=k+1
            else:
                k=0
                try:
                    self.signs = self.td.detect(self.front_image)
                    for self.sign in self.signs:
                        self.left = self.sign.relative_box[0]
                        self.top = self.sign.relative_box[1]
                        self.right = self.sign.relative_box[2]
                        self.bottom = self.sign.relative_box[3]
#                        self.front_val = str(self.sign)[5] + '=' + str(int(self.top))
                        self.x=((int(self.top * 480) + int(self.bottom * 480))/2)
                        self.y=(( int(self.left*640)+int(self.right*640))/2)
                        self.com.write("CB="+str(self.sign.index)+"+"+str(self.x) +"+"+  str(self.y)+'\n')
                        print(("CB="+str(self.sign.index)+"+"+str(self.x) +"+"+  str(self.y)+'\n'))
                except:
                    self.com.write("CB="+"0"+"+"+str(self.x)+"+"+str(self.y)+"+"+"\n")
                    print("CB="+str(0)+"+"+str(self.x) +"+"+  str(self.y)+'\n')

    def cc_show(self):#cc_show方法用于将检测到的标志在图像上显示出来,但在代码中被注释掉了。
        try:
            #draw_res(self.front_image, self.signs)
            #draw_res(self.side_image, self.tasks)
            #self.front_frame = draw_cruise_result(self.front_image, self.csruise_result)
            cv2.imshow("show", self.front_frame)
            #cv2.imshow("show1", self.front_image)
        except:
            print('show error')
################################################result





if __name__=='__main__':
    fig=0
    num=0
    go = run()
    go.front_start()
    #定义了front_start方法,该方法会开启一个线程并调用front_updata方法,用于获取
    # 前置摄像头的图像,并进行标志检测和位置计算。然后将检测结果通过串口发送给其他硬件设备。
    time.sleep(0.5)
    print('go')
    while True:
        if fig==1:
            name = 'picc/' + 'o' + str(num) + ".jpg"
            data = (-(80 - go.front_val) / 80)
            print(data)
            cv2.imwrite(name, go.front_image)
            f.write(name + " " + str(data) + "\n")
            print(name + " " + str(go.send) + " is OK!")
            num = num + 1
        if cv2.waitKey(1) & 0xFF == ord('s'):
            fig=1
        if cv2.waitKey(1) & 0xFF == ord('a'):
            fig=0
            f.close()
            
            print("over")
            break  
            
#        if cv2.waitKey(1) & 0xFF == ord('d'):
#            f.close()
#            break    
#    cv2.waitkey(1)
#
#    cv2.destroyAllWindows()

1,其中新建了一条独立线程(通过使用threading.Thread函数,可以让self.front_updata方法在一个独立的线程中运行,不会阻塞主线程的执行。)

其中的arg=()

参数 args 用于指定要传递给目标函数 target 的参数,是一个元组类型。如果目标函数不需要传递参数,则 args 可以为空,即 args=()

在这个特定的代码中,args=() 表示 self.front_updata() 函数没有需要传递的参数。

start()Thread 类提供的一个方法,用于启动一个新的线程来执行指定的函数(或方法)。调用 start() 方法后,线程会在后台异步执行指定的函数,不会阻塞主线程。如果没有调用 start() 方法,线程不会执行。同时,每个线程只能被启动一次,多次调用 start() 方法会抛出异常。

2,解析front_updata方法:

这段代码定义了一个名为front_updata的方法,用于在前置摄像头上检测目标并发送控制信号给单片机。

方法主要的步骤包括:

  1. 用一个无限循环(while True)来不断读取前置摄像头的图像,并处理图像中的目标。如果self.stopped的值为True,则跳出循环。

  2. 首先将坐标self.xself.y的值设为1000,表示当前没有检测到目标。然后通过self.front_camera.read()方法读取前置摄像头的图像,并将其保存在self.front_image变量中。(将self.x和self.y的值设为1000的目的是在没有检测到目标时,将其坐标值设置为一个特殊的值,以便在后续使用这些值时能够知道目标没有被检测到。例如,在代码中,如果self.x和self.y的值没有被更新,则会将其设为1000,并在发送到串口时加上一个特殊的标记,以便在接收方知道当前没有检测到目标。这样可以避免在没有检测到目标时出现意外的行为或错误。)

  3. 为了减少目标检测的计算量,设置了一个计数器k,每5帧图像才进行一次目标检测。

  4. 如果计数器k达到5,则调用目标检测器(self.td.detect()方法)在当前图像中检测目标。检测结果保存在self.signs列表中,遍历每一个目标(self.sign in self.signs),获取目标的左上角和右下角坐标(self.leftself.topself.rightself.bottom)。

  5. 根据目标的左上角和右下角坐标,计算目标在图像中的中心点坐标,并将其赋值给self.xself.y。然后调用self.com.write()方法将控制信号发送给单片机,格式为“CB=目标编号+x坐标+y坐标+换行符”。

  6. 如果在目标检测过程中发生异常,则默认当前图像中没有目标,将控制信号“CB=0+1000+1000+换行符”发送给单片机。同时,在终端上打印出“CB=0+x坐标+y坐标+换行符”的消息。

注意,该方法中涉及到一些变量和方法的来源需要在其他代码中寻找。比如self.stopped是一个标志位,用于控制线程的停止;self.td.detect()方法是目标检测器的接口方法,用于检测目标并返回检测结果;self.com.write()方法用于向串口发送数据,用于控制机器人运动。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值