之前使用ZXing做二维码识别,但是一些稍微不清晰的二维码,它都识别不出来。
https://cloud.tencent.com/developer/article/2115004
这里就寻找到的替代的方式:使用微信开源的二维码识别,效果好多了。
这里推荐
ZXing 做二维码生成。 识别还是使用WeChatQRCode。
微信开源了其二维码的解码功能,并贡献给 OpenCV 社区。
其开源的 wechat_qrcode 项目被收录到 OpenCV contrib 项目中。
从 OpenCV 4.5.2 版本开始,就可以直接使用。
微信的扫码引擎优势
需要安装两个依赖:
添加引用
using OpenCvSharp;
using Point = OpenCvSharp.Point;
using Rect = OpenCvSharp.Rect;
其中
OpenCvSharp4.Extensions 主要是一些辅助的工具 比如Mat和Bitmap的互转。
安装
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
文件夹中。
里面的文件都设置为
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;
}
}
}
}
读取图片
Mat img8 = new Mat(imgpath);
识别
ZQrWeChatUtils.ReadPic(img8);
转换Mat为Bitmap
Bitmap bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(img8);
获取其中二维码区域的图片
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;
}