6浏览
查看: 6|回复: 4

[项目] 【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测

[复制链接]
【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图2

什么是 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 视觉识别模块之圆形检测图1

驴友花雕  高级技神
 楼主|

发表于 3 小时前

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测

知识点
圆形检测是计算机视觉中基于几何特征的经典任务,核心是从图像中识别满足 “所有点到圆心距离相等” 特征的圆形区域(如零件孔洞、镜头、交通灯、硬币等),主流依赖霍夫变换或轮廓分析,适配不同精度和实时性需求。

1、核心原理
圆形的几何特征由 “圆心 (x0,y0)” 和 “半径 r” 定义,检测本质是在图像中搜索满足该特征的像素集合,主流实现路径有两种:
霍夫圆变换:将图像空间的圆形映射到参数空间(x0,y0,r),通过累加器计数找到峰值,对应真实圆形(OpenCV 中常用改进版 “霍夫梯度法”,先找圆心再算半径,提升效率)。
轮廓拟合:提取图像轮廓后,计算轮廓的最小外接圆或通过圆度(轮廓面积 / 最小外接圆面积)筛选圆形(圆度越接近 1,越可能是标准圆)。

2、主流算法(按效率和场景分类)

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图1

3、实操示例(OpenCV 霍夫梯度法实现)
适合标准圆形检测,适配多数场景,可直接替换为 K230 摄像头采集帧:
python
  1. import cv2
  2. import numpy as np
  3. # 读取图像(可替换为K230摄像头实时帧)
  4. img = cv2.imread("coins.jpg")
  5. img_copy = img.copy()
  6. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  7. # 图像预处理:降噪(关键!霍夫变换对噪声敏感)
  8. blur = cv2.GaussianBlur(gray, (9, 9), 2)  # 大核高斯模糊,增强降噪效果
  9. # 霍夫圆检测(核心参数需根据图像调整)
  10. circles = cv2.HoughCircles(
  11.     blur,
  12.     cv2.HOUGH_GRADIENT,  # 霍夫梯度法
  13.     dp=1.2,  # 累加器分辨率与图像分辨率的比值(越大越慢,精度越高)
  14.     minDist=50,  # 两个圆心的最小距离(避免重复检测)
  15.     param1=50,  # Canny边缘检测的高阈值(低阈值为其一半)
  16.     param2=30,  # 累加器阈值(越小检测越多,需过滤假圆)
  17.     minRadius=20,  # 最小圆半径
  18.     maxRadius=100  # 最大圆半径
  19. )
  20. # 绘制检测结果
  21. if circles is not None:
  22.     circles = np.uint16(np.around(circles))  # 转换为整数坐标
  23.     for i in circles[0, :]:
  24.         # 绘制圆心(蓝色)
  25.         cv2.circle(img_copy, (i[0], i[1]), 3, (255, 0, 0), -1)
  26.         # 绘制圆轮廓(红色,厚度2)
  27.         cv2.circle(img_copy, (i[0], i[1]), i[2], (0, 0, 255), 2)
  28.         # 标注半径
  29.         cv2.putText(img_copy, f"r={i[2]}", (i[0], i[1]-10),
  30.                     cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
  31. # 显示结果
  32. cv2.imshow("Circle Detection", img_copy)
  33. cv2.waitKey(0)
  34. cv2.destroyAllWindows()
复制代码

4、关键优化技巧(提升检测准确率)
预处理强化:
降噪优先:用大核高斯模糊(如 (9,9)、(11,11))或中值滤波,抑制噪声导致的假圆。
增强对比度:对暗图像用直方图均衡化,突出圆形边缘;对复杂背景用阈值分割(如二值化),分离前景圆形。
参数调优(霍夫变换核心):
dp:设为 1.2~1.5,平衡速度和精度;minDist 大于圆形直径的 1/2,避免重复检测。
param2:根据图像调整(30~50),值越大检测越严格,假圆越少但可能漏检小圆。
minRadius/maxRadius:根据目标圆形尺寸范围设置,过滤超出范围的噪声圆。
后处理筛选:
圆度验证:对检测到的圆,提取其轮廓计算圆度(需先通过圆心和半径裁剪轮廓),圆度<0.8 则过滤(非标准圆)。
面积过滤:计算圆形区域的实际面积,与理论面积(πr²)偏差过大则剔除(如椭圆、不规则图形)。
边缘设备适配:
K230 平台:先用 NPU 加速高斯模糊和 Canny 边缘检测,再用 CPU 运行霍夫变换,降低延迟;或部署轻量化深度学习模型(如 MobileNet + 圆回归),单帧处理延迟可控制在 80ms 内。

5、典型应用场景
工业质检:检测零件的圆形孔洞(如螺丝孔、轴承内圈)是否合格(半径是否达标、是否偏心)。
智能交通:识别交通灯、圆形交通标志(如禁止通行标志)。
机器人视觉:定位圆形物体(如瓶盖、球体),规划抓取路径。
医疗影像:提取 CT/MRI 图像中的圆形病灶(如肿瘤、血管截面)。

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图3

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图2

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图4

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 3 小时前

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图2

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图1

3、实操示例(OpenCV 霍夫梯度法实现)
适合标准圆形检测,适配多数场景,可直接替换为 K230 摄像头采集帧:
python

  1. import cv2
  2. import numpy as np
  3. # 读取图像(可替换为K230摄像头实时帧)
  4. img = cv2.imread("coins.jpg")
  5. img_copy = img.copy()
  6. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  7. # 图像预处理:降噪(关键!霍夫变换对噪声敏感)
  8. blur = cv2.GaussianBlur(gray, (9, 9), 2)  # 大核高斯模糊,增强降噪效果
  9. # 霍夫圆检测(核心参数需根据图像调整)
  10. circles = cv2.HoughCircles(
  11.     blur,
  12.     cv2.HOUGH_GRADIENT,  # 霍夫梯度法
  13.     dp=1.2,  # 累加器分辨率与图像分辨率的比值(越大越慢,精度越高)
  14.     minDist=50,  # 两个圆心的最小距离(避免重复检测)
  15.     param1=50,  # Canny边缘检测的高阈值(低阈值为其一半)
  16.     param2=30,  # 累加器阈值(越小检测越多,需过滤假圆)
  17.     minRadius=20,  # 最小圆半径
  18.     maxRadius=100  # 最大圆半径
  19. )
  20. # 绘制检测结果
  21. if circles is not None:
  22.     circles = np.uint16(np.around(circles))  # 转换为整数坐标
  23.     for i in circles[0, :]:
  24.         # 绘制圆心(蓝色)
  25.         cv2.circle(img_copy, (i[0], i[1]), 3, (255, 0, 0), -1)
  26.         # 绘制圆轮廓(红色,厚度2)
  27.         cv2.circle(img_copy, (i[0], i[1]), i[2], (0, 0, 255), 2)
  28.         # 标注半径
  29.         cv2.putText(img_copy, f"r={i[2]}", (i[0], i[1]-10),
  30.                     cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
  31. # 显示结果
  32. cv2.imshow("Circle Detection", img_copy)
  33. cv2.waitKey(0)
  34. cv2.destroyAllWindows()
复制代码

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图3

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图6

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图4

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图5

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 3 小时前

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测
项目测试实验代码

  1. #【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测
  2. import time, os, sys
  3. from media.sensor import *
  4. from media.display import *
  5. from media.media import *
  6. # 设置图像捕获分辨率 / Set picture capture resolution
  7. PICTURE_WIDTH = 400    # 图像处理宽度(平衡性能与精度)
  8. PICTURE_HEIGHT = 240   # 图像处理高度(平衡性能与精度)
  9. # 显示模式:"VIRT"用于无屏幕情况,"LCD"用于有屏幕情况
  10. # Display mode: "VIRT" for virtual display, "LCD" for physical screen
  11. DISPLAY_MODE = "LCD"   # 当前使用LCD物理屏幕模式
  12. # 根据显示模式设置显示分辨率 / Set display resolution based on mode
  13. if DISPLAY_MODE == "VIRT":
  14.     # 虚拟显示器模式(1920x1080) / Virtual display mode
  15.     DISPLAY_WIDTH = ALIGN_UP(1920, 16)  # 确保宽度16字节对齐 / Ensure width is 16-byte aligned
  16.     DISPLAY_HEIGHT = 1080
  17. elif DISPLAY_MODE == "LCD":
  18.     # LCD物理屏幕模式(640x480) / LCD physical screen mode
  19.     DISPLAY_WIDTH = 640
  20.     DISPLAY_HEIGHT = 480
  21. else:
  22.     raise ValueError("未知的显示模式,请选择 'VIRT' 或 'LCD' / Unknown display mode, please choose 'VIRT' or 'LCD'")
  23. def init_sensor():
  24.     """初始化传感器 / Initialize sensor"""
  25.     sensor = Sensor(id=2)  # 创建传感器实例,ID=2
  26.     sensor.reset()         # 重置传感器到默认状态
  27.     # 设置通道0的帧大小
  28.     sensor.set_framesize(width=PICTURE_WIDTH, height=PICTURE_HEIGHT, chn=CAM_CHN_ID_0)
  29.     # 设置像素格式为RGB565(16位彩色,节省内存)
  30.     sensor.set_pixformat(Sensor.RGB565, chn=CAM_CHN_ID_0)
  31.     return sensor
  32. def init_display():
  33.     """初始化显示器 / Initialize display"""
  34.     if DISPLAY_MODE == "VIRT":
  35.         # 初始化虚拟显示,60FPS刷新率
  36.         Display.init(Display.VIRT, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, fps=60)
  37.     elif DISPLAY_MODE == "LCD":
  38.         # 初始化物理LCD显示,同时输出到IDE便于调试
  39.         Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
  40. def process_circles(img, circles):
  41.     """处理检测到的圆形 / Process detected circles"""
  42.     print("【圆形信息 / Circle Statistics Start】")
  43.     # 遍历所有检测到的圆形
  44.     for i, circle in enumerate(circles):
  45.         # 使用蓝色绘制圆形轮廓 / Draw circles in blue
  46.         # circle.circle(): 返回圆形的(x, y, radius)信息
  47.         # color=(40,167,225): 天蓝色,thickness=3: 3像素线宽
  48.         img.draw_circle(circle.circle(), color=(40,167,225), thickness=3)
  49.         # 打印圆形详细信息(位置、半径等)
  50.         print(f"Circle {i}: {circle}")
  51.     print("【==============================】")
  52. def main():
  53.     try:
  54.         # 初始化设备 / Initialize devices
  55.         sensor = init_sensor()     # 初始化摄像头传感器
  56.         init_display()             # 初始化显示设备
  57.         MediaManager.init()        # 初始化媒体管理器
  58.         sensor.run()               # 启动摄像头采集
  59.         # 计算显示偏移量以居中显示 / Calculate display offsets for center alignment
  60.         # 将400x240图像在640x480屏幕上居中显示
  61.         x_offset = (DISPLAY_WIDTH - PICTURE_WIDTH) // 2   # 水平偏移:(640-400)/2 = 120
  62.         y_offset = (DISPLAY_HEIGHT - PICTURE_HEIGHT) // 2 # 垂直偏移:(480-240)/2 = 120
  63.         # 主循环 - 实时圆形检测
  64.         while True:
  65.             os.exitpoint()  # 检查退出点,响应程序终止信号
  66.             # 捕获图像 / Capture image
  67.             img = sensor.snapshot(chn=CAM_CHN_ID_0)
  68.             # 寻找并处理圆形 / Find and process circles
  69.             # threshold: 控制圆形检测的阈值,更高的值会减少检测到的圆形数量
  70.             # threshold: Controls circle detection sensitivity, higher values reduce the number of detected circles
  71.             # 基于霍夫圆变换算法,threshold=3500表示需要较强的圆形证据
  72.             circles = img.find_circles(threshold=3500)
  73.             process_circles(img, circles)  # 处理并绘制检测到的圆形
  74.             # 居中显示图像 / Display image in center
  75.             Display.show_image(img, x=x_offset, y=y_offset)
  76.     except KeyboardInterrupt as e:
  77.         # 处理用户中断(Ctrl+C)
  78.         print("用户中断 / User interrupted: ", e)
  79.     except Exception as e:
  80.         # 处理其他所有异常
  81.         print(f"发生错误 / Error occurred: {e}")
  82.     finally:
  83.         # 清理资源 / Cleanup resources
  84.         if 'sensor' in locals() and isinstance(sensor, Sensor):
  85.             sensor.stop()          # 停止摄像头采集
  86.         Display.deinit()           # 关闭显示驱动
  87.         os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)  # 启用睡眠模式
  88.         time.sleep_ms(100)         # 短暂延时确保资源完全释放
  89.         MediaManager.deinit()      # 释放媒体资源
  90. if __name__ == "__main__":
  91.     main()  # 程序入口点
复制代码


代码解读
程序总体功能
这是一个基于CanMV K230的实时圆形检测系统,能够在视频流中实时识别图像中的圆形轮廓,并用可视化的方式标记出来。

系统架构设计
核心处理流程
text
摄像头采集(400×240) → 霍夫圆变换检测 → 圆形轮廓绘制 → 居中显示(640×480) → 控制台输出
1. 智能分辨率策略
python
  1. PICTURE_WIDTH = 400    # 处理分辨率
  2. PICTURE_HEIGHT = 240
  3. DISPLAY_WIDTH = 640    # 显示分辨率
  4. DISPLAY_HEIGHT = 480
复制代码

设计理念分析:
处理分辨率:400×240(96,000像素)
相比640×480,计算量减少约60%
在检测精度和 processing 速度间取得最佳平衡
显示分辨率:640×480
提供清晰的视觉输出
居中显示保持良好用户体验

核心技术组件详解
1. 多显示模式架构
python
  1. DISPLAY_MODE = "LCD"  # 支持 "LCD" 和 "VIRT"
复制代码

双模式设计:
LCD模式:物理屏幕显示 + IDE调试输出
VIRT模式:1920×1080虚拟显示,适合无屏幕开发环境
内存对齐优化:ALIGN_UP(1920, 16) 提升内存访问效率

2. 霍夫圆变换算法
python
  1. circles = img.find_circles(threshold=3500)
复制代码

算法深度解析:
霍夫圆变换原理:
在参数空间 (x, y, radius) 中寻找圆形
每个边缘像素为可能的圆心和半径投票
通过累加器寻找局部最大值
阈值参数作用:
threshold=3500:累加器阈值
高阈值:只检测轮廓清晰、证据充分的圆形
低阈值:检测更多圆形,但可能包含噪声和误检

3. 传感器初始化流程
python
  1. sensor = Sensor(id=2)
  2. sensor.reset()
  3. sensor.set_framesize(width=400, height=240, chn=CAM_CHN_ID_0)
  4. sensor.set_pixformat(Sensor.RGB565, chn=CAM_CHN_ID_0)
复制代码

关键技术点:
RGB565格式:16位彩色,相比RGB888节省33%内存
通道管理:使用CAM_CHN_ID_0通道进行图像采集
硬件优化:充分利用K230的专用图像处理单元

性能优化策略
1. 计算复杂度优化
text
原始处理:640 × 480 = 307,200 像素
优化处理:400 × 240 = 96,000 像素
计算量减少:68.75%
2. 内存访问优化
python
  1. DISPLAY_WIDTH = ALIGN_UP(1920, 16)  # 16字节对齐
复制代码

对齐内存访问,提高DMA传输效率

减少内存碎片和访问冲突

3. 居中显示算法
python
  1. x_offset = (640 - 400) // 2 = 120
  2. y_offset = (480 - 240) // 2 = 120
复制代码

自动适应不同分辨率组合
保持图像在显示中心位置

算法工作流程
主循环执行序列
图像捕获:从摄像头获取400×240分辨率帧
圆形检测:运行霍夫圆变换算法查找圆形
可视化绘制:为每个检测到的圆形绘制蓝色轮廓
信息输出:打印圆形详细信息到控制台
居中显示:将处理后的图像居中显示在屏幕上

霍夫圆变换详细流程
text
原始图像 → 边缘检测 → 梯度计算 → 参数空间累加 →
峰值检测 → 阈值筛选 → 圆形输出

可视化与用户交互
视觉渲染系统
python
  1. img.draw_circle(circle.circle(), color=(40,167,225), thickness=3)
复制代码

视觉设计分析:
颜色选择:天蓝色(40,167,225)
醒目但不刺眼
与常见背景形成良好对比
线宽设计:3像素厚度
确保轮廓清晰可见
不过度遮挡原始图像
控制台信息输出
text
【圆形信息 / Circle Statistics Start】
Circle 0: (x=120, y=80, radius=25)
【==============================】

信息内容:
圆形中心坐标 (x, y)
圆形半径 (radius)
圆形完整几何信息
中英双语支持,便于国际化使用

异常处理与资源管理
三级保护机制
python
  1. try:
  2.     # 主程序逻辑
  3. except KeyboardInterrupt:    # 用户主动中断
  4. except Exception:           # 其他所有异常
  5. finally:                    # 强制资源清理
复制代码

资源释放顺序
停止传感器:sensor.stop()
关闭显示:Display.deinit()
系统睡眠:os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
释放媒体资源:MediaManager.deinit()
延时等待:time.sleep_ms(100) 确保完全释放

应用场景分析
工业视觉检测
零件定位:精密零件中的圆形孔洞定位
尺寸测量:圆形部件的直径和位置测量
质量检查:检测圆形特征的完整性和一致性

机器人导航
标记识别:圆形AR标记或导航信标识别
目标追踪:圆形物体的实时追踪定位
环境感知:识别环境中的圆形结构特征

安防监控
镜头检测:监控摄像头圆形镜头的识别
异常检测:圆形区域的入侵或变化检测
特征提取:场景中圆形特征的提取分析

医疗影像
细胞分析:圆形细胞结构的识别计数
病变检测:组织切片中的圆形病变区域
器械定位:圆形医疗设备的定位引导

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测

实际测试的范本

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图1

实验串口返回情况

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图2

实验场景图

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图3

【花雕动手做】CanMV K230 AI 视觉识别模块之圆形检测图4


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail