C# OpenCvSharp+ 微信二维码引擎实现二维码识别
微信开源了其二维码的解码功能,并贡献给 OpenCV 社区。其开源的 wechat_qrcode 项目被收录到 OpenCV contrib 项目中。从 OpenCV 4.5.2 版本开始,就可以直接使用。
该项目 github 地址:
https://github.com/opencv/opencv_contrib/tree/master/modules/wechat_qrcode
模型文件的地址:
https://github.com/WeChatCV/opencv_3rdparty
微信的扫码引擎,很早就支持了远距离二维码检测、自动调焦定位、多码检测识别等功能,它是基于 CNN 的二维码检测。
OpenCvSharp在 4.6.0.20220608 版本也加入了支持
效果
代码
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace OpenCvSharp_微信二维码引擎
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
const string detector_prototxt_path = "detect.prototxt";
const string detector_caffe_model_path = "detect.caffemodel";
const string prototxt_path = "sr.prototxt";
const string caffe_model_path = "sr.caffemodel";
private string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
WeChatQRCode wechatQrcode = null;
Mat src = null;
Bitmap bitmap = null;
Stopwatch sw = null;
StringBuilder sb = null;
Graphics g = null;
Pen p = new Pen(Brushes.Red);
SolidBrush drawBush = new SolidBrush(Color.Red);
Font drawFont = new Font("Arial", 8, FontStyle.Bold, GraphicsUnit.Millimeter);
void Detect(string location)
{
sw = new Stopwatch();
sw.Start();
src = Cv2.ImRead(location);
bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(src);
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
pictureBox1.Image = bitmap;
wechatQrcode.DetectAndDecode(src, out var rects, out var texts);
sw.Stop();
sb = new StringBuilder();
sb.AppendLine("耗时:" + sw.ElapsedMilliseconds.ToString() + "ms");
for (int i = 0; i < rects.Length; i++)
{
var x1 = rects[i].At<float>(0, 0);
var y1 = rects[i].At<float>(0, 1);
var x2 = rects[i].At<float>(2, 0);
var y2 = rects[i].At<float>(2, 1);
string result = texts[i];
DrawRect(bitmap, x1, y1, x2, y2, result);
sb.AppendLine("内容:[" + result + "] 位置:" + x1 + "," + y1 + "," + x2 + "," + y2);
}
MessageBox.Show(sb.ToString(), "识别信息");
}
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;
}
private void button2_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = fileFilter;
if (ofd.ShowDialog() == DialogResult.OK)
{
Detect(ofd.FileName);
}
}
private void Form1_Load(object sender, EventArgs e)
{
wechatQrcode = OpenCvSharp.WeChatQRCode.Create(
detector_prototxt_path
, detector_caffe_model_path
, prototxt_path
, caffe_model_path);
}
private void button1_Click(object sender, EventArgs e)
{
Detect("test.png");
}
}
}