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

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

头像 驴友花雕 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_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屏幕的优化驱动

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
重要性:在嵌入式系统中,异常处理防止系统死机

几何布局详解

 

14.jpg


坐标计算验证:
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
 

实验场景图  

 

12.jpg
13.jpg

评论

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