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


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

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

    先导入依赖包

    1. <dependency>
    2. <groupId>org.bytedecogroupId>
    3. <artifactId>javacppartifactId>
    4. <version>1.5.7version>
    5. <classifier>windows-x86_64classifier>
    6. dependency>
    7. <dependency>
    8. <groupId>org.bytedecogroupId>
    9. <artifactId>openblasartifactId>
    10. <version>0.3.19-1.5.7version>
    11. <classifier>windows-x86_64classifier>
    12. dependency>
    13. <dependency>
    14. <groupId>org.bytedecogroupId>
    15. <artifactId>opencvartifactId>
    16. <version>4.5.5-1.5.7version>
    17. dependency>
    18. <dependency>
    19. <groupId>org.bytedecogroupId>
    20. <artifactId>opencvartifactId>
    21. <version>4.5.5-1.5.7version>
    22. <classifier>windows-x86_64classifier>
    23. dependency>

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

    下面是解析代码

    1. package com.dyserver.bean;
    2. import org.bytedeco.opencv.opencv_core.Mat;
    3. import org.bytedeco.opencv.opencv_core.StringVector;
    4. import org.bytedeco.opencv.opencv_wechat_qrcode.WeChatQRCode;
    5. import java.awt.image.BufferedImage;
    6. import java.io.File;
    7. import java.io.FileInputStream;
    8. import java.io.FileOutputStream;
    9. import java.io.InputStream;
    10. import java.io.OutputStream;
    11. import java.net.URL;
    12. import java.net.URLConnection;
    13. import java.nio.charset.StandardCharsets;
    14. import java.util.ArrayList;
    15. import java.util.List;
    16. import java.util.UUID;
    17. import javax.imageio.ImageIO;
    18. import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
    19. /**
    20. *
    21. */
    22. public class WeChatDeCode {
    23. public static void main(String... args) {
    24. Mat img = imread("d:\\img" + "\\" + "1.png");
    25. System.out.println(deCode(img));
    26. //下载二维码到本地识别
    27. String url="";
    28. System.out.println(openPic(url));
    29. }
    30. public static String openPic(String url) {
    31. String savePath = "d:\\img";
    32. String filename = UUID.randomUUID().toString() + ".jpg";
    33. String re="0";
    34. try {
    35. dxz(url, savePath, filename);
    36. Mat img = imread(savePath + "\\" + filename);
    37. re=deCode(img);
    38. //如果识别失败那么尝试放大缩小图片尝试识别,提高准确率
    39. if(re.equals("0")) {
    40. ys(savePath, filename);
    41. Mat img1 = imread(savePath + "\\1_" + filename);
    42. re=deCode(img1);
    43. }
    44. if(re.equals("0")) {
    45. fd(savePath, filename);
    46. Mat img2 = imread(savePath + "\\2_" + filename);
    47. re=deCode(img2);
    48. }
    49. return re;
    50. } catch (Exception e) {
    51. // TODO Auto-generated catch block
    52. e.printStackTrace();
    53. return "0";
    54. }
    55. }
    56. private static void ys(String savePath, String filename) throws Exception {
    57. try {
    58. // 读取原始图片
    59. BufferedImage image = ImageIO.read(new FileInputStream(savePath + "\\" + filename));
    60. System.out.println("Width: " + image.getWidth());
    61. System.out.println("Height: " + image.getHeight());
    62. // 调整图片大小
    63. BufferedImage newImage = ImageUtils.resizeImage(image, image.getWidth()*2, image.getHeight()*2);
    64. // 图像缓冲区图片保存为图片文件(文件不存在会自动创建文件保存,文件存在会覆盖原文件保存)
    65. ImageIO.write(newImage, "jpg", new File(savePath + "\\1_" + filename));
    66. } catch (Exception e) {
    67. e.printStackTrace();
    68. }
    69. }
    70. private static void fd(String savePath, String filename) throws Exception {
    71. try {
    72. // 读取原始图片
    73. BufferedImage image = ImageIO.read(new FileInputStream(savePath + "\\" + filename));
    74. System.out.println("Width: " + image.getWidth());
    75. System.out.println("Height: " + image.getHeight());
    76. // 调整图片大小
    77. BufferedImage newImage = ImageUtils.resizeImage(image, 200, 200);
    78. // 图像缓冲区图片保存为图片文件(文件不存在会自动创建文件保存,文件存在会覆盖原文件保存)
    79. ImageIO.write(newImage, "jpg", new File(savePath + "\\2_" + filename));
    80. } catch (Exception e) {
    81. e.printStackTrace();
    82. }
    83. }
    84. private static void dxz(String urlString, String savePath, String filename) throws Exception {
    85. // 构造URL
    86. URL url = new URL(urlString);
    87. // 打开连接
    88. URLConnection con = url.openConnection();
    89. // 设置请求超时为20s
    90. con.setConnectTimeout(20 * 1000);
    91. // 文件路径不存在 则创建
    92. File sf = new File(savePath);
    93. if (!sf.exists()) {
    94. sf.mkdirs();
    95. }
    96. // jdk 1.7 新特性自动关闭
    97. try (InputStream in = con.getInputStream();
    98. OutputStream out = new FileOutputStream(sf.getPath() + "\\" + filename)) {
    99. // 创建缓冲区
    100. byte[] buff = new byte[1024];
    101. int n;
    102. // 开始读取
    103. while ((n = in.read(buff)) >= 0) {
    104. out.write(buff, 0, n);
    105. }
    106. } catch (Exception e) {
    107. e.printStackTrace();
    108. }
    109. }
    110. private static String deCode(Mat img) {
    111. // 微信二维码对象,要返回二维码坐标前2个参数必传;后2个在二维码小或不清晰时必传。
    112. WeChatQRCode we = new WeChatQRCode();
    113. List points = new ArrayList();
    114. // 微信二维码引擎解码,返回的valList中存放的是解码后的数据,points中Mat存放的是二维码4个角的坐标
    115. StringVector stringVector = we.detectAndDecode(img);
    116. if (stringVector.empty()) {
    117. return "0";
    118. }
    119. System.out.println(stringVector.get(0).getString(StandardCharsets.UTF_8));
    120. return stringVector.get(0).getString(StandardCharsets.UTF_8);
    121. }
    122. }

  • 相关阅读:
    c++视觉处理---计算轮廓面积
    数据挖掘面试经总结【私人版,仅供参考】
    政安晨:【深度学习神经网络基础】(十三)—— 卷积神经网络
    强化学习各种符号含义解释
    react基础
    MyBatis
    sql表关联查询,表查询出数据插入到另一张,使用正则查询,查询结果集转换为JSON数据
    ExtJS 教程汇总
    【鸿蒙最新全套教程】<HarmonyOS第一课>1、运行Hello World
    知识分享,教您实现虹科工业树莓派对远程IO模块的控制
  • 原文地址:https://blog.csdn.net/terry711/article/details/133632188