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

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

头像 驴友花雕 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_string_advanced方法

【推荐使用】
draw_string_advanced
增强版 draw_string,支持中文显示,并允许用户通过 font 参数自定义字体。
image.draw_string_advanced(x, y, char_size, str, [color, font])

【不推荐使用】
draw_string
image.draw_string(x, y, text[, color[, scale=1[, x_spacing=0[, y_spacing=0[, mono_space=True]]]]])
从图像的 (x, y) 位置开始绘制 8x10 大小的文本。参数可以分别传入 x, y,也可以作为元组 (x, y) 一起传递。

text: 要绘制的字符串,换行符 \n、\r 或 \r\n 用于将光标移动到下一行。
color: 表示颜色的 RGB888 元组,适用于灰度或 RGB565 图像,默认为白色。对于灰度图像,还可以传递像素值(范围 0-255);对于 RGB565 图像,可以传递字节翻转的 RGB565 值。
scale: 控制文本的缩放比例,默认为 1。只能为整数。
x_spacing: 调整字符之间的水平间距。正值表示增加间距,负值表示减少。
y_spacing: 调整行之间的垂直间距。正值表示增加间距,负值表示减少。
mono_space: 默认为 True,使字符具有固定宽度。设置为 False 时,字符间距将根据字符宽度动态调整。
该方法返回图像对象,允许通过链式调用其他方法。

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

项目测试实验代码

 

代码
#【花雕动手做】CanMV K230 AI视觉识别模块之使用draw_string_advanced()方法绘制文字

# 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位),支持1600万色和透明度
    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屏幕驱动芯片,支持RGB接口
    # to_ide=True表示将显示输出同时发送到IDE和硬件屏幕,便于调试
    Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
    
    # Initialize media manager
    # 初始化媒体管理器 - 负责统一管理摄像头、显示、音频等媒体资源
    MediaManager.init()

    try:
        # ========== 第一行:中文文字绘制 ==========
        # 使用draw_string_advanced方法绘制中文文字"世界你好!"
        # 参数说明:
        # 245, 200: 文字起始坐标(x, y)
        # 30: 字体大小(像素高度),30像素是比较大的字号
        # "世界你好!": 要绘制的中文字符串,包含4个汉字和1个标点
        # color=(0, 255, 127): 翠绿色,RGB值 (红=0, 绿=255, 蓝=127)
        img.draw_string_advanced(245, 200, 30, "世界你好!", color=(0, 255, 127))

        # ========== 第二行:英文文字绘制 ==========
        # 绘制英文文字"Hello World!",位于中文文字上方
        # 参数说明:
        # 230, 150: 文字起始坐标,y坐标150比中文的200更靠上
        # 30: 字体大小,与中文保持一致
        # "Hello World!": 经典的编程问候语
        # color=(0, 0, 255): 纯蓝色,RGB值 (红=0, 绿=0, 蓝=255)
        img.draw_string_advanced(230, 150, 30, "Hello World!", color=(0, 0, 255))
        
        # ========== 第三行:数字文字绘制 ==========
        # 绘制数字序列"1234567890",位于中文文字下方
        # 参数说明:
        # 230, 260: 文字起始坐标,y坐标260比中文的200更靠下
        # 30: 字体大小,保持统一
        # "1234567890": 数字0-9的完整序列
        # color=(255, 0, 0): 纯红色,RGB值 (红=255, 绿=0, 蓝=0)
        img.draw_string_advanced(230, 260, 30, "1234567890", color=(255, 0, 0))

        # Update display with background image
        # 更新显示背景图像 - 将绘制好的文字图像显示在屏幕上
        # 这里使用了双缓冲技术:先在内存中绘制完成,再一次性显示到屏幕,避免闪烁
        Display.show_image(img)
        
        # 主循环保持显示
        # 无限循环确保程序持续运行,文字保持显示状态
        while True:
            time.sleep(2)  # 每2秒循环一次,保持程序运行,减少CPU占用

    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)  # 短暂延时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
# 核心模块导入
from media.display import *    # 显示功能
from media.media import *      # 媒体管理
模块分工明确:display负责图形显示,media负责资源管理
硬件抽象层:通过统一的API屏蔽底层硬件差异

核心技术深度解析
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格式详解:
text
每个像素32位分配:
A (Alpha)  [31:24] - 透明度通道 (本例中未使用,全为0xFF)
R (Red)    [23:16] - 红色通道 (0-255)
G (Green)  [15:8]  - 绿色通道 (0-255)  
B (Blue)   [7:0]   - 蓝色通道 (0-255)

内存布局:0xAARRGGBB
示例:白色 = 0xFFFFFFFF,红色 = 0xFFFF0000
ST7701驱动特性:
RGB接口:并行RGB 16/18/24位接口

分辨率支持:最高支持1280x800

硬件加速:可能包含2D图形加速功能

2. draw_string_advanced() 方法技术实现
方法签名推测:
python
def draw_string_advanced(x, y, size, text, color, 
                       font=None, background=None, 
                       spacing=1, monospace=False):
   """
   高级文字绘制方法完整参数
   """
底层渲染算法:
c
// 基于FreeType或类似字体引擎的实现
typedef struct {
   uint16_t x;
   uint16_t y; 
   uint8_t size;
   char* text;
   uint32_t color;
   Font* font;
} TextRenderParams;

void draw_string_advanced(TextRenderParams* params) {
   // 1. 字体加载和缩放
   Font* font = load_font(params->font, params->size);
   
   // 2. 文本编码转换
   uint32_t* unicode_chars = text_to_unicode(params->text);
   
   // 3. 逐个字符渲染
   uint16_t cursor_x = params->x;
   for(int i = 0; unicode_chars[i] != 0; i++) {
       // 获取字符位图
       CharBitmap* bitmap = get_char_bitmap(font, unicode_chars[i]);
       
       // 4. 位图渲染到帧缓冲区
       render_char_bitmap(cursor_x, params->y, bitmap, params->color);
       
       // 5. 更新光标位置(考虑字符宽度和间距)
       cursor_x += bitmap->advance + params->spacing;
   }
}
3. 多语言文字处理技术
字符编码处理:
python
def handle_multi_language_text(text):
   """
   处理多语言文本的编码和渲染
   """
   # 编码检测
   if is_ascii_text(text):
       # ASCII文本(英文、数字、符号)
       encoding = 'ascii'
       font_file = 'latin_font.bin'
       
   elif contains_chinese(text):
       # 中文字符检测
       encoding = 'gb2312'  # 或UTF-8
       font_file = 'chinese_font.bin'
       
   else:
       # 其他语言
       encoding = 'utf-8'
       font_file = 'unicode_font.bin'
   
   return encoding, font_file
中文字符渲染优化:
python
def render_chinese_character(char, size):
   """
   中文字符的特殊处理
   """
   # 中文字符特点:
   # - 字形复杂,笔画多
   # - 在点阵字体中需要更高分辨率
   # - 可能需要矢量轮廓渲染
   
   if size < 20:
       # 小字号使用简化字型
       use_simplified_glyph = True
       antialias = False
   else:
       # 大字号使用完整字型,启用抗锯齿
       use_simplified_glyph = False  
       antialias = True
   
   return load_chinese_glyph(char, size, use_simplified_glyph, antialias)
4. 坐标系统和布局算法
文字位置计算:
python
def calculate_text_position(text, size, alignment='center'):
   """
   计算文字在屏幕上的位置
   """
   # 估算文本宽度(近似计算)
   if is_chinese_text(text):
       char_width = size * 0.8  # 中文字符宽度系数
   else:
       char_width = size * 0.6  # 英文字符宽度系数
   
   text_width = len(text) * char_width
   
   # 根据对齐方式计算起始x坐标
   if alignment == 'center':
       x = (DISPLAY_WIDTH - text_width) // 2
   elif alignment == 'left':
       x = 10  # 左边距
   else:  # right
       x = DISPLAY_WIDTH - text_width - 10
   
   return x
实际坐标分析:
python
# 代码中的坐标布局:
英文: (230, 150) - "Hello World!" ≈ 240像素宽,居中:230+120=350(接近320)
中文: (245, 200) - "世界你好!" ≈ 125像素宽,居中:245+62.5=307.5(接近320)  
数字: (230, 260) - "1234567890" ≈ 180像素宽,居中:230+90=320(完美居中)

# 垂直间距:50像素,形成清晰的视觉层次
5. 颜色管理和视觉设计
颜色空间处理:
python
def color_management_system():
   """
   颜色管理和转换
   """
   # RGB888转RGB565(如果显示硬件需要)
   def rgb888_to_rgb565(r, g, b):
       return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
   
   # 伽马校正(可选)
   def gamma_correct(color):
       # 提高在LCD上的显示效果
       return int(pow(color / 255.0, 2.2) * 255)
色彩心理学应用:
python
颜色策略 = {
   "英文": (0, 0, 255),      # 蓝色 - 技术、专业、稳定
   "中文": (0, 255, 127),    # 翠绿 - 自然、和谐、生机  
   "数字": (255, 0, 0)       # 红色 - 重要、警示、突出
}
6. 性能优化技术
字体缓存机制:
python
class FontCache:
   def __init__(self):
       self.cache = {}
       self.max_size = 100  # 最大缓存字符数
   
   def get_char(self, char, size):
       key = (char, size)
       if key in self.cache:
           return self.cache[key]
       
       # 缓存未命中,加载字符
       bitmap = load_char_from_flash(char, size)
       
       # LRU缓存管理
       if len(self.cache) >= self.max_size:
           self.evict_oldest()
       
       self.cache[key] = bitmap
       return bitmap
双缓冲显示技术:
python
def double_buffering_system():
   """
   双缓冲显示,避免闪烁
   """
   # 前台缓冲区:当前显示的内容
   # 后台缓冲区:正在绘制的内容
   
   while True:
       # 在后台缓冲区绘制
       back_buffer.clear()
       back_buffer.draw_text(...)
       
       # 交换缓冲区(原子操作)
       swap_buffers()
7. 异常处理和鲁棒性
资源管理:
python
def safe_resource_management():
   try:
       # 资源申请
       display = Display.init(...)
       media = MediaManager.init()
       
       # 业务逻辑
       main_loop()
       
   finally:
       # 确保资源释放(RAII模式)
       if display:
           Display.deinit()
       if media:
           MediaManager.deinit()
字体回退机制:
python
def robust_text_rendering(text, size, color):
   """
   健壮的文字渲染,处理字体缺失等情况
   """
   try:
       img.draw_string_advanced(x, y, size, text, color)
   except FontNotFoundError:
       # 字体缺失,使用默认字体
       img.draw_string_advanced(x, y, size, "【字体缺失】", color)
   except UnicodeEncodeError:
       # 编码错误,显示替代字符
       img.draw_string_advanced(x, y, size, "???", color)
技术亮点总结
多语言支持:完整的中英文和数字渲染能力
硬件加速:利用显示控制器的图形功能
内存优化:高效的字体缓存和位图管理
视觉设计:科学的颜色搭配和布局算法
系统稳定性:完善的异常处理和资源管理
实时性能:优化的渲染流水线,适合嵌入式环境

这个文字显示系统展示了CanMV K230在嵌入式GUI开发方面的强大能力,为复杂的用户界面应用奠定了坚实的技术基础。

实验场景图  

 

20.jpg
21.jpg

评论

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