用 OpenMV 做一个“看脸”(其实是看卡)的智能门禁:从零搭建全过程
你有没有想过,自家门口那扇老式铁门,也能变得像科幻电影里一样——人还没靠近,锁就自动开了?
当然,我们不是真的靠“看脸”解锁(OpenMV 虽强,但跑不动人脸识别大模型),而是通过识别一张卡片、一个图案、甚至是一枚贴纸来判断是否放行。整个系统成本不过两三百块,代码不到50行,却能实现非接触、可编程、带记录的现代门禁功能。
核心主角就是这块小板子:OpenMV。它看起来像个微型摄像头,其实是个“会思考的眼睛”。今天我就带你一步步把它变成家门口的智能守卫。
为什么选 OpenMV?因为它够“傻瓜”
先说个现实问题:你想做个视觉识别项目,传统做法是啥?
- 搞个树莓派 + USB摄像头;
- 安装 Linux 系统;
- 配 OpenCV;
- 写 Python 脚本;
- 外接一堆电源线和显示器……
结果设备比门锁还大,功耗堪比台灯,调试三天才点亮 LED。
而 OpenMV 的出现,就是为了打破这种繁琐。它是专为嵌入式视觉设计的小型化模块,集成了摄像头、处理器、RAM 和 MicroPython 运行环境。你可以直接用类似 Python 的脚本控制它,不用管底层驱动、内存管理或者操作系统。
换句话说:你会写 Python,就能让这颗“电子眼”看懂世界。
我手上这块是 OpenMV Cam H7 Plus,主频480MHz,支持640×480分辨率拍摄,运行一个颜色识别算法只要几十毫秒。最关键的是——它能独立运行,插上电就开始干活,完全不需要连接电脑。
核心思路:不是“认人”,是“认物”
我们的目标很明确:当授权用户展示特定物体时,门自动打开。
这个“物体”可以是:
- 一张红色塑料卡(颜色识别)
- 一个印有 AprilTag 的钥匙扣(标签识别)
- 一张定制图案的纸片(模板匹配)
相比指纹或密码,这种方式无需物理接触;相比人脸识别,它对算力要求极低,更适合在边缘端实时处理。
整个系统的逻辑非常清晰:
- 摄像头拍照;
- 判断图中有没有“正确的东西”;
- 有 → 开锁;没有 → 不动;
- 开完3秒后自动上锁。
就这么简单。
硬件怎么搭?四样东西搞定
别被“智能系统”吓到,实际硬件组成极其精简:
| 组件 | 功能 |
|---|---|
| OpenMV Cam | 视觉识别大脑 |
| 电磁锁 | 执行开关动作 |
| 继电器模块 | 控制高电压通断 |
| 电源(5V/12V) | 供电 |
接线也很直观:
- OpenMV 的某个 GPIO 引脚(比如 P0)接到继电器的信号输入端;
- 继电器输出端串联在电磁锁的供电回路中;
- 所有设备共地。
这样,OpenMV 输出高电平 → 继电器吸合 → 电磁锁断电释放 → 门打开。
⚠️ 注意安全:电磁锁通常工作在12V以上,务必做好高低压隔离。建议使用光耦继电器模块,避免反向电流损坏 OpenMV。
如果你还想更进一步,加个 ESP-01S Wi-Fi 模块,串口连上 OpenMV,每次开门都能往服务器发一条日志:“2025-04-05 14:32,ID=5 的员工已进入”。
软件怎么写?一行一行讲明白
下面这段代码,就是整个门禁系统的“灵魂”。
import sensor, image, time, pyb # 初始化摄像头 sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) # 320x240 sensor.skip_frames(time=2000) sensor.set_auto_gain(False) sensor.set_auto_whitebal(False) # 定义红色阈值 (LAB格式) red_threshold = (30, 100, 15, 127, 15, 127) # 设置继电器引脚 relay_pin = pyb.Pin("P0", pyb.Pin.OUT_PP) relay_pin.low() # 初始锁定 while True: img = sensor.snapshot() # 查找符合颜色的区域 blobs = img.find_blobs([red_threshold], pixels_threshold=100, area_threshold=100) if blobs: max_blob = max(blobs, key=lambda b: b.pixels()) img.draw_rectangle(max_blob.rect()) img.draw_cross(max_blob.cx(), max_blob.cy()) print("Detected at (%d, %d)" % (max_blob.cx(), max_blob.cy())) relay_pin.high() # 开锁 time.sleep(3) # 保持3秒 relay_pin.low() # 上锁 time.sleep_ms(50)我们来逐段拆解它的“思维过程”:
第一步:告诉摄像头“你要看清什么”
sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA)设置成彩色模式(RGB565),方便做颜色识别;分辨率设为 QVGA(320x240),既保证视野又不至于拖慢速度。
第二步:固定曝光和白平衡
sensor.set_auto_gain(False) sensor.set_auto_whitebal(False)这是关键!如果让摄像头自动调节增益和白平衡,每次光照稍变,颜色就会漂移。关掉自动,才能稳定识别同一张红卡。
第三步:定义“什么是红色”
red_threshold = (30, 100, 15, 127, 15, 127)这里用的是LAB 色彩空间,比 RGB 更接近人眼感知。三个通道分别是:
- L:亮度(30~100)
- A:红绿色调(15~127 表示偏红)
- B:黄蓝色调(15~127 同样表示偏红)
这个数值不是瞎写的。你需要用 OpenMV IDE 自带的“阈值编辑器”工具,在真实环境下取样几次,找到最稳定的范围。
第四步:看到目标就开锁
blobs = img.find_blobs([...]) if blobs: relay_pin.high() time.sleep(3) relay_pin.low()find_blobs()会返回所有符合条件的颜色块。我们取面积最大的那个,防止误触发。一旦检测到,立刻拉高 GPIO,驱动继电器。
延时3秒是为了让人顺利通过,之后自动恢复锁定状态。
除了“红卡”,还能怎么识别?
颜色识别最简单,但也最容易翻车——阴天、背光、反光都可能导致失败。那怎么办?换方法!
方法一:用 AprilTag 标签,精准又防伪
AprilTag 就像是二维码和 AR Marker 的结合体,长得像一个小方块,里面是黑白格子组成的编码图案。
优点非常明显:
- 可以给每个标签分配唯一 ID;
- 抗干扰能力强,轻微污损也能识别;
- 支持姿态估计,理论上还能测距离。
代码也超级简单:
tags = img.find_apriltags(families=image.TAG36H11) for tag in tags: if tag.id == 5: # 只有 ID=5 的卡才允许通行 relay_pin.high() time.sleep(3) relay_pin.low()你可以打印几个不同 ID 的标签,分别对应管理员、普通员工、访客,轻松实现权限分级。
而且这种标签很难伪造——随便画个方块根本骗不过算法。
方法二:模板匹配,适合复杂图案
如果你想识别一张带 logo 的卡片、一个卡通形象,可以用“模板匹配”。
原理就是:先把标准图像存进 OpenMV(比如叫template.bmp),然后每一帧都拿去比对相似度。
template = image.Image("/template.bmp") r = img.find_template(template, 0.70, step=4, search=image.SEARCH_EX) if r: print("Match found!") relay_pin.high() time.sleep(3) relay_pin.low()0.70是匹配阈值,意味着相似度超过70%才算成功。step=4表示跳格搜索,加快速度。
缺点是对角度、缩放敏感,最好正对着拍。但胜在灵活,几乎任何静态图案都能识别。
实际部署中的坑,我都踩过了
你以为写完代码就能万事大吉?Too young.
我在实验室测试时一切正常,一搬到走廊立马失灵。原因五花八门:
问题1:光线一变,颜色全崩
解决办法:
- 固定曝光时间(sensor.set_exposure_us(10000));
- 加装补光灯(推荐暖白光LED条);
- 或者干脆放弃颜色识别,改用 AprilTag。
问题2:继电器咔哒响,但锁打不开
排查发现:电磁锁启动电流大,而 OpenMV 的电源带不动。必须分开供电,且共地连接可靠。
另外记得给继电器并联一个续流二极管,否则断开瞬间的反电动势可能烧毁电路。
问题3:误识别,陌生人也能进门
加一层确认机制:
confirmed = 0 if blobs: confirmed += 1 else: confirmed = max(0, confirmed - 1) if confirmed >= 2: # 连续两帧识别成功才触发 relay_pin.high() time.sleep(3) relay_pin.low() confirmed = 0这样能有效过滤瞬时干扰。
还能怎么升级?让它变得更聪明
基础版搞定了,接下来可以玩点高级的:
✅ 加蜂鸣器提示音
- 成功:短“滴”一声;
- 失败:长“呜——”一声。
✅ 加状态灯
- 红灯常亮:待机;
- 绿灯闪:识别成功;
- 蓝灯闪:联网上传中。
✅ 接 SD 卡记日志
每条记录包括时间、识别类型、坐标、置信度,出问题了随时回溯。
✅ OTA 更新识别参数
通过 Wi-Fi 模块远程修改颜色阈值或替换模板图,不用每次都拆机器。
总结一下:谁适合做这个项目?
这套系统特别适合以下场景:
- 学生宿舍门禁(每人发个彩色卡)
- 小型办公室进出管理(用 AprilTag 员工卡)
- 实验室设备间管控(防止无关人员进入)
- 智能家居联动(识别手势图标触发场景)
它的最大优势不是多先进,而是够简单、够便宜、够可靠。一套下来硬件成本不超过300元,开发周期一天以内,还能作为教学案例让学生理解“感知-决策-执行”的完整闭环。
更重要的是,你不再是在“跑通一个例程”,而是在构建一个真正可用的智能终端。
如果你正在寻找一个既能练手又有实用价值的嵌入式项目,不妨试试用 OpenMV 做一个属于你的智能门禁。
当你第一次看到那扇门因为你手中的一张小卡片缓缓打开时,那种成就感,不亚于造出一台机器人。
对了,文中的完整代码我已经打包好,关注公众号回复“openmv-door”即可获取。
如果你在实现过程中遇到任何问题,欢迎留言交流。