**非常详细的视频和文字教程,讲解常见的openmv教程包括 巡线、物体识别、圆环识别、阈值自动获取等。非常适合学习openmv、K210、K230等项目
视频合集链接在
openmv教程合集 openmv入门到项目开发 openmv和STM32通信 openmv和opencv区别 openmv巡线 openmv数字识别教程LCD
专刊openmv视觉文章链接: https://blog.csdn.net/qq_46187594/category_12900902.html
2-匹配多个模板的
上面我们演示了如何实现匹配一个模板的,下面演示如何实现匹配多个模板的
首先把直接处理的文件都放进去pgm 按照一定的命名都放到openmv识别成的U盘里面
然后下面是我们的0-9数字识别功能代码
# 多模板匹配系统 - 数字识别增强版
# 核心功能:
# 1. 支持0-9数字模板实时匹配
# 2. 可视化识别结果及性能指标
# 3. 结构化数据输出import time
import sensor
import image
from image import SEARCH_EX # 导入穷举搜索模式# ******************** 摄像头初始化配置 ********************
sensor.reset() # 复位摄像头硬件
sensor.set_contrast(1) # 设置对比度(范围0-3)
sensor.set_gainceiling(16) # 设置最大增益值(防止过曝光)
sensor.set_framesize(sensor.QQVGA) # 设置图像分辨率160x120
sensor.set_pixformat(sensor.GRAYSCALE) # 使用灰度图像模式(提升处理速度)
sensor.set_vflip(True) # 垂直翻转图像(根据摄像头物理安装方向调整)
sensor.set_hmirror(True) # 水平镜像图像(根据实际需要调整)# ******************** 用户可配置参数 ********************
TEMPLATE_PATHS = [ # 模板文件路径列表"/0.pgm", "/1.pgm", "/2.pgm", # 模板文件应存放在OpenMV存储根目录"/3.pgm", "/4.pgm", "/5.pgm", # 建议使用32x32像素灰度图像"/6.pgm", "/7.pgm", "/8.pgm", "/9.pgm"
]
MATCH_THRESHOLD = 0.70 # 匹配相似度阈值(0.0-1.0,值越大匹配越严格)
SEARCH_STEP = 4 # 搜索步长(增大可提升速度但降低精度)
TEXT_COLOR = 255 # 显示文本颜色(灰度模式下255=白色)
TEXT_OFFSET = 5 # 文本与识别框的垂直间距(像素)# ******************** 模板预加载系统 ********************
class TemplateLoader:"""模板加载管理器,实现:1. 启动时预加载所有模板到内存2. 自动从文件路径提取模板名称3. 提供错误加载提示功能"""def __init__(self):self.templates = [] # 模板存储列表self.load_templates() # 初始化时自动加载模板def load_templates(self):"""加载并验证所有模板文件"""for path in TEMPLATE_PATHS:try:# 从文件路径提取模板名称(示例:"/9.pgm" -> "9")# split("/")[-1]获取文件名,split(".")[0]去除扩展名name = path.split("/")[-1].split(".")[0]# 构建模板字典对象template = {"image": image.Image(path), # 加载模板图像到内存"name": name, # 存储简化名称"path": path # 保留完整路径用于调试}self.templates.append(template)print(f"预加载成功:{path} -> {name}")except Exception as e:# 捕获文件不存在或格式错误等异常print(f"加载失败:{path} ({str(e)})")# 实例化模板加载器(程序启动时自动执行加载)
template_loader = TemplateLoader()# 初始化性能计数器(用于计算帧率)
clock = time.clock()# ******************** 主处理循环 ********************
while(True):clock.tick() # 开始帧计时# 图像采集处理流程img = sensor.snapshot() # 捕获一帧图像# 多模板匹配流程for template in template_loader.templates:# 执行模板匹配操作# find_template参数说明:# template - 预加载的模板图像对象# threshold - 相似度阈值# step - 搜索步长(影响速度和精度)# search - 搜索模式(SEARCH_EX为全搜索)result = img.find_template(template["image"], MATCH_THRESHOLD,step=SEARCH_STEP,search=SEARCH_EX)if result: # 当匹配结果有效时# 解包匹配区域坐标(x,y)和尺寸(width,height)x, y, w, h = result# 可视化处理部分# 绘制红色矩形框标记识别区域(颜色值255在灰度模式显示为白色)img.draw_rectangle(result, color=TEXT_COLOR)# 计算文本显示位置(防止超出图像上边界)text_y = y - TEXT_OFFSET if y > TEXT_OFFSET else 0# 在识别框上方显示模板名称# 参数说明:# x - 文本左上角X坐标(对齐识别框左侧)# text_y - 垂直位置(识别框上方5像素)# template["name"] - 显示的文本内容# color - 文本颜色# scale - 字体缩放比例# mono_space - 启用等宽字体显示img.draw_string(x, text_y, template["name"],color=TEXT_COLOR, scale=1, mono_space=True)# 数据输出部分# 输出格式:[时间戳] 识别到 模板名称 坐标: (中心X, 中心Y)print("[{:.0f}] 识别到 {} 坐标: ({},{})".format(time.ticks_ms(), # 获取系统毫秒时间戳template["name"], # 模板名称x + w//2, # 计算区域中心X坐标y + h//2 # 计算区域中心Y坐标))# 实时性能显示fps = clock.fps() # 计算实际帧率# 在画面左上角显示帧率信息(避免遮挡识别结果)# 参数5,5表示距离左上角5像素的起始位置img.draw_string(5, 5, "FPS:%.1f" % fps, color=TEXT_COLOR)
识别到会输出在
注意:如果觉得经常误识别,可以调整识别的匹配阈值
MATCH_THRESHOLD = 0.70 # 匹配相似度阈值(0.0-1.0,值越大匹配越严格)