2024_7_28
MaixCam学习日志
一、maixpy_v1(废弃)
(一)、image
1.
(二)、 conmm_uart.py(TTL串口接收和发送)
from maix.v1.machine import UART # 导入UART模块
from maix import time # 导入time模块
uart_A = UART("/dev/serial0", 115200) # 创建一个UART对象,设备为"/dev/serial0",波特率为115200
time.sleep_ms(100) # 暂停100毫秒,等待UART接口准备就绪
uart_A.write(b'hello world') # 通过UART接口发送字节字符串"hello world"
# 开始一个无限循环,直到接收到数据或者其他事件发生
while True:
if uart_A.any(): # 检查UART接口是否有任何可读的数据
while uart_A.any(): # 如果有可读的数据,这个内部循环将持续读取数据,直到没有更多的数据
read_data = uart_A.read() # 读取UART接口的数据
print("recv = ", read_data) # 打印接收到的数据
break # 当所有数据都被读取后,跳出无限循环
time.sleep_ms(10) # 暂停10毫秒,等待其他事件
print("deinit") # 打印"deinit"
uart_A.deinit() # 停用UART接口
del uart_A # 删除UART对象
print("exit") # 打印"exit",表示程序已经完成
<1>建立串口对象
uart_A = UART("/dev/serial0", 115200) # 创建一个UART对象,设备为"/dev/serial0",波特率为115200
/dev/serial0
linux系统中的一个特殊的文件路径,用于表示系统中的第一个串行端口。这是设备文件系统(devfs)的一部分,它提供了一种方式来访问硬件设备。
<2>串口发送
uart_A.write(b'hello world') # 通过UART接口发送字节字符串"hello world"
<3>串口接收
if uart_A.any(): # 检查UART接口是否有任何可读的数据
while uart_A.any(): # 如果有可读的数据,这个内部循环将持续读取数据,直到没有更多的数据
read_data = uart_A.read() # 读取UART接口的数据
print("recv = ", read_data) # 打印接收到的数据
break # 当所有数据都被读取后,跳出无限循环
(三)、 lcd.py
#!/usr/bin/env python # 指定脚本解释器
from maix.v1 import lcd, image # 导入lcd和image模块
from maix import time # 导入time模块
img = image.Image("test.jpg") # 创建一个Image对象,加载名为"test.jpg"的图片
lcd.init() # 初始化LCD
lcd.mirror(1) # 设置LCD镜像模式
lcd.display(img) # 在LCD上显示图片
# lcd.clear() # 清除LCD(这行代码被注释掉了,所以不会执行)
print('lcd width:', lcd.width()) # 打印LCD的宽度
print('lcd height:', lcd.height()) # 打印LCD的高度
while True: # 开始一个无限循环
time.sleep(1) # 每次循环都暂停1秒
二、network (网络)
三、peripheral (外设)
( 八 )、uart
8.1—uart—comm_uart.py
from maix import app, uart, pinmap, time
import sys
# 列出所有UART设备
# ports = uart.list_devices()
# 设置引脚功能,将A16设置为UART0的TX(发送)引脚,将A17设置为UART0的RX(接收)引脚
# pinmap.set_pin_function("A16", "UART0_TX")
# pinmap.set_pin_function("A17", "UART0_RX")
# 指定UART设备
device = "/dev/ttyS0"
# 初始化UART设备,波特率为115200
serial0 = uart.UART(device, 115200)
# 发送字符串"hello 1"并换行
serial0.write("hello 1\r\n".encode())
# 发送字符串"hello 2"并换行
serial0.write_str("hello 2\r\n")
# 主循环,直到应用程序需要退出
while not app.need_exit():
# 从UART读取数据
data = serial0.read()
if data:
# 如果有数据,打印数据类型、长度和内容
print("Received, type: {}, len: {}, data: {}".format(type(data), len(data), data))
# 将接收到的数据回传
serial0.write(data)
# 休眠1毫秒,让CPU空闲
time.sleep_ms(1)
四、protocol()
4.1—comm_protocol_custom_method.py(编写自定义通讯协议)
from maix import protocol
from maix import app
from maix.err import Err
# 定义应用程序ID,用于标识当前应用程序
APP_ID = "my_app1"
# 定义回显命令常量,值为0x01
APP_CMD_ECHO = 0x01
# 初始化通信方法,用于发送数据
def send(data:bytes):
# 发送数据的方法,目前为空实现
pass
# 初始化通信方法,用于读取数据
def read():
# 读取数据的方法,目前返回空字节串
return b''
# 设置应用程序ID,便于在响应消息中使用
app.set_app_id(APP_ID)
# 创建协议对象,缓冲区大小为1024字节
p = protocol.Protocol(buff_size = 1024)
# 主循环,直到应用程序需要退出
while not app.need_exit():
# 初始化发送数据变量为None
send_data = None
# 调用read()方法读取数据
data = read()
# 使用协议对象解码读取的数据,得到消息对象
msg = p.decode(data)
# 如果消息对象存在且是请求消息
if msg and msg.is_req:
# 如果消息命令是回显命令
if msg.cmd == APP_CMD_ECHO:
# 创建响应消息,内容为"echo from app {app_id}"
resp_msg = "echo from app {}".format(app.app_id())
# 使用协议对象编码响应消息,表示成功响应
send_data = msg.encode_resp_ok(resp_msg.encode())
# 如果消息命令是设置报告命令
elif msg.cmd == protocol.CMD.CMD_SET_REPORT:
# 使用协议对象编码错误响应消息,表示命令未实现
send_data = msg.encode_resp_err(Err.ERR_NOT_IMPL, "this cmd not support auto upload".encode())
# 如果有发送数据,调用send()方法发送响应数据
if send_data:
send(send_data)
4.2—comm_protocol_yolov5.py()
import struct
from maix import camera, display, image, nn, app
from maix import comm, protocol
from maix.err import Err
# 初始化YOLOv5对象检测模型
detector = nn.YOLOv5(model="/root/models/yolov5s.mud")
# 初始化摄像头,分辨率和格式与模型输入一致
cam = camera.Camera(detector.input_width(), detector.input_height(), detector.input_format())
# 初始化显示屏
dis = display.Display()
# 定义应用程序命令常量
APP_CMD_ECHO = 0x01
APP_CMD_DETECT_RES = 0x02
# 初始化报告开关
report_on = True
def encode_objs(objs):
'''
将对象信息编码为字节数据,用于协议传输
每个对象编码为:2字节x(小端序)+ 2字节y(小端序)+ 2字节w(小端序)+ 2字节h(小端序)+ 2字节class_id(小端序)
'''
body = b''
for obj in objs:
body += struct.pack("<hhHHH", obj.x, obj.y, obj.w, obj.h, obj.class_id)
return body
def decode_objs(body):
'''
将字节数据解码为对象信息,根据指定的协议格式
每个对象编码为:2字节x(有符号,小端序),2字节y(有符号,小端序),2字节w(无符号,小端序),
2字节h(无符号,小端序),2字节class_id(无符号,小端序)
'''
objs = []
i = 0
obj_size = struct.calcsize("<hhHHH") # 计算每个对象数据块的大小
while i < len(body):
# 根据指定格式解码数据
x, y, w, h, class_id = struct.unpack_from("<hhHHH", body, i)
objs.append({'x': x, 'y': y, 'w': w, 'h': h, 'class_id': class_id})
i += obj_size # 移动索引到下一个对象的起始位置
return objs
# 初始化通信对象,根据系统配置初始化UART或TCP服务器
# 可以通过maix.app.get_sys_config_kv("comm", "method")获取当前设置
p = comm.CommProtocol(buff_size = 1024)
while not app.need_exit():
# 接收并解码来自对端的消息
msg = p.get_msg()
if msg and msg.is_req: # 找到消息并且是请求
if msg.cmd == APP_CMD_ECHO:
# 处理回显命令,生成响应消息
resp_msg = "echo from app {}".format(app.app_id())
p.resp_ok(msg.cmd, resp_msg.encode())
elif msg.cmd == protocol.CMD.CMD_SET_REPORT:
# 处理设置报告命令
body = msg.get_body()
report_on = body[0] == 1 # 消息体的第一个字节为0x01表示自动报告,否则禁用报告
resp_body = b'\x01' # 0x01表示设置成功
p.resp_ok(msg.cmd, resp_body)
elif msg and msg.is_report and msg.cmd == APP_CMD_DETECT_RES:
# 处理检测结果报告
print("receive objs:", decode_objs(msg.get_body()))
p.resp_ok(msg.cmd, b'1')
# 检测对象
img = cam.read()
objs = detector.detect(img, conf_th = 0.5, iou_th = 0.45)
# 编码对象信息并发送
if len(objs) > 0 and report_on:
body = encode_objs(objs)
p.report(APP_CMD_DETECT_RES, body)
# 在屏幕上绘制检测结果
for obj in objs:
img.draw_rect(obj.x, obj.y, obj.w, obj.h, color = image.COLOR_RED)
msg = f'{detector.labels[obj.class_id]}: {obj.score:.2f}'
img.draw_string(obj.x, obj.y, msg, color = image.COLOR_RED)
dis.show(img)
五、sensors(传感器)
六、tools(工具)
七、vision(视觉)
(一)、
1.1—ai_vision—nn_classifier.py
使用一个预训练的模型对从相机捕获的图像进行分类,并将分类结果显示在屏幕上
# 导入MaixPy库中的一些模块
from maix import camera, display, image, nn, app
# 创建一个分类器对象,该对象使用了预训练的MobileNetV2模型
classifier = nn.Classifier(model="/root/models/mobilenetv2.mud")
# 初始化一个相机对象,相机的分辨率和格式与分类器的输入匹配
cam = camera.Camera(classifier.input_width(), classifier.input_height(), classifier.input_format())
# 初始化一个显示对象,用于在屏幕上显示图像
disp = display.Display()
# 开始一个循环,只要应用程序没有收到退出信号,就会一直运行
while not app.need_exit():
# 从相机读取一帧图像
img = cam.read()
# 使用分类器对读取的图像进行分类
res = classifier.classify(img)
# 获取分类结果中概率最高的类别的索引和概率
max_idx, max_prob = res[0]
# 生成一个字符串,包含了最可能的类别的概率和标签
msg = f"{max_prob:5.2f}: {classifier.labels[max_idx]}"
# 在图像上绘制一个红色的字符串,显示了分类结果
img.draw_string(10, 10, msg, image.COLOR_RED)
# 将图像的大小调整为显示器的大小
img = img.resize(disp.width(), disp.height(), image.Fit.FIT_CONTAIN)
# 将调整大小后的图像显示在屏幕上
disp.show(img)
1.2—ai_vision—nn_face_recognize.py
2.1—audio—audioplayback.py(播放音频)
# 导入MaixPy库中的一些模块
from maix import audio, time, app
# 创建一个音频播放器对象
p = audio.Player()
# 打印播放器的采样率、格式和通道数
print("sample_rate:{} format:{} channel:{}".format(p.sample_rate(), p.format(), p.channel()))
# 打开一个音频文件,并读取其内容
with open('/root/output.pcm', 'rb') as f:
ctx = f.read()
# 使用播放器播放读取的音频数据
p.play(bytes(ctx))
# 开始一个循环,只要应用程序没有收到退出信号,就会一直运行
while not app.need_exit():
# 暂停10毫秒
time.sleep_ms(10)
# 打印播放完成的消息
print("play finish!")
3 —camera—camera_capture.py(拍照)
# 导入MaixPy库中的一些模块
from maix import camera, display, time, app
# 创建一个相机对象,手动设置分辨率为512x320,因为默认的分辨率太大了
cam = camera.Camera(512, 320)
# 创建一个显示对象,MaixCAM的默认分辨率是552x368
disp = display.Display()
# 开始一个循环,只要应用程序没有收到退出信号,就会一直运行
while not app.need_exit():
# 记录当前的时间
t = time.ticks_ms()
# 从相机读取一帧图像,相机的最大帧率由相机硬件和驱动设置决定
img = cam.read()
# 在显示器上显示图像
disp.show(img)
# 打印出读取和显示图像所花费的时间,以及帧率
print(f"time: {time.ticks_ms() - t}ms, fps: {1000 / (time.ticks_ms() - t)}")
4.1 —display—display_backlight.py(屏幕背光设置)
# 导入MaixPy库中的一些模块
from maix import pwm, time, display, image
# 创建一个显示对象
disp = display.Display()
# 定义一个函数,用于在显示器上显示一个红色的圆和一个字符串
def show(i):
# 创建一个图像对象,大小与显示器的大小相同
img = image.Image(disp.width(), disp.height())
# 在图像上绘制一个红色的圆,圆心位于图像的中心,半径为50
img.draw_circle(disp.width() // 2, disp.height() //2, 50, image.COLOR_RED, thickness=-1)
# 在图像上绘制一个字符串,显示当前的亮度百分比
img.draw_string(2, 2, f"{i}%", image.COLOR_WHITE, scale=2)
# 在显示器上显示图像
disp.show(img)
# 循环100次,每次将显示器的背光亮度增加1%,并显示当前的亮度百分比
for i in range(100):
disp.set_backlight(i)
show(i)
time.sleep_ms(50)
# 循环100次,每次将显示器的背光亮度减少1%,并显示当前的亮度百分比
for i in range(100):
disp.set_backlight(100 - i)
show(100 - i)
time.sleep_ms(50)
4.2 —display—display_backlight.py(屏幕图像显示)
# 导入MaixPy库中的一些模块
from maix import display, app, image
# 创建一个显示对象
disp = display.Display()
# 打印出显示器初始化完成的消息
print("display init done")
# 打印出显示器的大小
print(f"display size: {disp.width()}x{disp.height()}")
# 初始化一个变量y,用于控制文本的垂直位置
y = 0
# 定义要显示的文本
text = "Hello, MaixPy!"
# 开始一个循环,只要应用程序没有收到退出信号,就会一直运行
while not app.need_exit():
# 创建一个新的图像对象,大小与显示器的大小相同,格式为RGB888
img = image.Image(disp.width(), disp.height(), image.Format.FMT_RGB888)
# 在图像上绘制一个红色的矩形,位置由变量y控制,宽度为文本的宽度加10,高度为80
img.draw_rect(0, y, image.string_size(text, scale=2).width() + 10, 80, color=image.Color.from_rgb(255, 0, 0), thickness=-1)
# 在图像上绘制文本,位置由变量y控制,颜色为白色,缩放因子为2
img.draw_string(4, y + 4, text, color=image.Color.from_rgb(255, 255, 255), scale=2)
# 在显示器上显示图像
disp.show(img)
# 更新变量y的值,使其在每次循环时增加1,当达到显示器的高度时回到0
y = (y + 1) % disp.height()
5.1 —image_basic—binary.py(图像处理常见预处理——图像二值化处理)
# 导入MaixPy库中的图像模块
from maix import image
# 1. 加载图像
# 使用image.load函数加载一个名为"test.jpg"的图像文件
src_img = image.load("test.jpg")
# 如果加载失败,则抛出异常
if src_img is None:
raise Exception(f"load image {file_path} failed")
# 2. 对图像进行二值化
# 定义一个阈值元组,用于二值化操作
thresholds = ((0, 100, 20, 80, 10, 80))
# 创建一个源图像的副本
img = src_img.copy()
# 使用binary函数对图像进行二值化操作
img.binary(thresholds)
# 将二值化后的图像保存为"binary.jpg"
img.save("binary.jpg")
5.2 —image_basic—draw_transparent_image.py(图像显示—多图层)
# 导入MaixPy库中的一些模块
from maix import display, image, app, time
# 定义要加载的图像文件的路径
file_path = "/maixapp/share/icon/detector.png"
# 加载图像文件,如果文件的扩展名是.png,则格式为RGBA8888,否则为RGB888
img = image.load(file_path, format = image.Format.FMT_RGBA8888 if file_path.endswith(".png") else image.Format.FMT_RGB888)
# 如果加载图像失败,则抛出异常
if img is None:
raise Exception(f"load image {file_path} failed")
# 创建一个显示对象
disp = display.Display()
# 创建一个新的图像对象,大小与显示器的大小相同,格式为RGBA8888
img_show = image.Image(disp.width(), disp.height(), image.Format.FMT_RGBA8888)
# 在新的图像对象上绘制一个紫色的矩形,覆盖整个图像
img_show.draw_rect(0, 0, img_show.width(), img_show.height(), image.COLOR_PURPLE, thickness=-1)
# 在新的图像对象上绘制加载的图像
img_show.draw_image(0, 0, img)
# 在显示器上显示新的图像对象
disp.show(img_show)
# 开始一个循环,只要应用程序没有收到退出信号,就会一直运行
while not app.need_exit():
# 暂停100毫秒
time.sleep_ms(100)
img是背景图层;img_show是绘图图层
5.3 —image_basic—find_apriltags.py(识别Apriltag信息)
# 导入MaixPy库中的一些模块
from maix import camera, display, image
# 导入ApriltagFamilies模块,这个模块包含了各种Apriltag的定义
from maix.image import ApriltagFamilies
# 创建一个相机对象,分辨率为160x120
cam = camera.Camera(160, 120)
# 创建一个显示对象
disp = display.Display()
# 定义要寻找的Apriltag的类型
families = ApriltagFamilies.TAG36H11
# 开始一个无限循环
while 1:
# 从相机读取一帧图像
img = cam.read()
# 在图像中寻找Apriltags
apriltags = img.find_apriltags(families=ApriltagFamilies.TAG36H11)
# 对于找到的每一个Apriltag
for a in apriltags:
# 获取Apriltag的四个角点
corners = a.corners()
# 对于每一个角点
for i in range(4):
# 在图像上绘制一条连接两个角点的绿色线段
img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_GREEN, 2)
# 在显示器上显示图像
disp.show(img)
Apriltag:贴在设备上标识设备的空间位置
5.4 —image_basic—find_barcode.py(识别条形码信息)
# 导入MaixPy库中的一些模块
from maix import camera, display, image
# 创建一个相机对象,分辨率为320x240
cam = camera.Camera(320, 240)
# 创建一个显示对象
disp = display.Display()
# 开始一个无限循环
while 1:
# 从相机读取一帧图像
img = cam.read()
# 在图像中寻找条形码
barcodes = img.find_barcodes()
# 对于找到的每一个条形码
for b in barcodes:
# 获取条形码的矩形区域
rect = b.rect()
# 在图像上绘制一个蓝色的矩形,表示条形码的位置
img.draw_rect(rect[0], rect[1], rect[2], rect[3], image.COLOR_BLUE, 2)
# 在图像上绘制一个字符串,显示条形码的内容
img.draw_string(0, 0, "payload: " + b.payload(), image.COLOR_GREEN)
# 在显示器上显示图像
disp.show(img)
barcodes = img.find_barcodes():识别条形码
5.5 —image_basic—find_blobs.py(识别色块)
from maix import camera, display, image # 导入maix模块中的camera,display和image类。
cam = camera.Camera(320, 240) # 创建一个Camera对象,分辨率为320x240。
disp = display.Display() # 创建一个Display对象,用于在屏幕上显示图像。
area_threshold = 1000 # 设置颜色块的最小面积阈值。
pixels_threshold = 1000 # 设置颜色块的最小像素数阈值。
thresholds = [[0, 80, -120, -10, 0, 30]] # 设置颜色阈值,用于在图像中查找特定颜色的区域。这里的阈值是为了查找绿色的区域。
while 1: # 无限循环,不断地从摄像头读取图像。
img = cam.read() # 从摄像头读取图像。
blobs = img.find_blobs(thresholds, area_threshold = 1000, pixels_threshold = 1000) # 在图像中查找满足颜色和大小阈值的区域,并返回一个包含这些区域信息的列表。
for b in blobs: # 遍历每个找到的颜色块。
corners = b.corners() # 获取颜色块的角点。
for i in range(4): # 遍历每个角点。
img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED) # 用红线连接角点,在图像上高亮显示颜色块。
disp.show(img) # 将处理后的图像显示在屏幕上。
5.6 —image_basic—find_edges.py(图像处理常见预处理——Canny边缘检测)
from maix import camera, display # 导入maix模块中的camera和display类。
from maix.image import EdgeDetector # 导入maix.image模块中的EdgeDetector类。
cam = camera.Camera(320, 240) # 创建一个Camera对象,分辨率为320x240。
disp = display.Display() # 创建一个Display对象,用于在屏幕上显示图像。
edge_type = EdgeDetector.EDGE_CANNY # 设置边缘检测的类型为Canny边缘检测。
while 1: # 无限循环,不断地从摄像头读取图像。
img = cam.read() # 从摄像头读取图像。
img.find_edges(edge_type, threshold=[50, 100]) # 在图像中查找边缘,使用Canny边缘检测,阈值设置为[50, 100]。
disp.show(img) # 将处理后的图像显示在屏幕上。
# 设置边缘检测的类型为Canny边缘检测。
edge_type = EdgeDetector.EDGE_CANNY
# 在图像中查找边缘,使用Canny边缘检测,阈值设置为[50, 100]。
img.find_edges(edge_type, threshold=[50, 100])
5.7 —image_basic—find_lines.py(图像处理常见预处理——线条检测)
from maix import camera, display, image # 导入maix模块中的camera,display和image类。
import math # 导入math模块,用于进行数学运算。
cam = camera.Camera(320, 240) # 创建一个Camera对象,分辨率为320x240。
disp = display.Display() # 创建一个Display对象,用于在屏幕上显示图像。
threshold = 2000 # 设置线条检测的阈值。
while 1: # 无限循环,不断地从摄像头读取图像。
img = cam.read() # 从摄像头读取图像。
lines = img.find_lines(threshold=2000) # 在图像中查找线条,阈值设置为2000。
for a in lines: # 遍历每个找到的线条。
img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_RED, 2) # 在图像上画出线条,线条的颜色设置为红色,线宽设置为2。
theta = a.theta() # 获取线条的角度。
rho = a.rho() # 获取线条的长度。
angle_in_radians = math.radians(theta) # 将角度转换为弧度。
x = int(math.cos(angle_in_radians) * rho) # 计算x坐标。
y = int(math.sin(angle_in_radians) * rho) # 计算y坐标。
img.draw_line(0, 0, x, y, image.COLOR_GREEN, 2) # 在图像上画出从原点到(x, y)的线条,线条的颜色设置为绿色,线宽设置为2。
img.draw_string(x, y, "theta: " + str(theta) + "," + "rho: " + str(rho), image.COLOR_GREEN) # 在图像上的(x, y)位置显示线条的角度和长度,文本的颜色设置为绿色。
disp.show(img) # 将处理后的图像显示在屏幕上。
# 在图像中查找线条,阈值设置为2000。
lines = img.find_lines(threshold=2000)
检测更细微的线条——降低阈值;只关心更明显的线条——提高阈值
红线的起点和终点就是检测到的线条的两个端点;绿线则是用来表示线条的极坐标表示的,
在极坐标系中,一个点可以通过一个长度(rho)和一个角度(theta)来表示。
5.8 —image_basic—find_qrcodes.py(识别二维码)
from maix import camera, display, image # 导入maix模块中的camera,display和image类。
cam = camera.Camera(320, 240) # 创建一个Camera对象,分辨率为320x240。
disp = display.Display() # 创建一个Display对象,用于在屏幕上显示图像。
while 1: # 无限循环,不断地从摄像头读取图像。
img = cam.read() # 从摄像头读取图像。
qrcodes = img.find_qrcodes() # 在图像中查找二维码,并返回一个包含这些二维码的列表。
for q in qrcodes: # 遍历每个找到的二维码。
corners = q.corners() # 获取二维码的角点。
for i in range(4): # 遍历每个角点。
img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED) # 用红线连接角点,在图像上高亮显示二维码。
img.draw_string(0, 0, "payload: " + q.payload(), image.COLOR_BLUE) # 在图像上的(0, 0)位置显示二维码的内容(payload),文本的颜色设置为蓝色。
disp.show(img) # 将处理后的图像显示在屏幕上。
qrcodes = img.find_qrcodes() # 在图像中查找二维码,并返回一个包含这些二维码的列表。
5.9 —image_basic—image_load_font.py(屏幕显示字符,可设置字体和大小)
from maix import image, display, app, time # 导入maix模块中的image,display,app和time类。
image.load_font("sourcehansans", "/maixapp/share/font/SourceHanSansCN-Regular.otf", size = 32) # 加载名为"sourcehansans"的字体,字体文件位于"/maixapp/share/font/SourceHanSansCN-Regular.otf",字体大小为32。
print("fonts:", image.fonts()) # 打印当前加载的所有字体。
image.set_default_font("sourcehansans") # 将默认字体设置为"sourcehansans"。
disp = display.Display() # 创建一个Display对象,用于在屏幕上显示图像。
img = image.Image(disp.width(), disp.height()) # 创建一个Image对象,大小为屏幕的宽度和高度。
img.draw_string(2, 2, "你好!Hello, world!", image.Color.from_rgb(255, 0, 0)) # 在图像上的(2, 2)位置绘制一段文本,文本的颜色设置为红色。
disp.show(img) # 将处理后的图像显示在屏幕上。
while not app.need_exit(): # 无限循环,直到应用需要退出。
time.sleep(1) # 每次循环后暂停1秒。
5.10 —image_basic—image_load.py(屏幕显示图片)
from maix import display, image, app, time # 导入maix模块中的display,image,app和time类。
file_path = "/maixapp/share/icon/detector.png" # 图片文件的路径。
# 加载图片文件。如果文件路径以".png"结尾,则格式设置为RGBA8888,否则设置为RGB888。
img = image.load(file_path, format = image.Format.FMT_RGBA8888 if file_path.endswith(".png") else image.Format.FMT_RGB888)
if img is None: # 如果加载图片失败,则抛出异常。
raise Exception(f"load image {file_path} failed")
disp = display.Display() # 创建一个Display对象,用于在屏幕上显示图像。
disp.show(img, fit = image.Fit.FIT_CONTAIN) # 将图片显示在屏幕上,图片的大小会被调整以适应屏幕的大小。
while not app.need_exit(): # 无限循环,直到应用需要退出。
time.sleep_ms(100) # 每次循环后暂停100毫秒。
5.11 —image_basic—image_ops.py(用于创建、调整和保存图像)
from maix import image # 导入maix模块中的image类。
img = image.Image(640, 480) # 创建一个Image对象,大小为640x480。
img = img.resize(320, 240) # 将图像的大小调整为320x240。
img.save("test.jpg") # 将图像保存为名为"test.jpg"的文件。
jpg = img.to_jpeg(quality = 95) # 将图像转换为JPEG格式,质量设置为95。
print(jpg.data_size()) # 打印JPEG图像的数据大小。
用于创建、调整和保存图像。
5.12 —image_basic—line_tracking.py(屏幕显示图片)
from maix import camera, display, image # 导入maix模块中的camera,display和image类。
cam = camera.Camera(320, 240) # 创建一个Camera对象,分辨率为320x240。
disp = display.Display() # 创建一个Display对象,用于在屏幕上显示图像。
# thresholds = [[0, 80, 40, 80, 10, 80]] # 红色阈值
thresholds = [[0, 80, -120, -10, 0, 30]] # 绿色阈值
# thresholds = [[0, 80, 30, 100, -120, -60]] # 蓝色阈值
while 1: # 无限循环,不断地从摄像头读取图像。
img = cam.read() # 从摄像头读取图像。
lines = img.get_regression(thresholds, area_threshold = 100) # 在图像中查找满足颜色阈值和面积阈值的线条回归。
for a in lines: # 遍历每个找到的线条回归。
img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2) # 在图像上画出线条,线条的颜色设置为绿色,线宽设置为2。
theta = a.theta() # 获取线条的角度。
rho = a.rho() # 获取线条的长度。
if theta > 90: # 如果角度大于90度。
theta = 270 - theta # 计算新的角度。
else: # 如果角度小于等于90度。
theta = 90 - theta # 计算新的角度。
img.draw_string(0, 0, "theta: " + str(theta) + ", rho: " + str(rho), image.COLOR_BLUE) # 在图像上的(0, 0)位置显示线条的角度和长度,文本的颜色设置为蓝色。
disp.show(img) # 将处理后的图像显示在屏幕上。
get_regression()
使用颜色阈值和面积阈值来查找特定颜色的线条,并提供线条的角度和长度等信息。find_lines()
使用边缘检测技术来查找所有的线条,而不考虑颜色,只提供线条的起点和终点坐标。
6.1 —opencv—opencv_camera.py(边缘检测)
from maix import image, display, app, time, camera # 导入maix模块中的image,display,app,time和camera类。
import cv2 # 导入OpenCV库。
disp = display.Display() # 创建一个Display对象,用于在屏幕上显示图像。
cam = camera.Camera(320, 240) # 创建一个Camera对象,分辨率为320x240。
while not app.need_exit(): # 无限循环,直到应用需要退出。
img = cam.read() # 从摄像头读取图像。
t = time.ticks_ms() # 获取当前时间(毫秒)。
img = image.image2cv(img) # 将maix.image.Image对象转换为numpy.ndarray对象。
print("time: ", time.ticks_ms() - t) # 打印转换所花费的时间。
edged = cv2.Canny(img, 180, 60) # 使用Canny方法检测图像中的边缘。
img_show = image.cv2image(edged) # 将numpy.ndarray对象转换为maix.image.Image对象。
disp.show(img_show) # 将处理后的图像显示在屏幕上。