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

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



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

【花雕动手做】CanMV K230 AI 视觉模块之绘制十字准心图案

绘制十字准心的draw_cross()方法

image.draw_cross(x, y[, color[, size=5[, thickness=1]]])
在图像上绘制一个十字标记。参数可以分别传入 x, y,也可以作为元组 (x, y) 一起传递。

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

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

测试实验代码

#【花雕动手做】CanMV K230 AI视觉识别模块之使用draw_cross()方法绘制十字准心

# 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
    测试显示功能的函数
    主要功能:在屏幕上绘制一个精美的十字准心图案,包含中心大十字和多个环绕小十字
    """

    # 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,240)位置绘制一个大十字准心
      # 参数说明:
      # 320, 240: 十字中心坐标(屏幕中心)
      # color=(0, 191, 255): 天蓝色 (RGB值)
      # size=40: 十字大小,指单臂长度(像素)
      # thickness=3: 线宽3像素
      img.draw_cross(320, 240, color=(0, 191, 255), size=40, thickness=3)

      # ========== 第二层:内圈小十字环绕 ==========
      # 在半径为50像素的圆周上均匀分布8个小十字
      for i in range(8):
            # 计算当前小十字的角度位置(0-360度均匀分布)
            angle = i * (360 / 8)# 每个十字间隔45度
            
            # 使用三角函数计算小十字的坐标位置
            # math.radians()将角度转换为弧度
            # math.cos()和math.sin()计算余弦和正弦值
            x = int(320 + 50 * math.cos(math.radians(angle)))# x坐标 = 中心x + 半径*cos(角度)
            y = int(240 + 50 * math.sin(math.radians(angle)))# y坐标 = 中心y + 半径*sin(角度)
            
            # 绘制内圈小十字
            # color=(135, 206, 235): 浅天蓝色,比中心十字稍浅
            # size=15: 大小15像素
            # thickness=2: 线宽2像素
            img.draw_cross(x, y, color=(135, 206, 235), size=15, thickness=2)

      # ========== 第三层:外圈更小的十字 ==========
      # 在半径为80像素的圆周上均匀分布12个更小的十字
      for i in range(12):
            angle = i * (360 / 12)# 每个十字间隔30度
            
            # 计算外圈十字坐标(半径80像素)
            x = int(320 + 80 * math.cos(math.radians(angle)))
            y = int(240 + 80 * math.sin(math.radians(angle)))
            
            # 绘制外圈小十字
            # color=(173, 216, 230): 更浅的天蓝色
            # size=10: 大小10像素
            # thickness=1: 线宽1像素(最细)
            img.draw_cross(x, y, color=(173, 216, 230), size=10, thickness=1)

      # ========== 第四层:四个角的装饰性十字 ==========
      # 在屏幕四个角落附近绘制中等大小的装饰十字
      # 左上角十字 (240, 140)
      img.draw_cross(240, 140, color=(0, 191, 255), size=25, thickness=2)
      # 右上角十字 (400, 140)
      img.draw_cross(400, 140, color=(0, 191, 255), size=25, thickness=2)
      # 左下角十字 (240, 340)
      img.draw_cross(240, 340, color=(0, 191, 255), size=25, thickness=2)
      # 右下角十字 (400, 340)
      img.draw_cross(400, 340, color=(0, 191, 255), size=25, thickness=2)

      # ========== 第五层:中心点缀小十字 ==========
      # 在中心大十字上面再绘制一个更小的十字,增加层次感
      img.draw_cross(320, 240, color=(173, 216, 230), size=8, thickness=1)
      
      # 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()# 调用显示测试函数

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

【花雕动手做】CanMV K230 AI 视觉模块之绘制十字准心图案

解读这段CanMV K230十字准心绘制代码的技术细节和实现原理:

代码架构分析
1. 核心模块导入
python
import time, os, urandom, sys, math

from media.display import *

from media.media import *
math模块:关键!用于三角函数计算圆周分布
media模块:CanMV特有的图形显示功能
这种导入方式显示了嵌入式系统对计算效率的重视

核心技术解析
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()
技术要点:
双缓冲机制:image.Image创建内存缓冲区,Display.show_image()一次性显示
ARGB8888:32位色深,支持透明度(虽然本例未使用Alpha通道)
ST7701驱动:针对特定LCD屏幕的优化驱动

2. draw_cross() 方法深度解析
python
# 方法签名推测(基于使用方式)

def draw_cross(x, y, color, size, thickness):

    """

    绘制十字准心

    参数:

    x, y: 中心坐标

    color: RGB颜色元组

    size: 十字单臂长度(从中心到端点的距离)

    thickness: 线条粗细

    """
绘制原理:
十字由两条垂直的线段组成:
水平线:从(x-size, y)到(x+size, y)
垂直线:从(x, y-size)到(x, y+size)
使用Bresenham直线算法或类似的光栅化算法

3. 极坐标分布算法
python
for i in range(8):

    angle = i * (360 / 8)# 45度间隔

    x = int(320 + 50 * math.cos(math.radians(angle)))

    y = int(240 + 50 * math.sin(math.radians(angle)))
数学原理:
角度转弧度:math.radians(angle) - 三角函数需要弧度制
极坐标转直角坐标:
x = r × cos(θ) + center_x
y = r × sin(θ) + center_y
均匀分布:360/n度间隔确保等分圆周

4. 颜色层次设计
python
# 颜色渐变策略

颜色方案 = {

    "中心": (0, 191, 255),      # 深天蓝 - 最醒目

    "内圈": (135, 206, 235),    # 中天蓝 - 中等醒目

    "外圈": (173, 216, 230),    # 浅天蓝 - 最淡

    "角落": (0, 191, 255)       # 与中心同色 - 形成视觉关联

}
视觉设计原则:
中心突出:最大尺寸 + 最深颜色
层次递减:向外圈尺寸减小、颜色变浅
对称平衡:四个角落重复中心颜色

性能优化分析
1. 计算优化
python
# 预计算避免重复运算

angle_step = 360 / 8# 只计算一次

for i in range(8):

    angle = i * angle_step# 复用计算结果
2. 内存管理
python
# 单次图像更新

Display.show_image(img)# 避免频繁刷新造成的闪烁
3. 异常处理机制
python
try:

    # 主要绘图逻辑

    pass

except KeyboardInterrupt:

    # 用户主动中断

    pass

except BaseException:

    # 其他所有异常

    pass
重要性:在嵌入式系统中,异常处理防止系统死机

几何布局详解



坐标计算验证:
python
# 屏幕中心

center_x = DISPLAY_WIDTH // 2 = 640 // 2 = 320

center_y = DISPLAY_HEIGHT // 2 = 480 // 2 = 240



# 内圈十字示例(0度方向)

x = 320 + 50 * cos(0°) = 320 + 50 * 1 = 370

y = 240 + 50 * sin(0°) = 240 + 50 * 0 = 240
实际应用场景
1. 机器视觉瞄准
python
# 可用于目标跟踪的参考系

def update_crosshair(target_x, target_y):

    img.clear()

    img.draw_cross(target_x, target_y, color=(255,0,0), size=30, thickness=2)
2. 摄像头校准
python
# 光学中心校准工具

def calibration_pattern():

    # 绘制精确的校准图案

    pass
3. 游戏UI元素
python
# 第一人称射击游戏的准心

def fps_crosshair():

    # 可动态变化的准心

    pass


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

【花雕动手做】CanMV K230 AI 视觉模块之绘制十字准心图案

实验场景图




页: [1]
查看完整版本: 【花雕动手做】CanMV K230 AI 视觉模块之绘制十字准心图案