在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

绘制十字准心的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()  # 调用显示测试函数

解读这段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屏幕的优化驱动

  1. 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直线算法或类似的光栅化算法

  1. 极坐标分布算法
    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度间隔确保等分圆周

  1. 颜色层次设计
    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

实验场景图

在这里插入图片描述
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐