驴友花雕 发表于 5 天前

【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数



什么是 CanMV K230?
CanMV K230是一款高性价比的RISC-V边缘AI平台,凭借低功耗、强视觉处理能力和开放的开发生态,成为嵌入式AI开发的理想选择,尤其适合需要快速部署视觉与AI功能的创客、中小企业及教育场景。CanMV 是一套 AI 视觉开发平台,K230 是其核心芯片。该模块结合了图像采集、AI推理、边缘计算等能力,适合嵌入式视觉应用开发。

CanMV:类似 OpenMV 的图像处理框架,支持 Python 编程,简化视觉识别开发流程。
K230 芯片:嘉楠科技推出的 AIoT SoC,采用 RISC-V 架构,内置第三代 KPU(AI加速单元),算力高达 6 TOPS,性能是 K210 的 13.7 倍。



驴友花雕 发表于 3 天前

【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数

知识点
物体计数(Object Counting)指利用传感器或计算机视觉技术,对图像、视频或真实场景中“有多少个目标”进行自动统计的过程。是计算机视觉领域的一项重要任务,旨在确定图像或视频中特定物体的数量。以下是一些常见的物体计数方法:

1、基于检测的计数方法:该方法依赖于能够定位图像中物体实例的视觉检测器。先使用目标检测算法,如 YOLO、Faster R-CNN 等,对图像中的物体进行检测,每个检测框对应一个物体,然后统计检测框的数量,从而得到物体的计数结果。这种方法的优点是直观且对于单个物体检测精度较高,但需要为不同的物体训练单独的检测器,并且在标注数据稀少的情况下,检测效果可能会受到影响。

2、基于回归的计数方法:这类方法旨在学习从全局图像特征到一个标量(即物体数量)的映射,或者从密集图像特征到密度图的映射。例如,通过训练一个神经网络,输入整幅图像,输出图像中物体的数量。它避免了解决复杂的检测问题,在计数高度重叠的实例上可能取得更好的效果,但缺点是缺乏对物体具体位置的定位信息。

3、基于聚类的计数方法:对于一些没有明显物体边界的情况,如细胞计数等,可以采用聚类的方法。首先提取图像中物体的特征,然后根据这些特征将相似的物体聚合成不同的类,每个类代表一个物体,最后统计类的数量得到物体计数。
通用匹配网络(GMN)计数方法:这是一种能够以类别无关的方式计数任何物体的模型架构。它将计数问题重新定义为匹配问题,利用计数任务中天然存在的图像自相似性特性,通过在同一张图像内匹配与示例块相似的 patches 来进行计数。GMN 可以充分利用大量为视频目标追踪标注的数据进行训练,并且引入了适配器模块,只需使用少量标注示例,就能对模型进行专业化微调,实现少样本学习。









驴友花雕 发表于 3 天前

【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数










驴友花雕 发表于 3 天前

【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数

【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数
项目测试实验代码

#【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数

import time
import os
import sys
from media.sensor import Sensor
from media.display import Display
from media.media import MediaManager

# 常量定义 / Constants definition
SCREEN_WIDTH = 640    # 屏幕宽度 / Screen width
SCREEN_HEIGHT = 480   # 屏幕高度 / Screen height

# 待检测物体的LAB色彩空间阈值 / LAB color space thresholds
# 这里写的阈值是配套工具中【金币生成器】生成的金币的颜色
# Format: (L_min, L_max, A_min, A_max, B_min, B_max)
TRACK_THRESHOLD = [(0, 100, -7, 127, 10, 83)]
# 这个阈值范围专门针对金币生成器产生的金币颜色进行优化
# 参数说明:
# L: 亮度 (0-100),这里范围很宽,适应不同光照条件
# A: 红绿色度 (-128到127),-7到127表示偏红色
# B: 黄蓝色度 (-128到127),10到83表示偏黄色

# 文字显示参数 / Text display parameters
FONT_SIZE = 25                  # 字体大小 / Font size
TEXT_COLOR = (233, 233, 233)   # 白色 / White (接近纯白的浅灰色)

def init_camera():
    """
    初始化并配置摄像头
    Initialize and configure the camera
   
    返回:
      sensor: 初始化后的传感器对象 / Initialized sensor object
    """
    # sensor = Sensor(width=1280,height=960)# 备用高分辨率配置
    sensor = Sensor()            # 创建传感器实例
    sensor.reset()               # 重置传感器到默认状态
    # 设置图像分辨率为640x480 / Set image resolution to 640x480
    sensor.set_framesize(width=SCREEN_WIDTH, height=SCREEN_HEIGHT)
    # 设置像素格式为RGB565 / Set pixel format to RGB565 (16位彩色)
    sensor.set_pixformat(Sensor.RGB565)
    return sensor

def init_display():
    """
    初始化显示设备
    Initialize display device
    """
    # 初始化3.5寸MIPI屏幕和IDE显示
    # Initialize 3.5-inch MIPI screen and IDE display
    # ST7701: 显示屏驱动芯片型号
    # to_ide=True: 同时输出到IDE,便于调试
    Display.init(Display.ST7701, width=SCREEN_WIDTH, height=SCREEN_HEIGHT, to_ide=True)
    # 初始化媒体管理器,分配图像处理资源
    MediaManager.init()

def process_frame(img, threshold):
    """
    处理单帧图像,检测并标记目标物体
    Process single frame, detect and mark target objects

    Args:
      img: 输入图像 / Input image
      threshold: 颜色阈值 / Color threshold

    Returns:
      blobs: 检测到的物体列表 / List of detected objects
    """
    # 在图像中查找符合颜色阈值的色块
    # find_blobs函数返回满足条件的连通区域列表
    blobs = img.find_blobs()
    # 默认参数:自动合并相邻色块,无最小面积限制

    # 如果检测到色块,进行可视化标记
    if blobs:
      for blob in blobs:
            # 绘制矩形框标记物体边界 / Draw rectangle around object boundary
            # blob 包含 (x, y, width, height)
            img.draw_rectangle(blob)
            
            # 在物体中心绘制十字准星 / Draw cross at object center
            # blob, blob 是中心点坐标 (cx, cy)
            img.draw_cross(blob, blob)

    return blobs# 返回检测到的物体列表

def draw_info(img, fps, num_objects):
    """
    在图像上绘制信息
    Draw information on image

    Args:
      img: 输入图像 / Input image
      fps: 帧率 / Frames per second
      num_objects: 检测到的物体数量 / Number of detected objects
    """
    # 构建信息文本字符串
    info_text = f'FPS: {fps:.3f}       Num: {num_objects}'
   
    # 在图像左上角绘制信息文本
    # 参数说明:
    # 0, 0: 文本起始坐标 (x, y)
    # FONT_SIZE: 字体大小
    # info_text: 要显示的文本内容
    # color=TEXT_COLOR: 文本颜色 (白色)
    img.draw_string_advanced(0, 0, FONT_SIZE, info_text, color=TEXT_COLOR)

def main():
    """
    主程序入口
    Main program entry
    """
    # 初始化设备 / Initialize devices
    sensor = init_camera()# 初始化摄像头
    init_display()          # 初始化显示设备
    sensor.run()            # 启动摄像头开始采集图像

    # 创建时钟对象用于FPS计算 / Create clock object for FPS calculation
    clock = time.clock()

    try:
      # 主循环 - 实时物体计数
      while True:
            # 更新时钟,记录当前时间点
            clock.tick()

            # 捕获图像 / Capture image
            img = sensor.snapshot()# 从摄像头获取一帧图像

            # 处理图像,检测目标物体
            # 使用预设的颜色阈值检测金币或其他目标物体
            blobs = process_frame(img, TRACK_THRESHOLD)

            # 在图像上显示帧率和物体数量信息
            draw_info(img, clock.fps(), len(blobs))

            # 显示处理后的图像 / Show image
            Display.show_image(img)

            # 在控制台打印FPS信息,用于性能监控
            print(f"FPS: {clock.fps():.3f}")

    except KeyboardInterrupt:
      # 处理用户中断 (Ctrl+C)
      print("Program terminated by user")
    except Exception as e:
      # 处理其他异常
      print(f"Error occurred: {str(e)}")
    finally:
      # 清理资源 / Cleanup resources (无论是否异常都会执行)
      sensor.deinit()   # 反初始化传感器,释放硬件资源
      Display.deinit()    # 关闭显示设备

# 程序入口点
if __name__ == "__main__":
    main()
代码解读:

程序总体功能
这是一个基于颜色特征的实时物体计数系统,专门用于检测和统计画面中特定颜色(如金币)的物体数量。

系统架构设计
核心处理流程
text
图像采集 → 颜色空间转换 → 阈值分割 → 连通域分析 → 物体标记 → 数量统计 → 结果显示
1. 模块化架构
python
# 硬件抽象层

from media.sensor import Sensor      # 摄像头硬件控制

from media.display import Display    # 显示输出控制

from media.media import MediaManager # 媒体资源管理



# 应用逻辑层

init_camera()    # 摄像头初始化

init_display()   # 显示初始化

process_frame()# 图像处理核心

draw_info()      # 信息可视化
核心技术组件详解
1. LAB颜色空间检测系统
颜色阈值设计
python
TRACK_THRESHOLD = [(0, 100, -7, 127, 10, 83)]
LAB颜色空间参数分析:
L通道 (亮度): 0-100
覆盖全部亮度范围,适应各种光照条件
从完全黑暗到最亮都能检测
A通道 (红-绿): -7 到 127
负值偏绿,正值偏红
-7 起点略偏红,127 强红色调
B通道 (黄-蓝): 10 到 83
负值偏蓝,正值偏黄
10-83 明确的金黄色调范围

阈值设计策略:
宽范围的L值确保光照鲁棒性
A、B通道精确锁定金黄色特征
专门针对"金币生成器"工具优化

2. 色块检测引擎
核心检测算法
python
blobs = img.find_blobs()
算法内部工作机制:
颜色空间转换: RGB → LAB(自动处理)
阈值分割: 根据LAB范围创建二值掩膜
连通域标记: 识别相连的像素区域
特征提取: 计算每个区域的位置、大小、中心点
色块数据结构
python
blob =

# x, y: 边界框左上角坐标

# width, height: 边界框尺寸

# cx, cy: 区域中心点坐标
3. 可视化系统
物体标记策略
python
img.draw_rectangle(blob)      # 边界框

img.draw_cross(blob, blob)   # 中心十字
视觉设计原理:
矩形框: 快速识别物体空间范围
十字准星: 精确定位物体中心
默认颜色: 自动选择高对比度颜色,确保可见性
信息显示设计
python
info_text = f'FPS: {fps:.3f}       Num: {num_objects}'
信息层级:
性能指标: 帧率(3位小数精度)
业务数据: 物体数量(实时更新)
布局优化: 左上角固定位置,避免遮挡主要内容

性能优化分析
1. 分辨率策略
python
SCREEN_WIDTH = 640

SCREEN_HEIGHT = 480# 307,200像素
性能权衡分析:
计算复杂度: 相比1280×960(1,228,800像素)减少75%
检测精度: 480p分辨率对物体计数足够精确
实时性: 确保在高帧率下稳定运行

2. 算法效率优化
python
# 默认参数优化

blobs = img.find_blobs()

# 等效于:

# blobs = img.find_blobs(, merge=True, area_threshold=0, pixels_threshold=0)
参数默认值优势:
merge=True: 自动合并相邻区域,减少碎片化
无面积限制: 检测所有大小的目标
简化配置: 用户只需关注颜色阈值

3. 实时性能监控
python
clock = time.clock()

clock.tick()    # 记录时间点

fps = clock.fps() # 计算帧率
监控机制:
高精度计时: 微秒级时间测量
持续跟踪: 每帧更新性能数据
双重输出: 屏幕显示 + 控制台日志

系统工作流程
完整处理流水线
text
1. 硬件初始化
   ↓
2. 图像采集 (sensor.snapshot())
   ↓
3. 颜色空间转换 (RGB→LAB)
   ↓
4. 阈值分割 (LAB范围过滤)
   ↓
5. 连通域分析 (区域标记)
   ↓
6. 特征计算 (位置、大小、中心)
   ↓
7. 可视化渲染 (边框 + 十字)
   ↓
8. 信息叠加 (帧率 + 计数)
   ↓
9. 结果显示 (Display.show_image)
物体计数逻辑
python
# 检测阶段

blobs = img.find_blobs()



# 统计阶段

object_count = len(blobs)# 直接使用列表长度作为计数



# 显示阶段

draw_info(img, fps, object_count)
健壮性设计
异常处理机制
python
try:

    # 主业务逻辑

    while True:

      # 实时处理循环

except KeyboardInterrupt:

    # 用户主动中断

    print("Program terminated by user")

except Exception as e:

    # 其他异常捕获

    print(f"Error occurred: {str(e)}")

finally:

    # 资源清理保障

    sensor.deinit()

    Display.deinit()

驴友花雕 发表于 3 天前

【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数

实际测试的范本



实验串口返回情况



实验场景图








页: [1]
查看完整版本: 【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数