9浏览
查看: 9|回复: 3

[项目] 【花雕动手做】CanMV K230 AI 视觉识别之线段检测

[复制链接]
【花雕动手做】CanMV K230 AI 视觉识别之线段检测图1

什么是 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 视觉识别之线段检测图3

【花雕动手做】CanMV K230 AI 视觉识别之线段检测图2

驴友花雕  高级技神
 楼主|

发表于 2 小时前

【花雕动手做】CanMV K230 AI视觉识别之线段检测

线段检测是计算机视觉中的基础任务,核心是从图像中识别并提取连续的直线段(如物体边缘、建筑轮廓、道路标线等),广泛用于场景理解、目标定位、图像分割等上层应用。

1、核心原理
线段检测的本质是识别图像中 “像素灰度值突变的连续区域”(即边缘),再通过算法拟合出直线段,核心步骤包括:
边缘检测:先提取图像中像素灰度变化剧烈的区域(如用 Canny 算子、Sobel 算子),得到边缘二值图。
直线拟合:对边缘像素进行分组,用数学方法(如霍夫变换、最小二乘法)拟合出直线,再截取有效线段(过滤短线段、重叠线段)。
后处理:去除噪声线段(如长度过短、角度异常)、合并重叠 / 相邻线段,得到最终的线段结果(通常以 “起点坐标 (x1,y1)、终点坐标 (x2,y2)” 表示)。

2、主流算法(按效率和精度分类)

【花雕动手做】CanMV K230 AI 视觉识别之线段检测图4

3、典型应用场景
工业检测:检测产品轮廓的直线段(如电路板引脚是否笔直、金属件边缘是否平整)。
自动驾驶:识别道路标线(实线 / 虚线)、车道边界,辅助车辆定位和路径规划。
文档处理:扫描文档中提取文字行、表格边框,实现文档结构化(如 PDF 表格提取)。
机器人视觉:检测环境中的线段(如墙角、栏杆),用于 SLAM 建图、障碍物避让。
医学影像:提取 CT/MRI 图像中的骨骼边缘线段,辅助病变诊断(如骨折检测)。

4、实操示例(OpenCV 实现 LSD 线段检测)
OpenCV 内置了 LSD 算法接口,无需复杂封装,直接调用即可:
python
  1. import cv2
  2. import numpy as np
  3. # 读取图像(可替换为K230摄像头采集的帧)
  4. img = cv2.imread("road.jpg")
  5. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  6. # 初始化LSD检测器
  7. lsd = cv2.createLineSegmentDetector(0)
  8. # 检测线段(返回线段数组:每个线段为[x1,y1,x2,y2])
  9. lines, _, _, _ = lsd.detect(gray)
  10. # 绘制线段(在原图上用红色标注)
  11. if lines is not None:
  12.     for line in lines:
  13.         x1, y1, x2, y2 = map(int, line[0])
  14.         cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
  15. # 显示结果
  16. cv2.imshow("Line Detection", img)
  17. cv2.waitKey(0)
  18. cv2.destroyAllWindows()
复制代码

5、关键优化技巧(提升检测效果)
图像预处理:检测前对图像进行降噪(如高斯模糊cv2.GaussianBlur)、增强对比度(如直方图均衡化),减少噪声线段干扰。
参数调优:
霍夫变换:调整rho(距离步长)、theta(角度步长)、threshold(累加器阈值),过滤虚假线段。
LSD:调整scale(检测尺度)、sigma_scale(高斯平滑系数),平衡精度和速度。
后处理过滤:设置线段长度阈值(如只保留长度 > 30 像素的线段)、角度阈值(如只保留水平 / 垂直线段),去除无效结果。
硬件加速:在 K230 等边缘设备上,可通过 NPU 加速边缘检测或线段拟合步骤,降低延迟(如用 Tengine-Lite 部署轻量化线段检测模型)。

【花雕动手做】CanMV K230 AI 视觉识别之线段检测图2

【花雕动手做】CanMV K230 AI 视觉识别之线段检测图1

【花雕动手做】CanMV K230 AI 视觉识别之线段检测图3

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 2 小时前

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

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

  1. #【花雕动手做】CanMV K230 AI 视觉识别模块之线段检测
  2. # 导入必要的模块:时间、操作系统、系统、垃圾回收
  3. import time, os, sys, gc
  4. # 导入媒体相关模块:传感器、显示、媒体管理
  5. from media.sensor import *
  6. from media.display import *
  7. from media.media import *
  8. # 导入PipeLine库,用于图像处理Pipeline和性能计时
  9. from libs.PipeLine import PipeLine, ScopedTiming
  10. # 设置图像处理分辨率常量 - 使用低分辨率提高处理速度
  11. PICTURE_WIDTH = 160    # 图像处理宽度(低分辨率)
  12. PICTURE_HEIGHT = 120   # 图像处理高度(低分辨率)
  13. # 初始化摄像头变量为空
  14. sensor = None
  15. # 设置显示分辨率常量 - 使用高分辨率保证显示质量
  16. DISPLAY_WIDTH = 640    # 显示宽度(高分辨率)
  17. DISPLAY_HEIGHT = 480   # 显示高度(高分辨率)
  18. def scale_coordinates(data_tuple, target_resolution="640x480"):
  19.     """
  20.     将160x120分辨率下的坐标元组等比例缩放到目标分辨率
  21.    
  22.     参数:
  23.         data_tuple: 包含坐标信息的元组 (x1, y1, x2, y2)
  24.         target_resolution: 目标分辨率,默认为"640x480"
  25.    
  26.     返回:
  27.         包含缩放后坐标的新元组 (x1, y1, x2, y2)
  28.     """
  29.     global PICTURE_WIDTH, PICTURE_HEIGHT
  30.    
  31.     # 输入验证:确保是包含至少4个元素的元组
  32.     if not isinstance(data_tuple, tuple) or len(data_tuple) < 4:
  33.         raise TypeError(f"期望输入至少包含4个元素的元组,但收到了 {type(data_tuple).__name__}")
  34.    
  35.     # 解析原始坐标点
  36.     x1, y1, x2, y2 = data_tuple[:4]
  37.    
  38.     # 设置源分辨率(处理分辨率)
  39.     src_width, src_height = PICTURE_WIDTH, PICTURE_HEIGHT
  40.    
  41.     # 根据目标分辨率设置目标尺寸
  42.     if target_resolution == "640x480":
  43.         dst_width, dst_height = 640, 480
  44.     else:
  45.         raise ValueError("不支持的分辨率,请使用 '640x480'")
  46.    
  47.     # 计算缩放比例(4倍缩放:640/160=4, 480/120=4)
  48.     scale_x = dst_width / src_width    # 水平缩放比例 = 4
  49.     scale_y = dst_height / src_height  # 垂直缩放比例 = 4
  50.    
  51.     # 应用缩放并四舍五入为整数坐标
  52.     scaled_x1 = round(x1 * scale_x)    # 缩放起点x坐标
  53.     scaled_y1 = round(y1 * scale_y)    # 缩放起点y坐标
  54.     scaled_x2 = round(x2 * scale_x)    # 缩放终点x坐标
  55.     scaled_y2 = round(y2 * scale_y)    # 缩放终点y坐标
  56.    
  57.     # 返回缩放后的坐标元组
  58.     return (scaled_x1, scaled_y1, scaled_x2, scaled_y2)
  59. # 设置显示模式为LCD
  60. display_mode = "LCD"
  61. # 创建图像处理Pipeline
  62. # rgb888p_size: RGB888格式的处理尺寸
  63. # display_size: 最终显示尺寸
  64. # display_mode: 显示模式
  65. pl = PipeLine(rgb888p_size=[640,360], display_size=[640,480], display_mode=display_mode)
  66. # 创建Pipeline实例,设置通道1的帧大小为处理分辨率
  67. pl.create(ch1_frame_size=[PICTURE_WIDTH,PICTURE_HEIGHT])
  68. # 主循环 - 实时线段检测和显示
  69. while True:
  70.     # 从通道1捕获图像(160x120低分辨率图像)
  71.     img = pl.sensor.snapshot(chn=CAM_CHN_ID_1)
  72.    
  73.     # 在图像中查找线段
  74.     # merge_distance=15: 合并距离阈值,相近线段会被合并
  75.     # max_theta_diff=10: 最大角度差异阈值,角度相近线段会被合并
  76.     lines = img.find_line_segments(merge_distance=15, max_theta_diff=10)
  77.    
  78.     # 创建新的ARGB8888格式图像用于显示(640x480高分辨率)
  79.     img = image.Image(640, 480, image.ARGB8888)
  80.    
  81.     # 清空图像(透明背景)
  82.     img.clear()
  83.    
  84.     # 遍历所有检测到的线段
  85.     for i, line in enumerate(lines):
  86.         # 获取线段坐标并缩放到显示分辨率
  87.         # line.line()返回原始坐标元组 (x1, y1, x2, y2)
  88.         scaled_line = scale_coordinates(line.line())
  89.         
  90.         # 在图像上绘制红色线段,线宽为6像素
  91.         img.draw_line(scaled_line, color=(255,0,0), thickness=6)
  92.    
  93.     # 在OSD3层显示处理后的图像
  94.     Display.show_image(img, 0, 0, Display.LAYER_OSD3)
  95.    
  96.     # 短暂延时,避免CPU过度占用
  97.     time.sleep_us(1)
复制代码

代码解读:

程序总体功能
这是一个基于CanMV K230的实时线段检测系统,采用双分辨率处理策略在视频流中实时识别并绘制图像中的线段。

系统架构与处理流程
核心处理管道
text
摄像头采集 → 低分辨率处理(160×120) → 线段检测算法 → 坐标缩放映射 → 高分辨率显示(640×480)
1. 双分辨率策略设计
python
  1. PICTURE_WIDTH = 160    # 处理分辨率 - 低
  2. PICTURE_HEIGHT = 120
  3. DISPLAY_WIDTH = 640    # 显示分辨率 - 高  
  4. DISPLAY_HEIGHT = 480
复制代码

设计原理:
处理分辨率:160×120(19,200像素)
显示分辨率:640×480(307,200像素)
性能提升:计算量减少 94%,大幅提高检测速度

核心技术组件详解
1. PipeLine图像处理管道
python
  1. pl = PipeLine(rgb888p_size=[640,360], display_size=[640,480], display_mode=display_mode)
  2. pl.create(ch1_frame_size=[PICTURE_WIDTH,PICTURE_HEIGHT])
复制代码

技术特点:
硬件加速:利用K230专用媒体处理单元
多路输出:支持不同尺寸的输入和输出流
通道管理:通道1专用于线段检测处理

2. 线段检测算法
python
  1. lines = img.find_line_segments(merge_distance=15, max_theta_diff=10)
复制代码

算法参数解析:
merge_distance=15:合并距离阈值
作用:将距离相近的线段合并为一条
效果:减少重复检测,优化结果显示
max_theta_diff=10:最大角度差异
作用:将角度相近的线段进行合并
效果:消除微小角度差异造成的重复线段

3. 坐标缩放核心算法
python
  1. def scale_coordinates(data_tuple, target_resolution="640x480"):
  2.     scale_x = 640 / 160 = 4    # 水平缩放比例
  3.     scale_y = 480 / 120 = 4    # 垂直缩放比例
复制代码

数学映射关系:

text
低分辨率坐标(160×120) → 高分辨率坐标(640×480)
(x, y) → (4x, 4y)

算法步骤:
提取原始线段端点坐标
应用4倍缩放比例
四舍五入为整数坐标
返回缩放后的坐标

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 2 小时前

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

实验场景图

【花雕动手做】CanMV K230 AI 视觉识别之线段检测图1

【花雕动手做】CanMV K230 AI 视觉识别之线段检测图3

【花雕动手做】CanMV K230 AI 视觉识别之线段检测图2

【花雕动手做】CanMV K230 AI 视觉识别之线段检测图4
回复

使用道具 举报

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

本版积分规则

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

硬件清单

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

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

mail