[MCU] 【嘉楠科技 CanMV K230测评】应用项目——寻找最大色块,并使用串口返回

王嘉辉   2024-11-17 09:33 楼主
import time, os, sys

from machine import UART
from machine import FPIOA
from media.sensor import * #导入sensor模块,使用摄像头相关接口
from media.display import * #导入display模块,使用display相关接口
from media.media import * #导入media模块,使用meida相关接口

# 颜色识别阈值 (L Min, L Max, A Min, A Max, B Min, B Max) LAB模型
# 下面的阈值元组是用来识别 红、绿、蓝三种颜色,当然你也可以调整让识别变得更好。
thresholds = [(15, 85, 31, 72, -28, 92),  # 红色阈值
              (30, 100, -64, -8, 50, 70),   # 橙色阈值
              (37, 100, -56, 67, -92, 91),   # 黑色阈值
              (47, 100, -128, 127, -45, 89)]   # 蓝色阈值

colors1 = [(255,0,0), (255,165,0), (0,0,255)]
colors2 = ["Red","Orange","Blue"]
fpioa = FPIOA()

fpioa.set_function(11,FPIOA.UART2_TXD)
fpioa.set_function(12,FPIOA.UART2_RXD)

uart = UART(UART.UART2,115200)

#寻找最大色块函数
def find_max(blobs):
    max_size=0
    for blob in blobs:
        if blob.pixels() > max_size:
            max_blob=blob
            max_size = blob.pixels()
    return max_blob

try:

    sensor = Sensor() #构建摄像头对象
    sensor.reset() #复位和初始化摄像头

    sensor.set_framesize(Sensor.FHD) #设置帧大小FHD(1920x1080),缓冲区和HDMI用,默认通道0
    sensor.set_framesize(width=400,height=240) #设置帧大小800x480,LCD专用,默认通道0
    sensor.set_pixformat(Sensor.RGB565) #设置输出图像格式,默认通道0
#   Display.init(Display.VIRT, sensor.width(), sensor.height()) #只使用IDE缓冲区显示图像
    Display.init(Display.ST7701, to_ide=True) #通过01Studio 3.5寸mipi显示屏显示图像

    MediaManager.init() #初始化media资源管理器

    sensor.run() #启动sensor

    clock = time.clock()

    while True:

        os.exitpoint() #检测IDE中断
        ################
        ## 这里编写代码 ##
        ################
        clock.tick()

        img = sensor.snapshot() #拍摄一张图片
        blobs = img.find_blobs([thresholds[0]]) # 0,1,2分别表示红,绿,蓝色。
        if blobs:
            for b in blobs: #画矩形和箭头表示、
                b = find_max(blobs)
                tmp = img.draw_rectangle(b[0:4],thickness = 4, color=(255,255,255),fill = False)
                tmp = img.draw_cross(b[5], b[6], thickness = 4)
                x256 =b.cx()//256
                x = b.cx()%256
                y =b.cy()
                pixels256 = b.pixels()//256
                pixels = b.pixels()
                Txdata = bytearray([0xa3,0xb3,x256,x,y,1,pixels256,pixels,0xc3])
                uart.write(Txdata)
                print(b.cx(),b.cy(),b.pixels())

                #目前判断车是否距离球体 的 想法:
                #对象的像素数量是否大于某一阈值、对象的质心坐标是否位于一帧图像的中点附近、
        else:

            x = 260
            y = 180
            x256 =y//256
            pixels = 0
            pixels256 = pixels
            Txdata = bytearray([0xa3,0xb3,x256,x,y,0,pixels256,pixels,0xc3])
            uart.write(Txdata)

        img.draw_string_advanced(0, 0, 30, 'FPS: '+str("%.3f"%(clock.fps())), color = (255, 255, 255))

        Display.show_image(img) #显示图片

        #print(clock.fps()) #打印FPS


###################
# IDE中断释放资源代码
###################
except KeyboardInterrupt as e:
    print("user stop: ", e)
except BaseException as e:
    print(f"Exception {e}")
finally:
    # sensor stop run
    if isinstance(sensor, Sensor):
        sensor.stop()
    # deinit display
    Display.deinit()
    os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
    time.sleep_ms(100)
    # release media buffer
    MediaManager.deinit()

使用寻找色块的程序,在其基础上进行更改。实现寻找图片中最大的色块,并通过串口返回给其他单片机,控制小车及云台进行追球。上面是工程的完整代码。

def find_max(blobs):
    max_size=0
    for blob in blobs:
        if blob.pixels() > max_size:
            max_blob=blob
            max_size = blob.pixels()
    return max_blob

这个是寻找最大色块的代码。首先轮询检测到的所有blobs,提取其中的pixels参数,进行找最大值的处理,并最终返回找到的最大值。

if blobs:
            for b in blobs: #画矩形和箭头表示、
                b = find_max(blobs)
                tmp = img.draw_rectangle(b[0:4],thickness = 4, color=(255,255,255),fill = False)
                tmp = img.draw_cross(b[5], b[6], thickness = 4)
                x256 =b.cx()//256
                x = b.cx()%256
                y =b.cy()
                pixels256 = b.pixels()//256
                pixels = b.pixels()
                Txdata = bytearray([0xa3,0xb3,x256,x,y,1,pixels256,pixels,0xc3])
                uart.write(Txdata)
                print(b.cx(),b.cy(),b.pixels())

                #目前判断车是否距离球体 的 想法:
                #对象的像素数量是否大于某一阈值、对象的质心坐标是否位于一帧图像的中点附近、
        else:

            x = 260
            y = 180
            x256 =y//256
            pixels = 0
            pixels256 = pixels
            Txdata = bytearray([0xa3,0xb3,x256,x,y,0,pixels256,pixels,0xc3])
            uart.write(Txdata)

这里是通过串口发送的代码。

首先是对数据进行一下处理,来获取色块的横纵坐标,以及像素点大小。然后调用串口将采集的数据发送出去。同时在前面加上帧头,在后面加上帧尾。

如果没有检测到,就会返回一组默认值。

回复评论 (2)

寻找最大色块,如果没有检测到,就会返回一组默认值,是这个效果

点赞 (1) 2024-11-18 07:35
引用: Jacktang 发表于 2024-11-18 07:35 寻找最大色块,如果没有检测到,就会返回一组默认值,是这个效果

是的,如果返回默认值的话,串口那边接收到(用的是32),就会控制云台和电机左右转动,来找,要是能找到的话,会再次进行定位。

点赞  2024-11-18 09:19
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复