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

2025-11-06469
AI 快速预览详细 收起
本文介绍了CanMV K230 AI视觉识别模块的线段检测功能。CanMV K230是一款高性价比的RISC-V边缘AI平台,适用于嵌入式视觉应用开发。文章详细讲解了线段检测的核心原理,包括边缘检测和直线拟合,并提供了OpenCV实现LSD线段检测的代码示例。此外,还介绍了关键优化技巧,如图像预处理和参数调优,以提升检测效果。

00 (2).jpg

什么是 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 倍。

 

00 (3).jpg
00 (4).jpg

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

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

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

 

05.jpg


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

4、实操示例(OpenCV 实现 LSD 线段检测)
OpenCV 内置了 LSD 算法接口,无需复杂封装,直接调用即可:
python

import cv2
import numpy as np

# 读取图像(可替换为K230摄像头采集的帧)
img = cv2.imread("road.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 初始化LSD检测器
lsd = cv2.createLineSegmentDetector(0)

# 检测线段(返回线段数组:每个线段为[x1,y1,x2,y2])
lines, _, _, _ = lsd.detect(gray)

# 绘制线段(在原图上用红色标注)
if lines is not None:
   for line in lines:
       x1, y1, x2, y2 = map(int, line[0])
       cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)

# 显示结果
cv2.imshow("Line Detection", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

 

02.jpg
03.jpg
04.jpg

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

 

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

# 导入必要的模块:时间、操作系统、系统、垃圾回收
import time, os, sys, gc

# 导入媒体相关模块:传感器、显示、媒体管理
from media.sensor import *
from media.display import *
from media.media import *

# 导入PipeLine库,用于图像处理Pipeline和性能计时
from libs.PipeLine import PipeLine, ScopedTiming

# 设置图像处理分辨率常量 - 使用低分辨率提高处理速度
PICTURE_WIDTH = 160    # 图像处理宽度(低分辨率)
PICTURE_HEIGHT = 120   # 图像处理高度(低分辨率)

# 初始化摄像头变量为空
sensor = None

# 设置显示分辨率常量 - 使用高分辨率保证显示质量
DISPLAY_WIDTH = 640    # 显示宽度(高分辨率)
DISPLAY_HEIGHT = 480   # 显示高度(高分辨率)

def scale_coordinates(data_tuple, target_resolution="640x480"):
    """
    将160x120分辨率下的坐标元组等比例缩放到目标分辨率
    
    参数:
        data_tuple: 包含坐标信息的元组 (x1, y1, x2, y2)
        target_resolution: 目标分辨率,默认为"640x480"
    
    返回:
        包含缩放后坐标的新元组 (x1, y1, x2, y2)
    """
    global PICTURE_WIDTH, PICTURE_HEIGHT
    
    # 输入验证:确保是包含至少4个元素的元组
    if not isinstance(data_tuple, tuple) or len(data_tuple) < 4:
        raise TypeError(f"期望输入至少包含4个元素的元组,但收到了 {type(data_tuple).__name__}")
    
    # 解析原始坐标点
    x1, y1, x2, y2 = data_tuple[:4]
    
    # 设置源分辨率(处理分辨率)
    src_width, src_height = PICTURE_WIDTH, PICTURE_HEIGHT
    
    # 根据目标分辨率设置目标尺寸
    if target_resolution == "640x480":
        dst_width, dst_height = 640, 480
    else:
        raise ValueError("不支持的分辨率,请使用 '640x480'")
    
    # 计算缩放比例(4倍缩放:640/160=4, 480/120=4)
    scale_x = dst_width / src_width    # 水平缩放比例 = 4
    scale_y = dst_height / src_height  # 垂直缩放比例 = 4
    
    # 应用缩放并四舍五入为整数坐标
    scaled_x1 = round(x1 * scale_x)    # 缩放起点x坐标
    scaled_y1 = round(y1 * scale_y)    # 缩放起点y坐标
    scaled_x2 = round(x2 * scale_x)    # 缩放终点x坐标
    scaled_y2 = round(y2 * scale_y)    # 缩放终点y坐标
    
    # 返回缩放后的坐标元组
    return (scaled_x1, scaled_y1, scaled_x2, scaled_y2)

# 设置显示模式为LCD
display_mode = "LCD"

# 创建图像处理Pipeline
# rgb888p_size: RGB888格式的处理尺寸
# display_size: 最终显示尺寸
# display_mode: 显示模式
pl = PipeLine(rgb888p_size=[640,360], display_size=[640,480], display_mode=display_mode)

# 创建Pipeline实例,设置通道1的帧大小为处理分辨率
pl.create(ch1_frame_size=[PICTURE_WIDTH,PICTURE_HEIGHT])

# 主循环 - 实时线段检测和显示
while True:
    # 从通道1捕获图像(160x120低分辨率图像)
    img = pl.sensor.snapshot(chn=CAM_CHN_ID_1)
    
    # 在图像中查找线段
    # merge_distance=15: 合并距离阈值,相近线段会被合并
    # max_theta_diff=10: 最大角度差异阈值,角度相近线段会被合并
    lines = img.find_line_segments(merge_distance=15, max_theta_diff=10)
    
    # 创建新的ARGB8888格式图像用于显示(640x480高分辨率)
    img = image.Image(640, 480, image.ARGB8888)
    
    # 清空图像(透明背景)
    img.clear()
    
    # 遍历所有检测到的线段
    for i, line in enumerate(lines):
        # 获取线段坐标并缩放到显示分辨率
        # line.line()返回原始坐标元组 (x1, y1, x2, y2)
        scaled_line = scale_coordinates(line.line())
        
        # 在图像上绘制红色线段,线宽为6像素
        img.draw_line(scaled_line, color=(255,0,0), thickness=6)
    
    # 在OSD3层显示处理后的图像
    Display.show_image(img, 0, 0, Display.LAYER_OSD3)
    
    # 短暂延时,避免CPU过度占用
    time.sleep_us(1)

代码解读:

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

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

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

 

核心技术组件详解
1. PipeLine图像处理管道
python
pl = PipeLine(rgb888p_size=[640,360], display_size=[640,480], display_mode=display_mode)
pl.create(ch1_frame_size=[PICTURE_WIDTH,PICTURE_HEIGHT])
技术特点:
硬件加速:利用K230专用媒体处理单元
多路输出:支持不同尺寸的输入和输出流
通道管理:通道1专用于线段检测处理

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

3. 坐标缩放核心算法
python
def scale_coordinates(data_tuple, target_resolution="640x480"):
   scale_x = 640 / 160 = 4    # 水平缩放比例
   scale_y = 480 / 120 = 4    # 垂直缩放比例
数学映射关系:

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

 

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

实验场景图 

 

06.jpg
07 (1).jpg
07 (2).jpg
07 (3).jpg

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(1)
罗罗罗
罗罗罗
666
驴友花雕
驴友花雕
作者
回复罗罗罗
感谢罗罗罗老师的许多支持和鼓励!
驴友花雕
驴友花雕
作者
回复罗罗罗
谢谢罗罗罗的许多鼓励!
共3条回复,已加载2条,点击查看更多共3条回复,已加载全部
- 没有更多了 -