王嘉辉 发表于 2024-11-17 09:33

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

<pre>
<code class="language-python">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() &gt; 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(]) # 0,1,2分别表示红,绿,蓝色。
      if blobs:
            for b in blobs: #画矩形和箭头表示、
                b = find_max(blobs)
                tmp = img.draw_rectangle(b,thickness = 4, color=(255,255,255),fill = False)
                tmp = img.draw_cross(b, b, thickness = 4)
                x256 =b.cx()//256
                x = b.cx()%256
                y =b.cy()
                pixels256 = b.pixels()//256
                pixels = b.pixels()
                Txdata = bytearray()
                uart.write(Txdata)
                print(b.cx(),b.cy(),b.pixels())

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

            x = 260
            y = 180
            x256 =y//256
            pixels = 0
            pixels256 = pixels
            Txdata = bytearray()
            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()
</code></pre>

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

<pre>
<code class="language-python">def find_max(blobs):
    max_size=0
    for blob in blobs:
      if blob.pixels() &gt; max_size:
            max_blob=blob
            max_size = blob.pixels()
    return max_blob</code></pre>

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

<pre>
<code class="language-python">if blobs:
            for b in blobs: #画矩形和箭头表示、
                b = find_max(blobs)
                tmp = img.draw_rectangle(b,thickness = 4, color=(255,255,255),fill = False)
                tmp = img.draw_cross(b, b, thickness = 4)
                x256 =b.cx()//256
                x = b.cx()%256
                y =b.cy()
                pixels256 = b.pixels()//256
                pixels = b.pixels()
                Txdata = bytearray()
                uart.write(Txdata)
                print(b.cx(),b.cy(),b.pixels())

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

            x = 260
            y = 180
            x256 =y//256
            pixels = 0
            pixels256 = pixels
            Txdata = bytearray()
            uart.write(Txdata)</code></pre>

<p>这里是通过串口发送的代码。</p>

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

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

Jacktang 发表于 2024-11-18 07:35

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

王嘉辉 发表于 2024-11-18 09:19

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

<p>是的,如果返回默认值的话,串口那边接收到(用的是32),就会控制云台和电机左右转动,来找,要是能找到的话,会再次进行定位。</p>
页: [1]
查看完整版本: 【嘉楠科技 CanMV K230测评】应用项目——寻找最大色块,并使用串口返回