[划][OpenCV简单应用]

简介

需要实现一个类似于微信小程序码的圆形码。本文记录早期调研过程和遇到的技术难点。

背景

首先研究了普通二维码的实现原理。扫描二维码时,摄像头捕捉到的图形可以不是标准正方形。识别过程是:通过边缘检测确定三个位置标识点,再根据三点共面进行矩阵变换,得到标准正方形,然后按规律解码信息点。

当然中间还有很多细节需要处理,包括边缘检测算法、矩阵变换原理及实现、冗余容错等等。考虑到已有成熟的实现方案,这里不再重复实现。

技术选型

优先考虑前端实现以支持跨平台,但全局引入 OpenCV 的 JS 包负担较大,自行实现算法难度也较高。因此先从后端实现入手。

后端可以使用 C 或 Python 实现。尝试 C 语言后发现配置复杂,最终选用了 Python。虽然所有语言的包本质上都是通过官方编译工具生成的,但官方编译指南版本较旧,因此直接使用了 pip 版本的 OpenCV。

需求的码原型图大概是:三个同心圆,最小的是实心圆用于定位,次小的透明不遮挡背景,最大的存储信息。透明圆的背景干扰是一个潜在问题,但设计目标是降低遮挡率,避免像普通二维码一样完全覆盖大片区域。

整体思路与普通二维码类似:定位点识别、矩阵变换、信息解析。

实现

第一步,定位点识别。这一步比正方形更复杂,正方形通过边缘检测可以直接识别四个顶点,再根据定位点特征匹配。圆形只能确定一个圆心。一种方案是通过定位圆上的豁口来确定方向,但缺少现成的豁口识别方法。另一种方案是直接通过模板匹配,给定一个标准摆正的目标图,比对源图和目标图的特征点,直接得出变换后的图形,可以跳过部分步骤。

第二步,矩阵变换相对简单。提取 4 个特征点的图内坐标,与特征点的实际坐标联立解矩阵方程,将变换矩阵代入源图,对每个点做映射,得到纠偏后的图像。

第三步未能实现。主要原因是第一步的实现效果不理想:豁口方法缺少直接可用的 API,需要大量自定义开发;模板匹配受分辨率和图形复杂度影响较大,简单图形甚至摄像头误差就可能造成误判。完整实现可能需要较长时间积累相关知识。

Demo 及参考资料

Demo: https://github.com/test3207/spot2

参考资料:

  1. https://docs.opencv.org/

  2. https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_intro/py_intro.html

  3. https://www.numpy.org.cn/user/

  4. https://blog.csdn.net/qq_33635860/article/details/78046838

  5. https://blog.csdn.net/fengyeer20120/article/details/87798638