本文的目的为给K230视觉检测模块使用色块识别算法检测小型目标(如激光等)提供优化方案

硬件准备

K230视觉识别模块,普通的激光模块

软件讲解

K230官方示例里的色块识别代码可用于识别无明显色差的大型色块,但完全无法检测到小型目标,由此我将提供一份方案用于解决这个问题

从图中可以看到墙上的小型激光虽然是红色的,但是完全识别不到

优化代码后,可以看到有个非常小的红框准确找到了原本激光的位置,就算快速移动激光也能被准确识别

其实只需要改官方示例的这一块代码

上面的thressholds是自定义的颜色阈值,阈值可以在CanMV IDE内置的功能里进行调节

以下是基于官方示例修改的识别函数,主要优化包括:降低识别阈值参数、合并碎片区域以及过滤小斑块功能

thresholds = [(88, 100, -8, 13, 0, 14)]

blobs = img.find_blobs([thresholds[0]],
                       merge=True,
                       pixels_threshold=10,
                       area_threshold=10)

阈值调节

选择阈值编辑器,然后选择帧缓冲区

首先点击重置滑块,调节L最小值至激光不再缩小的临界点,其他参数同理。无需调整无关目标,只需确保待识别对象刚好保持不变形即可。最后将下方LAB阈值复制并粘贴到代码的thressholds中

完整代码

包括了一些优化的代码和识别目标并将目标坐标十六进制后发送到串口2的功能

import time
from media.sensor import *
from media.display import *
from media.media import *
from machine import UART, FPIOA

fpioa = FPIOA()
# 根据你的连线,把 TXD/RXD 分配到相应的 FPIOA 引脚
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
uart = UART(UART.UART2, 115200)
# 调低 L_min,从 30 改为 20,更容易捕捉暗点
thresholds = [(88, 100, -8, 13, 0, 14)]

last_send_ms = time.ticks_ms()
# 记录上次发送的时间戳
sensor = Sensor()
sensor.reset()
sensor.set_framesize(width=800, height=480)
sensor.set_pixformat(Sensor.RGB565)
Display.init(Display.ST7701, width=800, height=480, to_ide=True)
MediaManager.init()
sensor.run()

clock = time.clock()
while True:
    clock.tick()
    img = sensor.snapshot()
    # 可选:简单伽马矫正提亮中间调
    lut = [min(255, int((i/255.0)**1.3 * 255)) for i in range(256)]
    img.gamma_corr(1.3)
    # 只检测红色,merge 合并碎片,过滤小斑块
    blobs = img.find_blobs([thresholds[0]],
                           merge=True,
                           pixels_threshold=10,
                           area_threshold=10)
    if blobs:
        b = max(blobs, key=lambda x: x[4])
        # 按像素数选最大
        x, y, w, h, _, cx, cy = b[0], b[1], b[2], b[3], b[4], b[5], b[6]
        img.draw_rectangle((x, y, w, h), thickness=2, color=(255,0,0),fill = False)
        #img.draw_cross(cx, cy, size=10, thickness=2, color=(255,0,0))

        lbx =  cx        & 0xFF  # X 低字节
        hbx = (cx >> 8)  & 0xFF  # X 高字节
        lby =  cy        & 0xFF  # Y 低字节
        hby = (cy >> 8)  & 0xFF  # Y 高字节
        packet = bytearray([0xE8, lbx, hbx, lby, hby])
        uart.write(packet)
        print(packet)

    else:
        # 未检测到红色块,发送空包 [0xE8, 0, 0, 0]
        uart.write(bytearray([0xE8, 0,0,0,0]))
        print(bytearray([0xE8, 0, 0]))

    Display.show_image(img)

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐