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

API 文档
draw_circle
image.draw_circle(x, y, radius[, color[, thickness=1[, fill=False]]])
在图像上绘制一个圆形。参数可以分别传入 x, y, radius,也可以作为元组 (x, y, radius) 一起传递。
color: 表示颜色的 RGB888 元组,适用于灰度或 RGB565 图像,默认为白色。对于灰度图像,还可以传递像素值(范围 0-255);对于 RGB565 图像,可以传递字节翻转的 RGB565 值。
thickness: 控制圆形边框的像素宽度,默认为 1。
fill: 设置为 True 时,将填充圆形内部,默认为 False。
该方法返回图像对象,允许通过链式调用其他方法。
【花雕动手做】CanMV K230 AI 视觉识别模块之使用draw_circle方法绘制圆形
测试实验代码
# 【花雕动手做】CanMV K230 AI 视觉识别模块之使用draw_circle方法绘制圆形
# 导入系统基础模块
import time, os, urandom, sys, math # 时间、操作系统、随机数、系统、数学运算
# 导入显示和媒体相关模块
from media.display import * # 显示控制
from media.media import * # 媒体管理
# 定义显示分辨率常量(640x480)
DISPLAY_WIDTH = 640
DISPLAY_HEIGHT = 480
def display_test():
"""
测试显示功能的函数
功能:绘制一个复杂的圆形图案(类似汽车轮毂设计)
"""
# ========== 初始化阶段 ==========
# 创建主背景图像(ARGB8888格式支持透明度)
img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
img.clear() # 清空图像
# 绘制白色背景(覆盖整个显示区域)
img.draw_rectangle(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, color=(255,255,255), fill=True)
# 初始化显示器(使用ST7701驱动芯片)
Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
# 初始化媒体管理器
MediaManager.init()
try:
# ========== 绘制主图案 ==========
# 1. 主轮廓(双层同心圆)
img.draw_circle(320, 240, 150, color=(50, 50, 50), thickness=8) # 外圈(灰色,线宽8)
img.draw_circle(320, 240, 130, color=(80, 80, 80), thickness=5) # 内圈(浅灰,线宽5)
# 2. 中心轮毂(三层结构)
img.draw_circle(320, 240, 40, color=(100, 100, 100), fill=True) # 填充灰色圆盘
img.draw_circle(320, 240, 40, color=(50, 50, 50), thickness=3) # 轮毂边框(深灰)
img.draw_circle(320, 240, 15, color=(30, 30, 30), fill=True) # 轮毂中心(黑色)
# 3. 辐条(8根均匀分布)
for i in range(8):
# 计算每根辐条的角度(360度均分)
angle = i * (360 / 8)
# 计算外端点坐标(130半径处)
x_outer = int(320 + 130 * math.cos(math.radians(angle)))
y_outer = int(240 + 130 * math.sin(math.radians(angle)))
# 计算内端点坐标(40半径处)
x_inner = int(320 + 40 * math.cos(math.radians(angle)))
y_inner = int(240 + 40 * math.sin(math.radians(angle)))
# 绘制辐条两端的小圆点(装饰效果)
img.draw_circle(x_outer, y_outer, 10, color=(70, 70, 70), fill=True) # 外端点
img.draw_circle(x_inner, y_inner, 8, color=(70, 70, 70), fill=True) # 内端点
# 4. 装饰性螺栓(16个均匀分布的小圆点)
for i in range(16):
angle = i * (360 / 16) # 更密集的分布
# 计算螺栓位置(140半径处)
x = int(320 + 140 * math.cos(math.radians(angle)))
y = int(240 + 140 * math.sin(math.radians(angle)))
# 绘制黑色小圆点
img.draw_circle(x, y, 5, color=(40, 40, 40), fill=True)
# ========== 显示输出 ==========
Display.show_image(img) # 将绘制好的图像显示到屏幕
# 保持显示(实际不会执行到这里,因为下面是无限循环)
while True:
time.sleep(2) # 每2秒检查一次退出条件
# ========== 异常处理 ==========
except KeyboardInterrupt as e:
print("用户中断: ", e) # 捕获Ctrl+C中断
except BaseException as e:
print(f"发生异常: {e}") # 捕获其他所有异常
# ========== 清理阶段 ==========
Display.deinit() # 反初始化显示器
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP) # 启用睡眠模式退出点
time.sleep_ms(100) # 短暂延时
MediaManager.deinit() # 释放媒体资源
# 程序主入口
if __name__ == "__main__":
os.exitpoint(os.EXITPOINT_ENABLE) # 启用退出点功能
display_test() # 执行显示测试函数代码解读
一、核心功能解析
1. 图形绘制逻辑
程序通过draw_circle()方法实现分层圆形图案绘制,模拟汽车轮毂结构:
主轮廓:双层同心圆(外圈150px/内圈130px)
中心轮毂:三层结构(灰色填充盘+深灰边框+黑色中心点)
辐条系统:8根辐条通过计算圆上坐标实现均匀分布
装饰细节:16个螺栓孔围绕主轮廓分布
2. 数学计算关键点
python
angle = i * (360 / n) # 均分角度计算
x = center_x + radius * math.cos(math.radians(angle)) # 极坐标转直角坐标
y = center_y + radius * math.sin(math.radians(angle))
使用三角函数将极坐标转换为屏幕像素坐标
角度需先转换为弧度(math.radians())
坐标取整处理(int())确保像素对齐
3. 显示控制流程
创建画布 → 2. 绘制图形 → 3. 初始化硬件 → 4. 显示输出 → 5. 异常处理 → 6. 资源释放
二、技术实现亮点
1. 硬件抽象层设计
通过Display.init()和MediaManager.init()实现硬件解耦
支持ST7701驱动芯片的显示器
使用os.exitpoint()管理低功耗模式
2. 图形渲染优化
ARGB8888格式支持透明度(虽未使用alpha通道)
分层绘制策略:先背景后前景,避免重复渲染
装饰元素使用填充圆点提升视觉效果
3. 异常安全机制
python
try:
# 业务逻辑
except KeyboardInterrupt:
# 用户中断处理
finally:
# 确保资源释放
捕获Ctrl+C中断和系统异常
显式调用反初始化方法释放硬件资源
100ms延时确保硬件稳定
三、扩展应用建议
1. 动态效果实现
python
# 示例:添加旋转动画
for frame in range(36): # 36帧动画
img.clear()
img.draw_rectangle(0,0,640,480,(255,255,255),True)
# 绘制动态辐条(随帧数旋转)
for i in range(8):
angle = i*45 + frame*10 # 基础角度+动态偏移
# ...(坐标计算代码)
Display.show_image(img)
time.sleep(0.05)
2. 交互功能扩展
python
# 添加触摸检测(需硬件支持)
from media.touch import Touch
touch = Touch()
while True:
if touch.read() == Touch.PRESSED:
x, y = touch.position()
if (x-320)**2 + (y-240)**2 < 150**2: # 检测点击是否在外圈内
print("点击了轮毂区域")
3. 性能优化方向
使用图像缓冲区减少重复计算
对静态元素预渲染到位图
采用差分更新机制(仅刷新变化区域)
四、潜在问题排查
显示异常:
检查to_ide=True参数是否与实际硬件匹配
确认分辨率常量与显示器物理尺寸一致
内存不足:
ARGB8888格式占用内存较大(640×480×4字节)
可改用RGB565格式减少内存占用
坐标错位:
确保三角函数计算后取整
检查显示器方向设置(可能需要坐标变换)
五、代码结构示意图
main()
├─ 初始化阶段
│ ├─ 创建画布
│ ├─ 硬件初始化
│ └─ 绘制白色背景
├─ 图形渲染
│ ├─ 主轮廓(双圆)
│ ├─ 中心轮毂(三层)
│ ├─ 辐条系统(8根)
│ └─ 装饰螺栓(16个)
├─ 显示输出
│ └─ 图像刷新
└─ 资源释放
├─ 显示器反初始化
└─ 媒体管理器释放
实验场景图



返回首页
回到顶部
评论