基于yolov5的智能分类垃圾桶整套实现

最近一段时间和实验室同学一起做了一个本科毕设,毕设的目的是做一个智能分类垃圾桶,摄像头拍一个物体,然后自动识别这个物体属于可回收垃圾、有害垃圾还是其他垃圾,接着控制舵机打开相对应的垃圾桶盖,其实还可以做厨余垃圾,但是因为缺少数据集的问题,为了减少工作量,我就没有加入新的厨余垃圾数据集(不想自己打那么多的标哈哈哈)。

下面描述一下项目的整体流程:首先在电脑上部署yolov5的环境,我使用的是Anaconda+Pycharm,yolov5的代码使用的是github上提供的标准代码,但是为了契合我们的项目,我在detect.py文件中加了一些自己的代码,整体的yolov5代码我会附在整篇文章的最后,方便大家使用。

yolov5环境部署好之后,运行detect.py文件,这时摄像头会打开,自动弹出一个窗口,如下所示:

 此时按下回车键就会自动拍摄一个照片保存到本地,然后按ESC键之后就会继续向下执行,我使用的是绝对路径,所以如果你想部署在你本地的话,还需要修改一下保存照片的路径,在detect.py文件中修改,具体如下:

output_dir = 'D:\yolov5'
i = 1
cap = cv2.VideoCapture(0)
while 1:
    ret, frame = cap.read()
    cv2.imshow('cap', frame)
    flag = cv2.waitKey(1)
    if flag == 13:

        output_path = os.path.join(output_dir, "1.jpg")
        cv2.imwrite(output_path, frame)
    i += 1
    if flag == 27:
         break

把   output_dir = 'D:\yolov5'   修改掉就好。

上一步完成之后,yolov5会识别刚才拍的照片中的物体,然后识别出的物体类型会存在class_label变量中,紧接着这个变量会通过socket传给树莓派,树莓派接收到这个变量之后会进行一些判断,判断打开哪一个舵机。舵机开完之后,下一步树莓派会将刚才接收到的物体类型连带垃圾桶上的温度、湿度传感器信息一起通过socket传给笔记本,笔记本这边做了一个前端界面,传过来的信息会存在数据库中,这样所有的信息都会汇总起来,这样就完成了一个简单的毕设工作。

下面具体讲一下每一步的细节,并且所有的文件、代码、成品图片都会一一展示出来。

首先是yolov5代码,yolov5如何部署,网上有很多的教程,大家可以去网上搜一下,其次是我在detect.py中加了socket传输代码,如果你部署的话,这个地方就需要修改一下IP地址,修改成你接受变量数据的设备IP,比如这边我要向树莓派传输变量,那么我就填写树莓派的IP地址,端口号填写9000应该问题就不打了,代码如下:

import socket

sk = socket.socket()
ip_port = ("192.168.1.108", 9000)
sk.connect(ip_port)
sk.send(class_label.encode())

在树莓派端也要部署接收的代码,代码如下:

def talk(conn):
    while 1:  # 循环通讯
        try:
            channel = conn.recv(1024).decode('utf-8')
            if not channel:
                break
            print("进程<%s>来自客户端的消息:%s" % (os.getpid(), channel))
            checkChenel(channel)
            conn.send(channel.encode('utf-8'))
        except:
            break
    conn.close()
 
 
def socket():
    import socket
    print("start socket")
    server_sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_sk.bind(('192.168.1.108', 9000))
    server_sk.listen(5)
    while 1:
        new_sk, addr = server_sk.accept()
        p = Process(target=talk, args=(new_sk,))
        p.start()
    server_sk.close()

这样两端就可以通信起来,从而能够传输物体类别参数。还有一个重要的问题也要注意一下,在使用socket的时候,不能单线程,得要启动一个双线程,不然就会报错,这样就得在上面这段代码下面加上一个创建新线程的代码,代码如下:

 # 创建一个线程
mthread = threading.Thread(target=socket)
#     # 启动刚刚创建的线程
mthread .start()
 
# Set frequency to 50hz, good for servos.
pwm.set_pwm_freq(50)
 
print('Moving servo on channel x, press Ctrl-C to quit...')
#while True:
#    channel=int(input('pleas input channel:'))
#     Move servo on channel O between extremes.
 

这样就可以正常地进行参数传输。紧接着通过以下代码来控制舵机旋转对应的角度:

def checkChenel(channel):
    channel = int(channel)
    if channel == 1:
        set_servo_angle(channel, -15)
        time.sleep(5)
        set_servo_angle(channel, 110)
        time.sleep(0.5)
    elif channel == 2 :
        set_servo_angle(channel, 60)
        time.sleep(5)
        set_servo_angle(channel, 170)
        time.sleep(0.5)
    elif channel == 3 :
        set_servo_angle(channel, 60)
        time.sleep(5)
        set_servo_angle(channel, 170)
        time.sleep(0.5)
    elif channel == 4 :
        set_servo_angle(channel, 60)
        time.sleep(5)
        set_servo_angle(channel, 170)
        time.sleep(0.5)

以上部分的具体展示如下:

1.yolov5识别具体的物体属于什么类别:

此时识别出的是种类二,也就是有害垃圾,这个是在yolov5配置文件中修改的,如下图所示:

 在配置的时候,这些绝对地址都需要修改,如果有报错的话,基本上都是绝对地址没有修改好,耐心检查一下就OK。

2.树莓派端接收到类别信息,控制舵机打开垃圾桶盖:

3.树莓派外界了一个温湿度传感器,打开舵机之后,树莓派会将垃圾类别信息以及外接温湿度传感器的信息汇总好,通过socket传输给专门制作的前端后台中,存入数据库之后,然后前端界面中会显示出来此次垃圾分类的类别信息和温湿度信息。

完整演示视频在我的个人空间里面,可以进去查看

智能垃圾桶演示视频

所有的代码我都汇总好了,数据集也汇总好了,有需要的可以自取。

 链接:https://pan.baidu.com/s/1x26GFAkIlbUnPvW2KJ2KZw?pwd=0412 
提取码:0412

猜你喜欢

转载自blog.csdn.net/m0_61438337/article/details/123607966