前言
最近公司项目有一个需求,要用二维码传递数据。于是使用了zxing生成和解析二维码,但是zxing扫描二维码原图还可以,一旦扫描用户使用手机拍摄的二维码,识别率急剧下降。尝试了对拍摄的照片进行降噪,二值化,但对识别率始终不太满意。
于是百度了一番,发现今年微信将自家扫描二维码引擎在opencv上开源了,所以当然是使用微信扫码啦,至于微信扫码引擎识别率高的原因就不介绍了,有喜欢研究的小伙伴可以自行百度。
下面是本人调用opencv扫码功能的一些步骤,希望可以帮到大家,也给自己做一个记录。
一、使用步骤
微信扫码功能是在opencv的拓展模块下,所以大家需要重新编译opencv和opencv-contrib,这里直接提供给大家。
使用功能时先扫描本地动态库文件和微信扫码需要的模板,之后就可以愉快的扫码了
二、代码
1.主要功能类
public class WeChatDeCode {
private static String path;
static {
OpencvConfig opencvConfig = new OpencvConfig();
path = opencvConfig.getOpencvPath();
System.load(path+File.separator+ Configs.lib_path);
}
public static void main(String... args) throws IOException {
File file = new File("D:\\SpringCloudTest\\test\\picture\\20211101-test-005.1.jpg");
BufferedImage image = ImageIO.read(file);
open(image);
}
public static String open(BufferedImage image) {
return openPic(image);
}
private static String openPic(BufferedImage image) {
Mat img = Converters.img2mat(image);
return deCode(img);
}
private static String deCode(Mat img) {
//微信二维码对象,要返回二维码坐标前2个参数必传;后2个在二维码小或不清晰时必传。
WeChatQRCode we = new WeChatQRCode(path+File.separator+ Configs.detector_prototxt_path, path+File.separator+ Configs.detector_caffe_model_path, path+File.separator+ Configs.super_resolution_prototxt_path, path+File.separator+ Configs.super_resolution_caffe_model_path);
List<Mat> points = new ArrayList<Mat>();
//微信二维码引擎解码,返回的valList中存放的是解码后的数据,points中Mat存放的是二维码4个角的坐标
List<String> valList = we.detectAndDecode(img,points);
System.out.println(valList.get(0));
return valList.get(0);
}
}
2.引用类
public class Configs extends ClassLoader {
public static final String detector_prototxt_path = "detect.prototxt";
public static final String detector_caffe_model_path = "detect.caffemodel";
public static final String super_resolution_prototxt_path = "sr.prototxt";
public static final String super_resolution_caffe_model_path = "sr.caffemodel";
public static String lib_path;
static {
String lib = "";
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("windows")) {
lib = "opencv_java452.dll";
} else if (os.contains("linux")) {
lib = "libopencv_java452.so";
} else if (os.contains("mac")) {
lib = "opencv_java452.jnilib";
}
lib_path = lib;
}
public Configs() {
}
}
3.读取配置类
@Configuration
public class OpencvConfig {
private static String opencvPath;
@Value("${opencvPath}")
public void setUsername(String opencvPath) {
OpencvConfig.opencvPath = opencvPath;
}
public String getOpencvPath() {
return opencvPath;
}
}
4.配置文件
之后在yml文件添加一个 opencvPath 的目录位置
总结
到这里就结束了,整个过程踩了很多坑,比如opencv和opencv-contrib的的编译,功能类中引入动态库文件不正确等等。
比如需要加载本地文件时,在IDEA中是可以正常运行的,但是打成jar包以后在windows或者linux系统中就无法运行,提醒一下自己,以后多注意这方面的东西