前言
之前使用ZXing做二维码识别,但是一些稍微不清晰的二维码,它都识别不出来。
https://www.psvmc.cn/article/2022-08-08-qrcode-csharp.html
这里就寻找到的替代的方式:使用微信开源的二维码识别,效果好多了。
这里推荐
ZXing 做二维码生成。
识别还是使用WeChatQRCode。
微信开源了其二维码的解码功能,并贡献给 OpenCV 社区。
其开源的 wechat_qrcode 项目被收录到 OpenCV contrib 项目中。
从 OpenCV 4.5.2 版本开始,就可以直接使用。
微信的扫码引擎优势
- 支持了远距离二维码检测
- 自动调焦定位
- 多码检测识别等功能
- 它是基于 CNN 的二维码检测
微信二维码识别
安装OpenCvSharp4依赖
需要安装两个依赖:
- OpenCvSharp4
- OpenCvSharp4.runtime.win
- OpenCvSharp4.Extensions
添加引用
1 2 3
| using OpenCvSharp; using Point = OpenCvSharp.Point; using Rect = OpenCvSharp.Rect;
|
其中
OpenCvSharp4.Extensions 主要是一些辅助的工具 比如Mat和Bitmap的互转。
安装
1 2 3
| Install-Package OpenCvSharp4 -Version 4.6.0.20220608 Install-Package OpenCvSharp4.runtime.win -Version 4.6.0.20220608 Install-Package OpenCvSharp4.Extensions -Version 4.6.0.20220608
|
注意:
不同版本的OpenCV的语法有些许差别。
下载模型
使用这个二维码识别需要下载模型文件
https://github.com/psvmc/opencv_3rdparty
我这里直接放在了项目的根目录下opencv_3rdparty-wechat_qrcode文件夹中。
里面的文件都设置为
工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| namespace card_scanner.Utils.ZCommon { using System; using System.Text;
using OpenCvSharp;
public class ZQrWeChatUtils { private const string DETECTOR_PROTOTXT_PATH = "opencv_3rdparty-wechat_qrcode/detect.prototxt"; private const string DETECTOR_CAFFE_MODEL_PATH = "opencv_3rdparty-wechat_qrcode/detect.caffemodel"; private const string PROTOTXT_PATH = "opencv_3rdparty-wechat_qrcode/sr.prototxt"; private const string CAFFE_MODEL_PATH = "opencv_3rdparty-wechat_qrcode/sr.caffemodel";
public static string ReadPic(Mat img) { using (WeChatQRCode wechatQrcode = WeChatQRCode.Create( DETECTOR_PROTOTXT_PATH, DETECTOR_CAFFE_MODEL_PATH, PROTOTXT_PATH, CAFFE_MODEL_PATH )) { wechatQrcode.DetectAndDecode( img, out Mat[] rects, out string[] texts ); StringBuilder sb = new StringBuilder(); string result = ""; for (int i = 0; i < rects.Length; i++) { float x1 = rects[i].At<float>(0, 0); float y1 = rects[i].At<float>(0, 1); float x2 = rects[i].At<float>(2, 0); float y2 = rects[i].At<float>(2, 1); result = texts[i]; sb.AppendLine("内容:[" + result + "] 位置:" + x1 + "," + y1 + "," + x2 + "," + y2); Console.WriteLine(@"读取的二维码:" + sb); } return result; } } } }
|
调用
读取图片
1
| Mat img8 = new Mat(imgpath);
|
识别
1
| ZQrWeChatUtils.ReadPic(img8);
|
转换Mat为Bitmap
1
| Bitmap bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(img8);
|
获取其中二维码区域的图片
1 2 3 4 5 6 7 8
| public Bitmap DrawRect(Bitmap bmp, float x1, float y1, float x2, float y2, string text) { g = Graphics.FromImage(bmp); g.DrawRectangle(p, x1, y1, x2 - x1, y2 - y1); g.DrawString(text, drawFont, drawBush, x1, y2); g.Dispose(); return bmp; }
|