MicroPython是为了在嵌入式系统中运行Python 3编程语言而设计的轻量级版本解释器。与常规Python相比,MicroPython解释器体积小(仅100KB左右),通过编译成二进制Executable文件运行,执行效率较高。它使用了轻量级的垃圾回收机制并移除了大部分Python标准库,以适应资源限制的微控制器。
MicroPython主要特点包括:
1、语法和功能与标准Python兼容,易学易用。支持Python大多数核心语法。
2、对硬件直接访问和控制,像Arduino一样控制GPIO、I2C、SPI等。
3、强大的模块系统,提供文件系统、网络、图形界面等功能。
4、支持交叉编译生成高效的原生代码,速度比解释器快10-100倍。
5、代码量少,内存占用小,适合运行在MCU和内存小的开发板上。
6、开源许可,免费使用。Shell交互环境为开发测试提供便利。
7、内置I/O驱动支持大量微控制器平台,如ESP8266、ESP32、STM32、micro:bit、掌控板和PyBoard等。有活跃的社区。
MicroPython的应用场景包括:
1、为嵌入式产品快速构建原型和用户交互。
2、制作一些小型的可 programmable 硬件项目。
3、作为教育工具,帮助初学者学习Python和物联网编程。
4、构建智能设备固件,实现高级控制和云连接。
5、各种微控制器应用如物联网、嵌入式智能、机器人等。
使用MicroPython需要注意:
1、内存和Flash空间有限。
2、解释执行效率不如C语言。
3、部分库函数与标准版有差异。
4、针对平台优化语法,订正与标准Python的差异。
5、合理使用内存资源,避免频繁分配大内存块。
6、利用原生代码提升速度关键部位的性能。
7、适当使用抽象来封装底层硬件操作。
总体来说,MicroPython让Python进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
OpenMV Cam 是一款小型、低功耗的微控制器板,可以让你在现实世界中使用机器视觉轻松实现应用程序。你可以使用高级 Python 脚本(由 MicroPython 操作系统提供)而不是 C/C++ 对 OpenMV Cam 进行编程。OpenMV Cam 的技术参数包括以下几个方面:
1、处理器:OpenMV Cam H7 Plus 使用 STM32H743II ARM Cortex M7 处理器,运行频率为 480 MHz,具有 32MB SDRAM + 1MB SRAM 和 32 MB 外部闪存 + 2 MB 内部闪存。OpenMV Cam M4 V2 使用 STM32F427VG ARM Cortex M4 处理器,运行频率为 180 MHz,具有 256KB RAM 和 1 MB 闪存。
2、图像传感器:OpenMV Cam H7 Plus 和 OpenMV Cam M4 V2 都使用 OV7725 图像传感器,能够在分辨率高于 320x240 时以 75 FPS 拍摄 320x240 8 位灰度图像或 320x240 16 位 RGB565 图像,在分辨率低于 320x240 时能够以 150 FPS 拍摄。
3、I/O 接口:OpenMV Cam H7 Plus 和 OpenMV Cam M4 V2 都具有以下 I/O 接口:
(1)全速 USB (12Mbs) 接口,连接到电脑。当插入 OpenMV Cam 后,你的电脑会出现一个虚拟 COM 端口和一个“U盘”。
(2)μSD 卡槽能够进行 100Mbs 读/写,使你的 OpenMV Cam 能够录制视频,并把机器视觉的素材从 μSD 卡提取出来。
(3)SPI 总线的运行速度高达 54Mbs,使你可以简单地把图像流数据传给 LCD 扩展板、WiFi 扩展板,或者其他控制器。
(4)I2C 总线(高达 1Mb/s)、CAN 总线(高达 1Mb/s)和异步串行总线(TX/RX,高达 7.5Mb/s),用于与其他控制器或传感器连接。
(5)一个 12 位 ADC 和一个 12 位 DAC。
(6)所有 I/O 引脚上都有中断和 PWM(板上有 9 或者10个 I/O 引脚)。
4、LED:OpenMV Cam H7 Plus 和 OpenMV Cam M4 V2 都配备了一个 RGB LED(三色)和两个高亮的 850nm IR LED(红外)。
5、镜头:OpenMV Cam H7 Plus 和 OpenMV Cam M4 V2 都配备了标准 M12 镜头接口和一个默认的 2.8 毫米镜头。如果你想在 OpenMV Cam 上使用更专业的镜头,你可以轻松购买并自行安装。
import sensor, image, time
from pyb import UART
from machine import I2C, Pin
from mpu6050 import MPU6050
from fpioa_manager import fm
from machine import RTC
import motion_tracker_gui as mtgui
import motion_tracker_core as mtcore
import motion_tracker_utils as mtutils
import math as m
import numpy as np
import cv2
import os
import sys
import pyblish_barcode as pbb
import qrcodegen as qrg
from pyduino import Arduino as PyDuino
# 初始化摄像头
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
# 设置降落标志的颜色范围
color_ranges = [(30, 100, 15, 127, 15, 127)]
while True:
img = sensor.snapshot()
for color_range in color_ranges:
lower_bound, upper_bound, b, g, r, a = color_range
img = cv2.inRange(img, lower_bound, upper_bound)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
contours, _ = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
if cv2.contourArea(contour) > 500:
(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Image", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
解读:
首先,我们导入所需的库并初始化摄像头。
然后,我们设置降落标志的颜色范围。在这个例子中,我们使用了一个简单的颜色范围(30, 100, 15, 127, 15, 127),你可以根据实际需求调整这个范围。
在无限循环中,我们捕获摄像头的每一帧图像,并将其转换为灰度图像。
对于每个颜色范围,我们使用cv2.inRange()函数提取图像中属于该范围的颜色。
使用cv2.findContours()函数找到图像中的轮廓。
对于每个轮廓,我们计算其面积,如果面积大于某个阈值(例如500),我们认为它是一个降落标志,并在原始图像上绘制一个矩形框。
最后,我们显示处理后的图像,并在按下“q”键时退出程序。
案例2:基于模板匹配的着陆标志检测
import sensor, image, time
from pyb import UART
from machine import I2C, Pin
from mpu6050 import MPU6050
from fpioa_manager import fm
from machine import RTC
import motion_tracker_gui as mtgui
import motion_tracker_core as mtcore
import motion_tracker_utils as mtutils
import math as m
import numpy as np
import cv2
import os
import sys
import pyblish_barcode as pbb
import qrcodegen as qrg
from pyduino import Arduino as PyDuino
# 初始化摄像头
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
# 加载降落标志模板
template = cv2.imread("landing_sign_template.png", 0)
w, h = template.shape[::-1]
while True:
img = sensor.snapshot()
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
if max_val > 0.8:
(x, y) = max_loc
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Image", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
解读:
首先,我们导入所需的库并初始化摄像头。
然后,我们加载降落标志的模板图像。在这个例子中,我们使用了一个简单的模板图像(landing_sign_template.png),你可以根据实际需求替换为其他图像。
在无限循环中,我们捕获摄像头的每一帧图像,并使用cv2.matchTemplate()函数将模板图像与当前帧进行匹配。
使用cv2.minMaxLoc()函数找到匹配结果中的最大值及其位置。
如果最大值大于某个阈值(例如0.8),我们认为找到了一个降落标志,并在原始图像上绘制一个矩形框。
最后,我们显示处理后的图像,并在按下“q”键时退出程序。
案例3:检测单一着陆标志
这个例子通过OpenMV Cam来检测画面中是否存在一个特定的着陆标志。在这个例子中,我们将寻找一个白色的“L”形状的标志。
import sensor
import image
import math
sensor.reset() # 初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为RGB565
sensor.set_framesize(sensor.QVGA) # 设置图像尺寸为QVGA
sensor.skip_frames(time = 2000) # 延迟2000毫秒以等待物体进入视野
while True:
img = sensor.snapshot() # 捕捉一帧图像
找到了吗 = img.find_shape(('L',), scale = 0.4, threshold = 20) # 在图像中寻找“L”形状的标志
if 找到了吗 is not None: # 如果找到标志
print("找到了着陆标志") # 打印消息
else:
print("没有找到着陆标志") # 如果没有找到标志,打印消息
要点解读:这个程序使用find_shape方法寻找画面中的特定形状。在这个例子中,我们在指定的形状和比例范围内寻找“L”形状的标志。如果找到标志,会打印出消息。
案例4:检测多个着陆标志
这个例子通过OpenMV Cam来检测画面中是否存在多个特定的着陆标志。在这个例子中,我们将寻找多个白色的“L”形状的标志。
import sensor
import image
import math
sensor.reset() # 初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为RGB565
sensor.set_framesize(sensor.QVGA) # 设置图像尺寸为QVGA
sensor.skip_frames(time = 2000) # 延迟2000毫秒以等待物体进入视野
while True:
img = sensor.snapshot() # 捕捉一帧图像
for x in range(10): # 在图像中寻找10个“L”形状的标志
找到了吗 = img.find_shapes((('L',),), scale = 0.4, threshold = 20, region = (x*100, x*100, 150, 150)) # 在图像中寻找“L”形状的标志,每个区域大小为150x150,相隔100个像素
if 找到了吗 is not None: # 如果找到标志
print("找到了着陆标志") # 打印消息
break # 如果找到一个标志就跳出循环
else: # 如果循环结束还没有找到标志
print("没有找到着陆标志") # 打印消息
要点解读:这个程序使用find_shapes方法寻找画面中的多个特定形状。在这个例子中,我们尝试在10个不同的区域中寻找“L”形状的标志。如果在一个区域内找到标志,会打印出消息并跳出循环。如果循环结束还没有找到标志,会打印出消息。
案例5:着陆标志跟踪
这个例子通过OpenMV Cam来跟踪画面中特定的着陆标志。在这个例子中,我们将跟踪一个白色的“L”形状的标志。
import sensor
import image
import math
import time
# 初始化摄像头
sensor.reset()
# 设置像素格式为RGB565
sensor.set_pixformat(sensor.RGB565)
# 设置图像尺寸为QVGA
sensor.set_framesize(sensor.QVGA)
# 延迟2000毫秒以等待物体进入视野
sensor.skip_frames(time = 2000)
# 开始捕捉图像流
sensor.start_capture()
try:
while True:
# 等待一帧图像
sensor.wait_for_frames()
# 获取一帧图像
img = sensor.get_frame()
# 在图像中寻找“L”形状的标志
blob = img.find_blob(('L',), scale = 0.4, threshold = 20)
if blob is not None:
# 如果找到标志,打印其在画面中的位置
x, y, w, h = blob['region']
print("着陆标志在画面中的位置是:({x},{y})")
else:
print("没有找到着陆标志")
# 每10帧图像后,清空缓存区并重新开始计时
if sensor.frame_count() % 10 == 0:
time.sleep(0.01)
sensor.clear_frames()
except KeyboardInterrupt:
# 如果按下Ctrl+C,退出循环并停止捕捉图像流
print("程序结束")
sensor.stop_capture()
该程序通过摄像头捕捉图像流,并在每一帧中寻找“L”形状的标志。如果找到标志,则打印其在画面中的位置。每10帧图像后,清空缓存区并重新开始计时,以避免程序失控。如果按下Ctrl+C,程序将退出循环并停止捕捉图像流。
案例6:颜色阈值检测:
import sensor
import image
import time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)
def detect_landing_marker():
while True:
img = sensor.snapshot()
img_hsv = img.to_hsv()
red_threshold = [(0, 100, -128, 127, -128, 127)]
blue_threshold = [(90, 100, -128, 127, -128, 127)]
red_blobs = img_hsv.find_blobs(red_threshold, pixels_threshold=200, area_threshold=200)
blue_blobs = img_hsv.find_blobs(blue_threshold, pixels_threshold=200, area_threshold=200)
if red_blobs:
for blob in red_blobs:
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
print("Red landing marker detected!")
if blue_blobs:
for blob in blue_blobs:
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
print("Blue landing marker detected!")
detect_landing_marker()
要点解读:
该程序使用OpenMV Cam进行着陆标志的颜色阈值检测。
使用OpenMV Cam的sensor和image模块进行图像处理和颜色阈值检测。
初始化摄像头设置,包括像素格式和帧大小等。
使用sensor.skip_frames()函数跳过一些帧以使感光度稳定。
定义了一个detect_landing_marker()函数,用于着陆标志检测。
在函数中,将图像转换为HSV颜色空间,并设置红色和蓝色的阈值。
使用img_hsv.find_blobs()函数查找红色和蓝色的颜色区域,并设置像素和面积的阈值。
如果检测到红色或蓝色的区域,则绘制矩形和十字标记,并输出相应的着陆标志检测结果。
案例7:形状识别:
import sensor
import image
import time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)
def detect_landing_marker():
while True:
img = sensor.snapshot()
img_binary = img.to_grayscale().binary([200])
blobs = img_binary.find_blobs()
if blobs:
for blob in blobs:
if blob.area() > 1000 and blob.area() < 5000:
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
print("Landing marker detected!")
detect_landing_marker()
要点解读:
该程序使用OpenMV Cam进行着陆标志的形状识别。
使用OpenMV Cam的sensor和image模块进行图像处理和形状识别。
初始化摄像头设置,包括像素格式和帧大小等。
使用sensor.skip_frames()函数跳过一些帧以使感光度稳定。
定义了一个detect_landing_marker()函数,用于着陆标志检测。
在函数中,将图像转换为灰度图像,并进行二值化处理。
使用img_binary.find_blobs()函数查找图像中的区域。
对于每个区域,根据面积进行筛选,并绘制矩形和十字标记,并输出相应的着陆标志检测结果。
案例8:模板匹配:
import sensor
import image
import time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)
template = image.Image("landing_marker_template.pgm")
def detect_landing_marker():
while True:
img = sensor.snapshot()
res = img.find_template(template, threshold=0.75, roi=(0, 0, img.width(), img.height()))
if res:
img.draw_rectangle(res.rect(), color=(255, 0, 0))
img.draw_string(res.x(), res.y(), "Landing marker", color=(255, 0, 0))
detect_landing_marker()
要点解读:
该程序使用OpenMV Cam进行着陆标志的模板匹配。
使用OpenMV Cam的sensor和image模块进行图像处理和模板匹配。
初始化摄像头设置,包括像素格式和帧大小等。
使用sensor.skip_frames()函数跳过一些帧以使感光度稳定。
加载着陆标志的模板图像,命名为landing_marker_template.pgm。
定义了一个detect_landing_marker()函数,用于着陆标志检测。
在函数中,获取摄像头的实时图像,并使用img.find_template()函数在图像中查找模板。
设置匹配的阈值和感兴趣区域(ROI),并根据匹配结果在图像上绘制矩形和标注文字,以表示检测到的着陆标志。
这些实际运用的程序案例展示了如何使用MicroPython和OpenMV Cam进行着陆标志检测。其中,颜色阈值检测利用颜色信息进行检测,形状识别通过区域的面积进行筛选,模板匹配使用预定义的模板图像进行匹配。根据具体的需求和场景,可以选择适合的方法来检测和识别着陆标志。
请注意,以上案例只是为了拓展思路,可能存在错误或不适用的情况。不同的硬件平台、使用场景和MicroPython版本可能会导致不同的使用方法。在实际编程中,您需要根据您的硬件配置和具体需求进行调整,并进行多次实际测试。需要正确连接硬件并了解所使用的传感器和设备的规范和特性非常重要。对于涉及到硬件操作的代码,请确保在使用之前充分了解和确认所使用的引脚和电平等参数的正确性和安全性。