回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

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

头像 驴友花雕 2025.11.01 2 0

00 (3).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 (4).jpg

绘制线条的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()  # 调用显示测试函数

解读这段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. 几何布局分析

 

17.jpg


坐标计算示例:

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设计的多个技术领域。代码不仅功能完整,而且在性能和视觉效果之间取得了很好的平衡。
 

实验场景图  

 

15.jpg
16.jpg

评论

user-avatar
icon 他的勋章
    展开更多