树莓派小车实现目标追踪(coco数据集,gluoncv,树莓派和PC信息交互)

本文档介绍了一个使用树莓派3b+、麦克纳姆轮和USB摄像头的项目,通过PC上的GluonCV库进行图像预测,利用YOLO3_darknet53_coco模型进行目标检测。PC端接收树莓派发送的图片,处理后返回目标信息,树莓派根据这些信息控制小车运动。整个过程中,PC和树莓派通过socket进行通信。
摘要由CSDN通过智能技术生成

目录

一、原理图

二、硬件介绍及成果展示

三、pc端操作及关键源码

3.1接收树莓派发来的图片

3.2处理接收到的图像

3.3将结果(txt)发回给树莓派

四、树莓派端操作及关键代码

4.1 截图,并上传到电脑

4.2 接受电脑返回的txt

4.3 读取txt

4.4 根据参数做出小车的运动决策

五、项目源码


一、原理图

 由于树莓派3b性能有限,所以只能通过电脑进行预测。


二、硬件介绍及成果展示

树莓派3b+

麦克纳姆轮

usb摄像头:640*480

视频展示:

树莓派小车追踪目标_哔哩哔哩_bilibili


三、pc端操作及关键源码

3.1接收树莓派发来的图片

import socket
import os
import sys
import struct
import result
import scanimage

def socket_service():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # IP地址留空默认是本机IP地址
        s.bind(('', 8088))
        s.listen(7)
    except socket.error as msg:
        print(msg)
        sys.exit(1)

    print("连接开启,等待传图...")

    sock, addr = s.accept()
    deal_data(sock, addr)
    s.close()


def deal_data(sock, addr):
    print("成功连接上 {0}".format(addr))

    while True:
        fileinfo_size = struct.calcsize('128sl')
        buf = sock.recv(fileinfo_size)
        if buf:
            filename, filesize = struct.unpack('128sl', buf)
            fn = filename.decode().strip('\x00')
            # PC端图片保存路径
            new_filename = os.path.join('D:\AI_project\gluoncv', fn)

            recvd_size = 0
            fp = open(new_filename, 'wb')

            while not recvd_size == filesize:
                if filesize - recvd_size > 1024:
                    data = sock.recv(1024)
                    recvd_size += len(data)
                else:
                    data = sock.recv(1024)
                    recvd_size = filesize
                fp.write(data)
            fp.close()
        sock.close()
        class_id, scores, bounding_boxs = scanimage.scan(r'D:\AI_project\gluoncv\image.png')
        # # print('class_id:', class_id)
        # # print('scores:', scores)
        # # print('bounding_boxs:', bounding_boxs)
        os.remove(r'D:\AI_project\gluoncv\image.png')
        file = open(r"D:\AI_project\gluoncv\result.txt", 'w')
        file.write(str(class_id))
        file.write('\n')
        file.write(str(scores))
        file.write('\n')
        file.write(str(bounding_boxs))
        break


if __name__ == '__main__':
    socket_service()

将树莓派和PC保持在同一个网络中。使用socket包互相传递信息。

注:手机热点获取树莓派ip地址方法:

(49条消息) 手机热点ip查看(用于远程树莓派)_宇智波洛必达的博客-CSDN博客

3.2处理接收到的图像

调用gluoncv

from gluoncv import model_zoo, data, utils

下载yolo3_darknet53_coco模型,并把树莓派上传的截图放进去进行预测。

预测结果是

class_ID:预测到的目标标签

scores:得分(应该是叫可信度还是啥的?)

bounding_boxs:[预测框左上角坐标,右下角坐标]

net = model_zoo.get_model('yolo3_darknet53_coco', pretrained=True, root='D:\AI_project\gluoncv\model')
x, img = data.transforms.presets.yolo.load_test(dir, short=512)
class_IDs, scores, bounding_boxs = net(x)

# print('Shape of pre-processed image:', x.shape)
# print('class:', class_IDs[0][0])
# print('scores:', scores[0][0])
# print('bounding_box:', bounding_boxs[0][0])

另外,bounding_boxs的坐标系如下图:

3.3将结果(txt)发回给树莓派

import socket
import os
import sys
import struct


def send_txt():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 192.168.199.1和8088分别为服务端(pc)的IP地址和网络端口
        s.connect(('192.168.150.59', 8077))
    except socket.error as msg:
        print(msg)
        print(sys.exit(1))

    while True:
        # filepath是要被发送图片的路径
        filepath = r'D:\AI_project\gluoncv\result.txt'
        fhead = struct.pack(b'128sl', bytes(os.path.basename(filepath), encoding='utf-8'), os.stat(filepath).st_size)
        s.send(fhead)
        print('client filepath: {0}'.format(filepath))

        fp = open(filepath, 'rb')
        while 1:
            data = fp.read(1024)
            if not data:
                print('{0} 发送成功...'.format(filepath))
                break
            s.send(data)
        s.close()
        break



发完后,这一轮的操作就和电脑再没关系了,电脑回到等待接收图像的状态,以此循环。


四、树莓派端操作及关键代码

4.1 截图,并上传到电脑

上传部分和电脑给raspberry发txt的过程完全一直,不再赘述。

4.2 接受电脑返回的txt

和电脑等待接受截图时完全一致。

4.3 读取txt

# @Time   : 2022/9/11 11:15
# @Author :lgl
# @e-mail :GuanlinLi_BIT@163.com
def read_result(file_route):
    global y1, x2, y2, x1
    file = open(file_route, 'r')
    line1 = file.readline()
    label = file.readline()
    line3 = file.readline()
    line4 = file.readline()
    score = file.readline()
    line5 = file.readline()
    line6 = file.readline()
    coordinate = file.readline()

    label = (label.split("[")[1]).split(".")[0]
    score = (score.split("[")[1]).split("]")[0]
    coordinate = coordinate.split(" ")
    num = 0
    for i in coordinate:
        if len(i) != 1 and len(i) != 0 and num == 0:
            x1 = i
            num += 1
            continue
        if len(i) != 1 and len(i) != 0 and num == 1:
            y1 = i
            num += 1
            continue
        if len(i) != 1 and len(i) != 0 and num == 2:
            x2 = i
            num += 1
            continue
        if len(i) != 1 and len(i) != 0 and num == 3:
            y2 = i
            num += 1
            continue
    x1 = x1.split("[")
    x1 = x1[len(x1)-1]
    y2 = y2.split("]")[0]
    return label, score, x1, y1, x2, y2

read_result("/home/pi/Desktop/gluoncv/result.txt")
print(x1,y1,x2,y2)

4.4 根据参数做出小车的运动决策

from motor import *
from random import random


def move(s, x1, y1, x2, y2, t):
    s = float(s)
    x1 = float(x1)
    y1 = float(y1)
    x2 = float(x2)
    y2 = float(y2)
    t = float(t)
    if s < 0.5:  # 得分过低,找不到目标,需要随机移动,直到找到东西
        forward(t)
        x = random()
        if x > 0.7:
            left_move(t)
        if x < 0.3:
            right_move(t)
        if 0.6 > x > 0.4:
            back(t)
    else:
        if x2 - x1 < 300:  # 找到了目标,但是距离太远,需要接近目标
            forward(t)
            print("forward")
        else:
            if x1 > 640 or x2 > 640 or x1 < 0 or x2 < 0 or y1 > 480 or y2 > 480 or y1 < 0 or y2 < 0:
                # 图像显示不全,证明距离太近了,需要后退
                back(t / 2)
                print("back")
            else:
                if (x1 + x2) / 2 > 400:  # 目标偏左
                    right_move(t)
                    print("right_move")
                if (x1 + x2) / 2 < 240:  # 目标偏右
                    left_move(t)
                    print("left_move")
                if 240 <= (x1 + x2) / 2 <= 400:  # 位置合适,不动,接着拍摄即可
                    print("OK!!!")

五、项目源码

树莓派小车实现目标追踪(yolo3,coco数据集,gluoncv,树莓派和PC信息交互)-Python文档类资源-CSDN文库

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

宇智波洛必达

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值