java通过opencv解析二维码(微信开源解码工具)

以往java解析二维码都是使用google.zxing,但是zxing解析二维码的成功率比较低,很多美化或者个性化的二维码无法解析。

微信开源了其二维码的解码功能,并贡献给 OpenCV 社区。其开源的 wechat_qrcode 项目被收录到 OpenCV contrib 项目中。从 OpenCV 4.5.2 版本开始,就可以直接使用。

先导入依赖包

XML 复制代码
<dependency>
   <groupId>org.bytedeco</groupId>
   <artifactId>javacpp</artifactId>
   <version>1.5.7</version>
   <classifier>windows-x86_64</classifier>
</dependency>
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>openblas</artifactId>
    <version>0.3.19-1.5.7</version>
    <classifier>windows-x86_64</classifier>
</dependency>
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>opencv</artifactId>
    <version>4.5.5-1.5.7</version>
</dependency>
<dependency>
     <groupId>org.bytedeco</groupId>
     <artifactId>opencv</artifactId>
      <version>4.5.5-1.5.7</version>
      <classifier>windows-x86_64</classifier>
</dependency>

以上依赖用于windows系统 如果要发布到liunx系统把windows-x86_64改成liunx-x86_64

下面是解析代码

java 复制代码
package com.dyserver.bean;

import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.StringVector;
import org.bytedeco.opencv.opencv_wechat_qrcode.WeChatQRCode;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.imageio.ImageIO;

import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;

/**
 * @author ChenYi
 */
public class WeChatDeCode {

	public static void main(String... args) {
		Mat img = imread("d:\\img" + "\\" + "1.png");
		System.out.println(deCode(img));
		
		//下载二维码到本地识别
		String url="";
		System.out.println(openPic(url));
	}

	public static String openPic(String url) {

		String savePath = "d:\\img";
		String filename = UUID.randomUUID().toString() + ".jpg";
		String re="0";
		try {
			dxz(url, savePath, filename);		
			Mat img = imread(savePath + "\\" + filename);
			re=deCode(img);
			//如果识别失败那么尝试放大缩小图片尝试识别,提高准确率
			if(re.equals("0")) {
				ys(savePath, filename);
				Mat img1 = imread(savePath + "\\1_" + filename);
				re=deCode(img1);
			}
			if(re.equals("0")) {
				fd(savePath, filename);
				Mat img2 = imread(savePath + "\\2_" + filename);
				re=deCode(img2);
			}
			return re;
			
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "0";
		}
	}

	private static void ys(String savePath, String filename) throws Exception {
		try {
			// 读取原始图片
			BufferedImage image = ImageIO.read(new FileInputStream(savePath + "\\" + filename));
			System.out.println("Width: " + image.getWidth());
			System.out.println("Height: " + image.getHeight());
			// 调整图片大小
			BufferedImage newImage = ImageUtils.resizeImage(image, image.getWidth()*2, image.getHeight()*2);
			// 图像缓冲区图片保存为图片文件(文件不存在会自动创建文件保存,文件存在会覆盖原文件保存)
			ImageIO.write(newImage, "jpg", new File(savePath + "\\1_" + filename));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void fd(String savePath, String filename) throws Exception {
		try {
			// 读取原始图片
			BufferedImage image = ImageIO.read(new FileInputStream(savePath + "\\" + filename));
			System.out.println("Width: " + image.getWidth());
			System.out.println("Height: " + image.getHeight());
			// 调整图片大小
			BufferedImage newImage = ImageUtils.resizeImage(image, 200, 200);
			// 图像缓冲区图片保存为图片文件(文件不存在会自动创建文件保存,文件存在会覆盖原文件保存)
			ImageIO.write(newImage, "jpg", new File(savePath + "\\2_" + filename));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void dxz(String urlString, String savePath, String filename) throws Exception {
		// 构造URL
		URL url = new URL(urlString);
		// 打开连接
		URLConnection con = url.openConnection();
		// 设置请求超时为20s
		con.setConnectTimeout(20 * 1000);
		// 文件路径不存在 则创建
		File sf = new File(savePath);
		if (!sf.exists()) {
			sf.mkdirs();
		}
		// jdk 1.7 新特性自动关闭
		try (InputStream in = con.getInputStream();
				OutputStream out = new FileOutputStream(sf.getPath() + "\\" + filename)) {
			// 创建缓冲区
			byte[] buff = new byte[1024];
			int n;
			// 开始读取
			while ((n = in.read(buff)) >= 0) {
				out.write(buff, 0, n);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static String deCode(Mat img) {
		// 微信二维码对象,要返回二维码坐标前2个参数必传;后2个在二维码小或不清晰时必传。
		WeChatQRCode we = new WeChatQRCode();
		List<Mat> points = new ArrayList<Mat>();
		// 微信二维码引擎解码,返回的valList中存放的是解码后的数据,points中Mat存放的是二维码4个角的坐标
		StringVector stringVector = we.detectAndDecode(img);

		if (stringVector.empty()) {
			return "0";
		}

		System.out.println(stringVector.get(0).getString(StandardCharsets.UTF_8));
		return stringVector.get(0).getString(StandardCharsets.UTF_8);
	}

}
相关推荐
小豆庄6 小时前
处理含车牌/人脸的隐私视频,如何做到数据不离机?
opencv·ai·云计算·视频
小徐不徐说12 小时前
C++ 机器视觉入门:从零搭建 AOI 开发环境(OpenCV + CMake)
开发语言·c++·opencv
晨间晓4 天前
图片里的高频和低频是什么?用华为云码道开发 OpenCV 傅里叶频谱分析工具
opencv·计算机视觉·华为云
晨间晓4 天前
图片里的阴影能不能减弱?用华为云码道开发 OpenCV 光照校正工具
人工智能·opencv·华为云
晨间晓4 天前
图片里的细小噪点怎么平滑?用华为云码道开发 OpenCV 图像滤波对比工具
人工智能·opencv·华为云
偷吃米饭4 天前
图片特征怎么描述?用华为云码道开发 OpenCV ORB 特征提取工具
人工智能·opencv·华为云
晨间晓4 天前
图片里的关键点怎么找?用华为云码道开发 OpenCV FAST 特征点检测工具
人工智能·opencv·华为云
晨间晓4 天前
二值图里的噪点怎么去掉?用华为云码道开发 OpenCV 形态学操作工具
人工智能·opencv·华为云
晨间晓4 天前
图片里的角点在哪里?用华为云码道开发 OpenCV Harris 角点检测工具
人工智能·opencv·华为云
晨间晓5 天前
图片细节丰富不丰富?用华为云码道开发 OpenCV 纹理复杂度分析工具
人工智能·opencv·华为云