(开源)2023工训大赛智能垃圾分类项目(可循环播放视频,显示垃圾分类信息,拍照识别,垃圾分类,满载报警,压缩)

省赛:由于这个比赛是两年一届,并未做足充分的准备,但是通过一定的单片机基础,加上速成能力,也就是熬夜学,通过疯狂的网络搜索,在省赛第5 入选国赛

下面来简单介绍一下我们作品:

主控:因为识别如果你不将图像处理放到主控上处理,就有点麻烦,因为我们是使用的K210作为识别装置的,识别速度很快,如果进行识别发串口,就有点赌,本来速度就快,处理都处理不过来,当然你也可以用个取平均的算法,貌似这样也不是很好,还是得把识别和分类放到一起,这样处理才连贯。

最开始考虑的使用openmv,或者opencv在树莓派上做图像识别。 这个方案现阶段真不建议尝试,说实话,效果很不好。先不说准确率了,光是识别帧率就低到离谱。 所以当时也很巧合,发现一款很不错,上手很简单的开发板。就是Sipeed科技推出的几款k210芯片的开发板,第一眼看到,真是精致,再了解它的功能,简直强大,再看它的价格,wc,好划算(虽然这一年涨价了,还涨了不少)。尤其是这么小巧的一个板子,跑图像识别真是强,还很流畅,为什么呢?自己去看吧。

原文链接:https://blog.csdn.net/GUA8122HOU/article/details/120317568

这是k210总代码:

python 复制代码
#2023 10 15 派大星改
# object classifier boot.py
# generated by maixhub.com
from fpioa_manager import *
from modules import ultrasonic
from fpioa_manager import fm
from Maix import GPIO
import math
import struct
import sensor, image, lcd, time
import KPU as kpu
import gc, sys
from Maix import GPIO
from machine import UART
from machine import Timer,PWM
#
#
i= 8
# 定义超声波传感器的触发引脚和回响引脚
trig_pin = 0
echo_pin = 1

#控制串口通信
board_info_tx=15
board_info_rx=17
# 将GPIO口初始化为输入/输出模式
fm.register(trig_pin, fm.fpioa.GPIO0)
fm.register(echo_pin, fm.fpioa.GPIO1)
trig = GPIO(GPIO.GPIO0, GPIO.OUT)
echo = GPIO(GPIO.GPIO1, GPIO.IN)
tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)               #控制2个云台舵机
S1 = PWM(tim, freq=50, duty=0, pin=21)
tim = Timer(Timer.TIMER1, Timer.CHANNEL0, mode=Timer.MODE_PWM)
S2 = PWM(tim, freq=50, duty=0, pin=23)

value = 0xFF
s = struct.pack('B', value)
list_of_values = [255]*3
s = struct.pack('3B', *list_of_values)                                       #串口通信结束符

fm.register(board_info_tx,fm.fpioa.UART1_TX,force=True)
fm.register(board_info_rx,fm.fpioa.UART1_RX,force=True)
uart_A = UART(UART.UART1, 115200, 8, None, 1, timeout=1000, read_buf_len=4096)
#uart_A = UART(UART.UART1, 115200,read_buf_len=4096)


def Servo_1(servo,angle):
    S1.duty((angle+90)/180*10+2.5)              #竖直舵机
def Servo_2(servo,angle):
    S2.duty((angle+90)/270*10+2.5)              #水平舵机
#超声波
def measure_distance():
    trig.value(0) # 发送触发信号
    time.sleep_ms(2)
    trig.value(1)
    time.sleep_us(10)
    trig.value(0)
    start_time = time.ticks_ms()
    while echo.value() == 0 and time.ticks_diff(time.ticks_ms(), start_time) < 3000:
        pass

    # 如果等待超时,返回错误代码 -1
    if time.ticks_diff(time.ticks_ms(), start_time) >= 3000:
        print("Error: no echo received!")
        return -1

    # 记录回响信号的时间戳
    t1 = time.ticks_us()
    while echo.value() == 1:
        pass
    t2 = time.ticks_us()

    print(t2)
    # 计算距离(单位:厘米)
    duration = t2 - t1
    distance = duration * 0.017
    print(distance)
    if distance < 15:                                 #距离判断
       write_str = ("t20.bco=63488")
       uart_A.write(write_str)
       print("满载")
       uart_A.write(s)
    else:
       write_str = ("t20.bco=34784")
       uart_A.write(write_str)
       print("未满载")
       uart_A.write(s)
    return






def lcd_show_except(e):
    import uio
    err_str = uio.StringIO()
    sys.print_exception(e, err_str)
    err_str = err_str.getvalue()
    img = image.Image(size=(224,224))
    img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))
    lcd.display(img)
 #开机启动
 ########################################################################################################################
def main(labels = None, model_addr="/sd/m.kmodel", sensor_window=(224, 224), lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):
    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    sensor.set_windowing(sensor_window)
    sensor.set_hmirror(sensor_hmirror)
    sensor.set_vflip(sensor_vflip)
    sensor.run(1)

    lcd.init(type=1,invert=1)        #小LCD屏幕
    lcd.rotation(lcd_rotation)
    lcd.clear(lcd.WHITE)
    if not labels:
        with open('labels.txt','r') as f:
            exec(f.read())
    if not labels:
        print("no labels.txt")
        img = image.Image(size=(320, 240))
        img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)
        lcd.display(img)
        return 1
    try:
        img = image.Image("startup.jpg")
        lcd.display(img)
    except Exception:
        img = image.Image(size=(320, 240))
        img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)
        lcd.display(img)
    task = kpu.load(model_addr)
    try:
####################################循环######################################################################################
        a= 0
        while(a<3):
            print("启动")
            write_str = ("page main")           #跳到计数主屏幕
            uart_A.write(write_str)
            uart_A.write(s)
            print(write_str)
            a+=1


        while(True):
            Servo_1(S1, i)
            Servo_2(S2, 0)
            time.sleep_ms(500)
            measure_distance()                 #满载检查
            print("满载jianche ")
            write_str = ("n5.val=0")           #初始化串口屏幕
            uart_A.write(write_str)
            uart_A.write(s)
            print(write_str)
            while(True):

                img = sensor.snapshot()
                t = time.ticks_ms()
                fmap = kpu.forward(task, img)
                t = time.ticks_ms() - t
                plist=fmap[:]
                pmax=max(plist)                      #判断最大置信度
                if pmax < 0.4:                       #检测空物品
                    empty_str = "Not subject"
                    img.draw_string(0, 0, empty_str, scale=2)
                    lcd.display(img)
                    Servo_1(S1, i)
                    Servo_2(S2, 0)
                    break
                max_index=plist.index(pmax)
                img.draw_string(0,0, "%.2f : %s" %(pmax, labels[max_index].strip()), scale=2)
                img.draw_string(0, 200, "t:%dms" %(t), scale=2)
                lcd.display(img)


                if plist.index(pmax)==0 or plist.index(pmax)==6:  #fruit "vegetable"    厨余垃圾
                    if pmax >= 0.5:

                            time.sleep_ms(50)      #等待垃圾掉落待静止的时间
                            Servo_2(S2,90)
                            time.sleep_ms(1000)
                            Servo_1(S1,-20)
                            time.sleep_ms(1500)
                            #write_str = ()
                            Servo_1(S1,i)
                            time.sleep_ms(400)
                            Servo_2(S2,0)
                            time.sleep_ms(1000)
                            uart_A.write("t7.txt=\"厨余垃圾\"")
                            print("厨余垃圾ok")
                            uart_A.write(s)

                            time.sleep_ms(450)   #舵机归位
                            Servo_1(S1,i)
                            time.sleep_ms(450)
                            break
                            #time.sleep_ms(500)      #等待垃圾掉落待静止的时间

                if plist.index(pmax)== 1 or plist.index(pmax)==2 or plist.index(pmax)== 7:  #capsule      有害垃圾
                    if pmax >= 0.6:    #0.5

                            time.sleep_ms(50)      #时隔几秒后继续检测垃圾
                            #Servo_2(S2,90)
                            #time.sleep_ms(500)
                            Servo_1(S1,-30)
                            time.sleep_ms(1500)
                            #write_str = ()
                            uart_A.write("t7.txt=\"有害垃圾\"")
                            print("有害垃圾ok")
                            uart_A.write(s)

                            time.sleep_ms(450)   #舵机归位
                            Servo_1(S1,i)
                            Servo_2(S2,0)
                            time.sleep_ms(450)
                            break



                if plist.index(pmax)==4 or plist.index(pmax)==8:  #bottle        可回收垃圾
                    if pmax >= 0.5:

                            time.sleep_ms(50)      #等待垃圾掉落待静止的时间
                            Servo_2(S2,180)
                            time.sleep_ms(1000)
                            Servo_1(S1,-20)
                            time.sleep_ms(1500)
                            #write_str = ()
                            Servo_1(S1,i)
                            time.sleep_ms(400)
                            Servo_2(S2,0)
                            time.sleep_ms(1000)
                            uart_A.write("t7.txt=\"可回收垃圾\"")
                            print("可回收垃圾ok")
                            uart_A.write(s)
                            time.sleep_ms(1200)   #舵机归位
                            break



                if plist.index(pmax)==3 or plist.index(pmax)== 5 or plist.index(pmax)== 9:  #cigarette      其他垃圾
                    if pmax >= 0.7:  #0.5

                            time.sleep_ms(50)      #等待垃圾掉落待静止的时间
                            Servo_2(S2,-90)
                            time.sleep_ms(1000)
                            Servo_1(S1,-20)
                            time.sleep_ms(1500)
                            #write_str = ()
                            Servo_1(S1,i)
                            time.sleep_ms(400)
                            Servo_2(S2,0)
                            time.sleep_ms(1000)

                            uart_A.write("t7.txt=\"其他垃圾\"")
                            print("其他垃圾ok")
                            uart_A.write(s)
                            time.sleep_ms(450)   #舵机归位
                            Servo_1(S1,i)
                            Servo_2(S2,0)
                            time.sleep_ms(500)
                            break
        uart.deinit()                   # uart.deinit()和kpu.deinit(task)用于关闭UART和释放模型资源。
        del uart
    except Exception as e:
        raise e
    finally:
        if not task is None:
            kpu.deinit(task)

if __name__ == "__main__":
  try :
      #labels = ["bottle", "brick", "capsule", "pill", "stone", "vegetable"]
      #labels = ["chuyu", "dainci", "jiaolang", "shitou", "shuiping", "taoci", "yaobaozhung", "yilaguan"]
      labels = ["chuyu", "dainci", "jiaolang", "shitou", "shuiping", "taoci", "xiaotudou", "yaobaozhung", "yilaguan", "zhuangtou"]
      main(labels=labels, model_addr="/sd/m.kmodel")
  except Exception as e:
      sys.print_exception(e)
      lcd_show_except(e)
  finally:
      gc.collect()

识别:K210,虽然这东西是挺强的,但是模型有点难训练。我们是根据maixpy 官网的本地环境来进行训练的,环境有点麻烦,也可以直接CPU跑 但是有点发烫 我电脑都跑坏了,修了我300大洋,所以还是使用GPU跑,训练速度也快、

分类装置:初赛直接就是云台加舵机,没啥讲的,k210控制就可以了

满载检测:超声波检查,省赛的时候就做了一个,因为超声波挺费时间的,比赛一个物体识别的时间是有要求的,我们做了一个,结果没用上,没抽到,国赛我把其他三个加上去,结果是我自己选一个,气死,开始我还用小车的红外避障模块来做,简单的一批,后面还是觉得测的不如超声波准。还是用的

python 复制代码
import time
from fpioa_manager import fm
from Maix import GPIO

# 定义超声波传感器的触发引脚和回响引脚
trig_pin = 0
echo_pin = 1

# 将GPIO口初始化为输入/输出模式
fm.register(trig_pin, fm.fpioa.GPIO0)
fm.register(echo_pin, fm.fpioa.GPIO1)
trig = GPIO(GPIO.GPIO0, GPIO.OUT)
echo = GPIO(GPIO.GPIO1, GPIO.IN)


def measure_distance():
    # 发送触发信号
    trig.value(0)
    time.sleep_ms(2)
    trig.value(1)
    time.sleep_us(10)
    trig.value(0)

    # 等待回响信号
    while echo.value() == 0:
        pass
    t1 = time.ticks_us()

    while echo.value() == 1:
        pass
    t2 = time.ticks_us()

    # 计算距离(单位:厘米)
    duration = t2 - t1
    distance = duration * 0.034 / 2
    return distance


while True:
    distance = measure_distance()
    print("Distance: %.2f cm" % distance)
    time.sleep(1)

屏幕:直接使用串口屏,简单的要si,不要十分复杂的代码,你会发串口就可以用。

压缩:我们使用的是电动推杆,用arduino uno 控制 通过监听串口判断是不是可回收垃圾,然后启动

项目地址,求求了点个stars把

相关推荐
QuantumYou3 分钟前
计算机视觉 对比学习 串烧二
人工智能·学习·计算机视觉
阿利同学4 分钟前
热成像目标检测数据集
人工智能·目标检测·机器学习·目标跟踪·数据集·热成像目标检测数据集·机器学习 深度学习
拥抱AGI18 分钟前
我说大模型微调没啥技术含量,谁赞成谁反对?
人工智能·学习·语言模型·大模型学习·大模型入门·大模型教程
aqymnkstkw20 分钟前
2024年【电气试验】考试题库及电气试验模拟试题
大数据·c语言·人工智能·嵌入式硬件·安全
阡之尘埃27 分钟前
Python数据分析案例59——基于图神经网络的反欺诈交易检测(GCN,GAT,GIN)
python·神经网络·数据挖掘·数据分析·图神经网络·反欺诈·风控大数据
2401_85044049738 分钟前
激发AI创造力:掌握Prompt提示词的高效提问方法
人工智能·prompt
Terry Cao 漕河泾1 小时前
SRT3D: A Sparse Region-Based 3D Object Tracking Approach for the Real World
人工智能·计算机视觉·3d·目标跟踪
多猫家庭2 小时前
宠物毛发对人体有什么危害?宠物空气净化器小米、希喂、352对比实测
人工智能·宠物
AI完全体2 小时前
AI小项目4-用Pytorch从头实现Transformer(详细注解)
人工智能·pytorch·深度学习·机器学习·语言模型·transformer·注意力机制
AI知识分享官2 小时前
智能绘画Midjourney AIGC在设计领域中的应用
人工智能·深度学习·语言模型·chatgpt·aigc·midjourney·llama