10浏览
查看: 10|回复: 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 视觉模块之绘制一个箭头图案图2

驴友花雕  中级技神
 楼主|

发表于 2 小时前

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

绘制线条的draw_arrow()方法

  1. 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 格式图像。

项目测试实验代码

  1. #【花雕动手做】CanMV K230 AI视觉识别模块之使用draw_arrow()方法绘制箭头
  2. # Import required modules
  3. # 导入所需的模块
  4. import time, os, urandom, sys, math
  5. # Import display and media related modules
  6. # 导入显示和媒体相关模块
  7. from media.display import *
  8. from media.media import *
  9. # Define display resolution constants
  10. # 定义显示分辨率常量
  11. DISPLAY_WIDTH = 640    # 显示宽度:640像素
  12. DISPLAY_HEIGHT = 480   # 显示高度:480像素
  13. def display_test():
  14.     """
  15.     Function to test display functionality
  16.     测试显示功能的函数
  17.     主要功能:在屏幕上绘制多个不同方向、大小和颜色的箭头,展示draw_arrow()方法的用法
  18.     """
  19.     # Create main background image with white color
  20.     # 创建白色背景的主图像
  21.     # ARGB8888格式:每个像素32位(Alpha透明通道+RGB各8位)
  22.     img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
  23.     img.clear()  # 清空图像缓冲区
  24.     # 绘制白色填充矩形作为背景,fill=True表示填充
  25.     img.draw_rectangle(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, color=(255,255,255), fill=True)
  26.     # Initialize display with ST7701 driver
  27.     # 使用ST7701驱动初始化显示器
  28.     # ST7701是常见的LCD屏幕驱动芯片
  29.     # to_ide=True表示将显示输出同时发送到IDE和硬件屏幕
  30.     Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
  31.    
  32.     # Initialize media manager
  33.     # 初始化媒体管理器 - 负责管理摄像头、显示等媒体资源
  34.     MediaManager.init()
  35.     try:
  36.         # ========== 第一组:中央主要箭头 ==========
  37.         # 绘制水平向右的主箭头,象征前进方向
  38.         # 参数说明:
  39.         # 320, 200: 箭头起点坐标(x1, y1)
  40.         # 400, 200: 箭头终点坐标(x2, y2)  
  41.         # color=(0, 191, 255): 天蓝色 (RGB值)
  42.         # thickness=5: 线宽5像素(最粗,突出主箭头)
  43.         img.draw_arrow(320, 200, 400, 200, color=(0, 191, 255), thickness=5)
  44.         # ========== 第二组:辅助箭头 ==========
  45.         # 在主箭头上方和下方绘制两个平行的辅助箭头
  46.         # 上方的辅助箭头(比主箭头细且颜色浅)
  47.         img.draw_arrow(300, 180, 380, 180, color=(135, 206, 235), thickness=3)
  48.         # 下方的辅助箭头
  49.         img.draw_arrow(340, 220, 420, 220, color=(135, 206, 235), thickness=3)
  50.         # ========== 第三组:对角线箭头 ==========
  51.         # 绘制两个对角线方向的箭头,增加画面的动感和立体感
  52.         # 左上到右下的对角线箭头
  53.         img.draw_arrow(250, 150, 350, 250, color=(0, 191, 255), thickness=3)
  54.         # 右上到左下的对角线箭头(实际上是另一个方向的斜箭头)
  55.         img.draw_arrow(350, 150, 450, 250, color=(0, 191, 255), thickness=3)
  56.         # ========== 第四组:反向箭头 ==========
  57.         # 绘制与主箭头方向相反的箭头,形成对比效果
  58.         # 与主箭头完全反向(从右向左)
  59.         img.draw_arrow(400, 200, 320, 200, color=(173, 216, 230), thickness=3)
  60.         # 与上方辅助箭头反向
  61.         img.draw_arrow(380, 180, 300, 180, color=(173, 216, 230), thickness=2)
  62.         # 与下方辅助箭头反向  
  63.         img.draw_arrow(420, 220, 340, 220, color=(173, 216, 230), thickness=2)
  64.         # ========== 第五组:垂直箭头 ==========
  65.         # 绘制垂直方向的箭头,丰富箭头的方向变化
  66.         # 左侧垂直向下的箭头
  67.         img.draw_arrow(320, 150, 320, 250, color=(0, 191, 255), thickness=3)
  68.         # 右侧垂直向下的箭头
  69.         img.draw_arrow(400, 150, 400, 250, color=(0, 191, 255), thickness=3)
  70.         # ========== 第六组:点缀小箭头 ==========
  71.         # 绘制两个小尺寸的装饰性箭头,增加画面的细节
  72.         # 左下角的小箭头
  73.         img.draw_arrow(300, 220, 310, 230, color=(135, 206, 235), thickness=2)
  74.         # 右上角的小箭头
  75.         img.draw_arrow(330, 170, 340, 180, color=(135, 206, 235), thickness=2)
  76.         
  77.         # Update display with background image
  78.         # 更新显示背景图像 - 将绘制好的箭头图案显示在屏幕上
  79.         Display.show_image(img)
  80.         
  81.         # 主循环保持显示
  82.         while True:
  83.             time.sleep(2)  # 每2秒循环一次,保持程序运行
  84.     except KeyboardInterrupt as e:
  85.         # 捕获键盘中断(如Ctrl+C),优雅退出
  86.         print("user stop: ", e)
  87.     except BaseException as e:
  88.         # 捕获其他所有异常,防止程序崩溃
  89.         print(f"Exception {e}")
  90.     # Cleanup and deinitialize display
  91.     # 清理并反初始化显示器
  92.     Display.deinit()
  93.     # 启用睡眠退出点,允许系统进入低功耗模式
  94.     os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
  95.     time.sleep_ms(100)  # 短暂延时确保资源释放完成
  96.    
  97.     # Release media resources
  98.     # 释放媒体资源
  99.     MediaManager.deinit()
  100. if __name__ == "__main__":
  101.     # Enable exit points and run display test
  102.     # 启用退出点并运行显示测试
  103.     # EXITPOINT_ENABLE允许通过IDE停止程序执行
  104.     os.exitpoint(os.EXITPOINT_ENABLE)
  105.     display_test()  # 调用显示测试函数
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2 小时前

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

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

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


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

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


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

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

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


箭头绘制算法原理:

python
  1. # 伪代码实现
  2. def draw_arrow_algorithm(x1, y1, x2, y2, color, thickness):
  3.     # 1. 计算方向向量和长度
  4.     dx = x2 - x1
  5.     dy = y2 - y1
  6.     length = math.sqrt(dx*dx + dy*dy)
  7.    
  8.     # 2. 归一化方向向量
  9.     if length > 0:
  10.         dx /= length
  11.         dy /= length
  12.    
  13.     # 3. 绘制主体线段(稍微缩短以避免与箭头头部重叠)
  14.     line_end_x = x2 - dx * head_length
  15.     line_end_y = y2 - dy * head_length
  16.     draw_line(x1, y1, line_end_x, line_end_y, color, thickness)
  17.    
  18.     # 4. 计算箭头头部参数
  19.     head_length = thickness * 3  # 头部长度与线宽成正比
  20.     head_angle = math.pi / 6     # 30度夹角
  21.    
  22.     # 5. 计算箭头翼部点(使用旋转矩阵)
  23.     # 左侧翼点
  24.     left_angle = math.atan2(dy, dx) - head_angle
  25.     left_x = x2 - head_length * math.cos(left_angle)
  26.     left_y = y2 - head_length * math.sin(left_angle)
  27.    
  28.     # 右侧翼点
  29.     right_angle = math.atan2(dy, dx) + head_angle  
  30.     right_x = x2 - head_length * math.cos(right_angle)
  31.     right_y = y2 - head_length * math.sin(right_angle)
  32.    
  33.     # 6. 绘制箭头头部三角形
  34.     draw_line(x2, y2, left_x, left_y, color, thickness)
  35.     draw_line(x2, y2, right_x, right_y, color, thickness)
  36.     draw_line(left_x, left_y, right_x, right_y, color, thickness)
复制代码


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

python
  1. 颜色层次 = {
  2.     "主要": (0, 191, 255),      # 深天蓝 - 最高重要性
  3.     "次要": (135, 206, 235),    # 中天蓝 - 中等重要性  
  4.     "装饰": (173, 216, 230)     # 浅天蓝 - 最低重要性
  5. }
复制代码


线宽层次系统:

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


4. 几何布局分析

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

坐标计算示例:

python
  1. # 主箭头坐标分析
  2. 起点 = (320, 200)  # 屏幕水平中心偏上
  3. 终点 = (400, 200)  # 向右80像素
  4. 长度 = 80像素
  5. # 对角线箭头坐标分析  
  6. 左上右下: (250,150) → (350,250)  # 100像素斜线
  7. 右上左下: (350,150) → (450,250)  # 100像素斜线
复制代码


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


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


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


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


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


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


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


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

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


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 2 小时前

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

实验场景图  

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

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

使用道具 举报

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

本版积分规则

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

硬件清单

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

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

mail