【花雕动手做】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 倍。
【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数
知识点物体计数(Object Counting)指利用传感器或计算机视觉技术,对图像、视频或真实场景中“有多少个目标”进行自动统计的过程。是计算机视觉领域的一项重要任务,旨在确定图像或视频中特定物体的数量。以下是一些常见的物体计数方法:
1、基于检测的计数方法:该方法依赖于能够定位图像中物体实例的视觉检测器。先使用目标检测算法,如 YOLO、Faster R-CNN 等,对图像中的物体进行检测,每个检测框对应一个物体,然后统计检测框的数量,从而得到物体的计数结果。这种方法的优点是直观且对于单个物体检测精度较高,但需要为不同的物体训练单独的检测器,并且在标注数据稀少的情况下,检测效果可能会受到影响。
2、基于回归的计数方法:这类方法旨在学习从全局图像特征到一个标量(即物体数量)的映射,或者从密集图像特征到密度图的映射。例如,通过训练一个神经网络,输入整幅图像,输出图像中物体的数量。它避免了解决复杂的检测问题,在计数高度重叠的实例上可能取得更好的效果,但缺点是缺乏对物体具体位置的定位信息。
3、基于聚类的计数方法:对于一些没有明显物体边界的情况,如细胞计数等,可以采用聚类的方法。首先提取图像中物体的特征,然后根据这些特征将相似的物体聚合成不同的类,每个类代表一个物体,最后统计类的数量得到物体计数。
通用匹配网络(GMN)计数方法:这是一种能够以类别无关的方式计数任何物体的模型架构。它将计数问题重新定义为匹配问题,利用计数任务中天然存在的图像自相似性特性,通过在同一张图像内匹配与示例块相似的 patches 来进行计数。GMN 可以充分利用大量为视频目标追踪标注的数据进行训练,并且引入了适配器模块,只需使用少量标注示例,就能对模型进行专业化微调,实现少样本学习。
【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数
【花雕动手做】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()
【花雕动手做】CanMV K230 AI 视觉识别模块之物体计数
实际测试的范本实验串口返回情况
实验场景图
页:
[1]