驴友花雕 发表于 昨天 14:46

【花雕动手做】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 倍。



驴友花雕 发表于 昨天 16:54

【花雕动手做】CanMV K230 AI 视觉模块之绘制一个箭头图案

绘制线条的draw_arrow()方法

image.draw_arrow(x0, y0, x1, y1[, color[, thickness=1]])
在图像上绘制从 (x0, y0) 到 (x1, y1) 的箭头。参数可以分别传入 x0, y0, x1, y1,也可以作为元组 (x0, y0, x1, y1) 一起传递。

color: 表示颜色的 RGB888 元组,适用于灰度或 RGB565 图像,默认为白色。对于灰度图像,还可以传递像素值(范围 0-255);对于 RGB565 图像,可以传递字节翻转的 RGB565 值。
thickness: 控制箭头线条的像素宽度,默认为 1。
该方法返回图像对象,允许通过链式调用其他方法。

不支持压缩图像和 Bayer 格式图像。

项目测试实验代码

#【花雕动手做】CanMV K230 AI视觉识别模块之使用draw_arrow()方法绘制箭头

# Import required modules
# 导入所需的模块
import time, os, urandom, sys, math

# Import display and media related modules
# 导入显示和媒体相关模块
from media.display import *
from media.media import *

# Define display resolution constants
# 定义显示分辨率常量
DISPLAY_WIDTH = 640    # 显示宽度:640像素
DISPLAY_HEIGHT = 480   # 显示高度:480像素

def display_test():
    """
    Function to test display functionality
    测试显示功能的函数
    主要功能:在屏幕上绘制多个不同方向、大小和颜色的箭头,展示draw_arrow()方法的用法
    """

    # Create main background image with white color
    # 创建白色背景的主图像
    # ARGB8888格式:每个像素32位(Alpha透明通道+RGB各8位)
    img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
    img.clear()# 清空图像缓冲区
    # 绘制白色填充矩形作为背景,fill=True表示填充
    img.draw_rectangle(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, color=(255,255,255), fill=True)

    # Initialize display with ST7701 driver
    # 使用ST7701驱动初始化显示器
    # ST7701是常见的LCD屏幕驱动芯片
    # to_ide=True表示将显示输出同时发送到IDE和硬件屏幕
    Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
   
    # Initialize media manager
    # 初始化媒体管理器 - 负责管理摄像头、显示等媒体资源
    MediaManager.init()

    try:
      # ========== 第一组:中央主要箭头 ==========
      # 绘制水平向右的主箭头,象征前进方向
      # 参数说明:
      # 320, 200: 箭头起点坐标(x1, y1)
      # 400, 200: 箭头终点坐标(x2, y2)
      # color=(0, 191, 255): 天蓝色 (RGB值)
      # thickness=5: 线宽5像素(最粗,突出主箭头)
      img.draw_arrow(320, 200, 400, 200, color=(0, 191, 255), thickness=5)

      # ========== 第二组:辅助箭头 ==========
      # 在主箭头上方和下方绘制两个平行的辅助箭头
      # 上方的辅助箭头(比主箭头细且颜色浅)
      img.draw_arrow(300, 180, 380, 180, color=(135, 206, 235), thickness=3)
      # 下方的辅助箭头
      img.draw_arrow(340, 220, 420, 220, color=(135, 206, 235), thickness=3)

      # ========== 第三组:对角线箭头 ==========
      # 绘制两个对角线方向的箭头,增加画面的动感和立体感
      # 左上到右下的对角线箭头
      img.draw_arrow(250, 150, 350, 250, color=(0, 191, 255), thickness=3)
      # 右上到左下的对角线箭头(实际上是另一个方向的斜箭头)
      img.draw_arrow(350, 150, 450, 250, color=(0, 191, 255), thickness=3)

      # ========== 第四组:反向箭头 ==========
      # 绘制与主箭头方向相反的箭头,形成对比效果
      # 与主箭头完全反向(从右向左)
      img.draw_arrow(400, 200, 320, 200, color=(173, 216, 230), thickness=3)
      # 与上方辅助箭头反向
      img.draw_arrow(380, 180, 300, 180, color=(173, 216, 230), thickness=2)
      # 与下方辅助箭头反向
      img.draw_arrow(420, 220, 340, 220, color=(173, 216, 230), thickness=2)

      # ========== 第五组:垂直箭头 ==========
      # 绘制垂直方向的箭头,丰富箭头的方向变化
      # 左侧垂直向下的箭头
      img.draw_arrow(320, 150, 320, 250, color=(0, 191, 255), thickness=3)
      # 右侧垂直向下的箭头
      img.draw_arrow(400, 150, 400, 250, color=(0, 191, 255), thickness=3)

      # ========== 第六组:点缀小箭头 ==========
      # 绘制两个小尺寸的装饰性箭头,增加画面的细节
      # 左下角的小箭头
      img.draw_arrow(300, 220, 310, 230, color=(135, 206, 235), thickness=2)
      # 右上角的小箭头
      img.draw_arrow(330, 170, 340, 180, color=(135, 206, 235), thickness=2)
      
      # Update display with background image
      # 更新显示背景图像 - 将绘制好的箭头图案显示在屏幕上
      Display.show_image(img)
      
      # 主循环保持显示
      while True:
            time.sleep(2)# 每2秒循环一次,保持程序运行

    except KeyboardInterrupt as e:
      # 捕获键盘中断(如Ctrl+C),优雅退出
      print("user stop: ", e)
    except BaseException as e:
      # 捕获其他所有异常,防止程序崩溃
      print(f"Exception {e}")

    # Cleanup and deinitialize display
    # 清理并反初始化显示器
    Display.deinit()
    # 启用睡眠退出点,允许系统进入低功耗模式
    os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
    time.sleep_ms(100)# 短暂延时确保资源释放完成
   
    # Release media resources
    # 释放媒体资源
    MediaManager.deinit()

if __name__ == "__main__":
    # Enable exit points and run display test
    # 启用退出点并运行显示测试
    # EXITPOINT_ENABLE允许通过IDE停止程序执行
    os.exitpoint(os.EXITPOINT_ENABLE)
    display_test()# 调用显示测试函数

驴友花雕 发表于 昨天 17:02

【花雕动手做】CanMV K230 AI 视觉模块之绘制一个箭头图案

解读这段CanMV K230箭头绘制代码的技术细节和实现原理:

代码架构分析
1. 核心模块依赖
python
import time, os, urandom, sys, math
from media.display import *
from media.media import *

math模块:虽然本例未直接使用,但draw_arrow()内部可能用到三角函数计算箭头头部
media模块:提供底层图形绘制能力
模块选择体现了嵌入式系统对计算效率的重视

核心技术解析
1. 显示系统初始化流程
python
img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
MediaManager.init()

技术要点:
ARGB8888格式:32位色深,支持1600万色和透明度
ST7701驱动:针对RGB接口LCD的专用驱动芯片
双缓冲机制:内存绘制完成后一次性显示,避免闪烁

2. draw_arrow() 方法深度解析
基于使用方式推测的方法签名:

python
def draw_arrow(x1, y1, x2, y2, color, thickness):
    """
    绘制从(x1,y1)到(x2,y2)的箭头
    技术实现包含:
    1. 主体线段绘制
    2. 箭头头部三角形计算
    3. 抗锯齿处理(可选)
    """

箭头绘制算法原理:

python
# 伪代码实现
def draw_arrow_algorithm(x1, y1, x2, y2, color, thickness):
    # 1. 计算方向向量和长度
    dx = x2 - x1
    dy = y2 - y1
    length = math.sqrt(dx*dx + dy*dy)
   
    # 2. 归一化方向向量
    if length > 0:
      dx /= length
      dy /= length
   
    # 3. 绘制主体线段(稍微缩短以避免与箭头头部重叠)
    line_end_x = x2 - dx * head_length
    line_end_y = y2 - dy * head_length
    draw_line(x1, y1, line_end_x, line_end_y, color, thickness)
   
    # 4. 计算箭头头部参数
    head_length = thickness * 3# 头部长度与线宽成正比
    head_angle = math.pi / 6   # 30度夹角
   
    # 5. 计算箭头翼部点(使用旋转矩阵)
    # 左侧翼点
    left_angle = math.atan2(dy, dx) - head_angle
    left_x = x2 - head_length * math.cos(left_angle)
    left_y = y2 - head_length * math.sin(left_angle)
   
    # 右侧翼点
    right_angle = math.atan2(dy, dx) + head_angle
    right_x = x2 - head_length * math.cos(right_angle)
    right_y = y2 - head_length * math.sin(right_angle)
   
    # 6. 绘制箭头头部三角形
    draw_line(x2, y2, left_x, left_y, color, thickness)
    draw_line(x2, y2, right_x, right_y, color, thickness)
    draw_line(left_x, left_y, right_x, right_y, color, thickness)

3. 视觉层次设计策略
颜色层次系统:

python
颜色层次 = {
    "主要": (0, 191, 255),      # 深天蓝 - 最高重要性
    "次要": (135, 206, 235),    # 中天蓝 - 中等重要性
    "装饰": (173, 216, 230)   # 浅天蓝 - 最低重要性
}

线宽层次系统:

python
线宽层次 = {
    "主要": 5,    # 最粗 - 视觉焦点
    "中等": 3,    # 中等 - 重要元素
    "细小": 2   # 最细 - 装饰元素
}

4. 几何布局分析



坐标计算示例:

python
# 主箭头坐标分析
起点 = (320, 200)# 屏幕水平中心偏上
终点 = (400, 200)# 向右80像素
长度 = 80像素

# 对角线箭头坐标分析
左上右下: (250,150) → (350,250)# 100像素斜线
右上左下: (350,150) → (450,250)# 100像素斜线

性能优化技术
1. 批量绘制优化
python
# 所有箭头在内存中一次性绘制完成
# 然后单次调用Display.show_image()显示
# 避免频繁的显示更新造成的闪烁

2. 计算优化
python
# 可能的内部优化:
- 使用整数运算避免浮点开销
- 使用查表法替代实时三角函数计算
- 利用硬件加速的直线绘制算法

3. 内存管理
python
# ARGB8888内存占用计算:
640 × 480 × 4字节 = 1,228,800字节 ≈ 1.17MB
# 在嵌入式系统中属于较大的帧缓冲区

异常处理机制
python
try:
    # 主要绘图逻辑
    # 可能发生的异常:
    # - 坐标超出范围
    # - 内存分配失败
    # - 硬件访问错误
except KeyboardInterrupt:
    # 用户主动终止 - 友好退出
except BaseException:
    # 捕获所有其他异常 - 防止系统崩溃

实际应用场景扩展
1. 导航系统界面
python
def draw_navigation_interface():
    # 主方向箭头
    img.draw_arrow(320, 240, 400, 200, color=(0,255,0), thickness=4)
    # 替代路线箭头
    img.draw_arrow(320, 240, 350, 150, color=(255,165,0), thickness=2)

2. 数据流向图示
python
def draw_data_flow():
    # 处理器到内存
    img.draw_arrow(100, 200, 200, 200, color=(0,0,255), thickness=3)
    # 内存到显示器
    img.draw_arrow(200, 200, 300, 100, color=(0,0,255), thickness=3)

3. 运动轨迹分析
python
def show_velocity_vectors():
    for object in tracked_objects:
      img.draw_arrow(object.x, object.y,
                      object.x + object.vx, object.y + object.vy,
                      color=(255,0,0), thickness=2)

技术亮点总结
算法效率:在资源受限的嵌入式设备上实现复杂的矢量图形
视觉设计:通过颜色和线宽创建清晰的视觉层次
几何精度:准确的箭头方向计算和头部形状生成
系统稳定性:完善的异常处理确保可靠运行
扩展性:代码结构便于添加更多箭头类型和效果

这个箭头绘制示例很好地展示了CanMV K230在嵌入式图形处理方面的强大能力,结合了计算机图形学、嵌入式系统和UI设计的多个技术领域。代码不仅功能完整,而且在性能和视觉效果之间取得了很好的平衡。


驴友花雕 发表于 昨天 17:06

【花雕动手做】CanMV K230 AI 视觉模块之绘制一个箭头图案

实验场景图




页: [1]
查看完整版本: 【花雕动手做】CanMV K230 AI 视觉模块之绘制一个箭头图案