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);
	}

}
相关推荐
sali-tec5 天前
C# 基于OpenCv的视觉工作流-章27-图像分割
图像处理·人工智能·opencv·算法·计算机视觉
saoys5 天前
Opencv 学习笔记:腐蚀操作 + 轮廓标记 + 分水岭分割
笔记·opencv·学习
saoys5 天前
Opencv 学习笔记:距离变换(DIST_L1 算法实战 + 归一化)
笔记·opencv·学习
guygg885 天前
图像匹配技术:相关匹配、Hausdorff距离匹配与基于距离变换的Hausdorff距离匹配
图像处理·opencv·计算机视觉
AI科技星5 天前
物理世界的几何建构:论统一场论的本体论革命与概念生成
人工智能·opencv·线性代数·算法·矩阵
fie88895 天前
基于Matlab实现的指纹识别系统流程
opencv·计算机视觉·matlab
sali-tec6 天前
C# 基于OpenCv的视觉工作流-章26-图像拼接
图像处理·人工智能·opencv·算法·计算机视觉
智驱力人工智能6 天前
机场鸟类活动智能监测 守护航空安全的精准工程实践 飞鸟检测 机场鸟击预防AI预警系统方案 机场停机坪鸟类干扰实时监测机场航站楼鸟击预警
人工智能·opencv·算法·安全·yolo·目标检测·边缘计算
Σίσυφος19006 天前
OpenCV 之双线性插值
人工智能·opencv·计算机视觉
格林威6 天前
Baumer相机金属粉末铺粉均匀性评估:用于增材制造过程监控的 7 个实用技巧,附 OpenCV+Halcon 实战代码!
人工智能·opencv·视觉检测·制造·工业相机·智能相机·堡盟相机