K230基础-特征检测
第十七章 特征检测-K230 视觉系统的“眼睛”与“大脑”连接
🎯 本章目标:
掌握在 K230(CanMV 平台)上使用 传统图像处理方法 实现特征检测,包括 颜色识别、边缘检测、轮廓提取、直线检测、二维码识别、人脸检测(Haar) 等,为不依赖深度学习模型的轻量级视觉应用提供完整解决方案。
1. 什么是特征检测?
特征检测(Feature Detection) 是从图像中提取有意义信息的过程,如:
- 颜色、形状、边缘、角点、纹理
- 特定图案(二维码、条形码)
- 人脸、数字、字符
✅ 用途:
- 机器人循迹(颜色/边缘)
- 工业检测(缺陷、位置)
- 人机交互(手势、人脸)
- 自主导航(标志识别)
2. 颜色特征检测
2.1 基于阈值的颜色识别
import sensor
import imagesensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time=2000)# 定义颜色阈值(LUV 或 RGB)
# 格式: (L_min, L_max, A_min, A_max, B_min, B_max)
red_threshold = (30, 100, 15, 127, 15, 127) # 红色(LUV)
blue_threshold = (0, 30, -128, -20, -128, -40) # 蓝色while True:img = sensor.snapshot()# 查找颜色块blobs = img.find_blobs([red_threshold], pixels_threshold=100, area_threshold=100)for b in blobs:# 绘制矩形框img.draw_rectangle(b.rect(), color=(255, 0, 0))# 绘制中心点img.draw_cross(b.cx(), b.cy(), color=(0, 255, 0))# 打印信息print(f"红色块: x={b.cx()}, y={b.cy()}, 面积={b.pixels()}")
🔧 调试建议:
- 使用
img.get_statistics()
获取某区域颜色值- 在 PC 上用 OpenMV IDE 调参
2.2 多颜色识别
thresholds = [(30, 100, 15, 127, 15, 127), # 红(30, 100, -64, -8, -32, 32), # 绿(0, 30, -128, -20, -128, -40) # 蓝
]blobs = img.find_blobs(thresholds, merge=True)
merge=True
:合并相邻颜色块- 可用于识别彩色标签、RGB 灯状态
3. 轮廓与边缘特征
3.1 边缘检测(Canny)
img.to_grayscale()
img.find_edges(image.EDGE_CANNY, threshold=(50, 80))
✅ 用途:提取物体轮廓、文档边界
3.2 轮廓提取:find_contours()
# 二值化后提取轮廓
img.binary([(128, 255)])
contours = img.find_contours(threshold=50)for c in contours:img.draw_line(c, color=(255, 0, 0)) # 绘制轮廓线print(f"轮廓点数: {len(c)}")
✅ 用途:形状识别、路径规划
4. 几何形状特征
4.1 寻找矩形:find_rects()
# 寻找矩形(基于轮廓)
rects = img.find_rects(threshold=10000)for r in rects:img.draw_rectangle(r.rect(), color=(0, 255, 0))print(f"矩形角点: {list(r.corners())}")
✅ 用途:识别二维码框、标定板、门框
4.2 寻找圆:find_circles()
# 仅适用于清晰圆形
circles = img.find_circles(threshold=2000, x_margin=10, y_margin=10, r_margin=10)for c in circles:img.draw_circle(int(c.x()), int(c.y()), int(c.r()), color=(0, 0, 255))print(f"圆心: ({c.x()}, {c.y()}), 半径: {c.r()}")
⚠️ 限制:对模糊、遮挡的圆检测效果差
5. 直线特征检测:find_lines()
# 边缘检测 + 直线提取
img.to_grayscale()
edges = img.find_edges(image.EDGE_CANNY, threshold=(50, 80))
lines = img.find_lines(threshold=1000)for l in lines:img.draw_line(l.line(), color=(255, 255, 0))print(f"直线: [{l.x1()}, {l.y1()}] → [{l.x2()}, {l.y2()}], 角度={l.theta()}")
✅ 用途:
- 机器人循迹(检测黑线)
- 建筑结构分析
- 文档倾斜校正
6. 二维码与条形码识别
6.1 二维码识别:find_qrcodes()
import imagewhile True:img = sensor.snapshot()# 直接识别二维码(无需预处理)codes = img.find_qrcodes()for code in codes:img.draw_rectangle(code.rect(), color=(0, 255, 0))img.draw_string(10, 10, code.payload(), color=(255, 255, 255))print("二维码内容:", code.payload())
✅ 支持:QR Code、Data Matrix、Aztec 等(依固件而定)
6.2 条形码识别:find_barcodes()
codes = img.find_barcodes()for code in codes:img.draw_rectangle(code.rect(), color=(255, 0, 0))print("条形码:", code.payload())print("类型:", code.type())
📌 常见类型:EAN13、UPC、CODE128
7. 人脸检测(Haar 级联)
7.1 使用内置 Haar 特征检测
# Haar 检测需要灰度图
sensor.set_pixformat(sensor.GRAYSCALE)# 加载 Haar 分类器(需提前烧录)
face_cascade = image.HaarCascade("frontalface", stages=25)while True:img = sensor.snapshot()# 检测人脸objects = img.find_features(face_cascade, threshold=0.7, scale_factor=1.25)for r in objects:img.draw_rectangle(r, color=(255, 0, 0))print(f"人脸: x={r[0]}, y={r[1]}, w={r[2]}, h={r[3]}")
✅ 优点:无需 KPU 模型,纯软件实现
❌ 缺点:速度慢,精度低于 CNN
8. 特征检测综合项目:智能分拣系统
# 场景:识别不同颜色和形状的物体thresholds = [(30, 100, 15, 127, 15, 127, 0, 100), # 红色(30, 100, -64, -8, -32, 32, 0, 100), # 绿色(0, 30, -128, -20, -128, -40, 0, 100) # 蓝色
]while True:img = sensor.snapshot()blobs = img.find_blobs(thresholds, pixels_threshold=200, merge=True)for b in blobs:x, y, w, h = b.rect()# 判断形状aspect_ratio = w / hif 0.8 < aspect_ratio < 1.2:shape = "Square"elif aspect_ratio > 1.5:shape = "Rectangle"else:shape = "Other"# 标记color_name = ["Red", "Green", "Blue"][b.code()-1]label = f"{color_name} {shape}"img.draw_rectangle(b.rect(), color=(255, 255, 255))img.draw_string(x, y-10, label, color=(255, 0, 0))print(f"检测: {label} @ ({b.cx()}, {b.cy()})")
9. 高级技巧与优化
9.1 ROI(感兴趣区域)检测
roi = (80, 60, 160, 120) # 只检测中间区域
blobs = img.find_blobs(thresholds, roi=roi)
✅ 优势:提升速度,减少误检
9.2 多级检测策略
# 1. 快速检测(低分辨率)
sensor.set_framesize(sensor.QQVGA)
blobs = img.find_blobs([...])# 2. 精细检测(高分辨率 ROI)
if blobs:sensor.set_framesize(sensor.QVGA)# 对目标区域放大检测
9.3 特征融合
# 颜色 + 形状 + 二维码
if qr := img.find_qrcodes():# 优先处理二维码
elif blobs := img.find_blobs():# 处理颜色块
elif faces := img.find_features():# 处理人脸
10. 常见问题与调试
❌ 问题1:find_blobs()
检测不到
排查:
- 是否为 RGB 图像?
- 阈值是否匹配目标颜色?
- 是否未调用
to_grayscale()
影响其他检测?
❌ 问题2:find_lines()
效果差
解决:
- 先
find_edges()
提取边缘- 调整
threshold
参数- 确保光照均匀
❌ 问题3:Haar 人脸检测卡顿
优化:
- 使用
QQVGA
分辨率- 降低
scale_factor
(如 1.3)- 限制检测区域
11. 性能与适用场景
方法 | 速度(QQVGA) | 适用场景 |
---|---|---|
find_blobs | ~10ms | 颜色识别、物体跟踪 |
find_lines | ~8ms | 循迹、结构分析 |
find_qrcodes | ~15ms | 信息读取 |
find_features (Haar) | 人脸检测(低帧率) |
✅ 建议:
- 实时性要求高:使用
find_blobs
/find_lines
- 精度要求高:使用 KPU 深度学习模型
- 混合系统:传统方法 + AI 融合