需求类似发布一条朋友圈,带图片的就要先检测看图片里是否有二维码,有就禁止发布。因为项目有用到zxing就先用zxing去识别,但识别率太低了,因为不是扫码是直接在相册选张图就检测,有的图里的二维码很小就检测不到,最后用OpenCV定位,但虽然比zxing好点,但圆角的二维码就不认识了。
请问有好的识别库推荐吗,不需要解析二维码的内容,只要能知道一张图里是否有二维码就行了。
这张图就定位不到二维码
OpenCV定位二维码的代码
public static boolean isQRCode(String imgUrl) {
LogUtil.showD(TAG, "图片地址:"+imgUrl);
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat src = Imgcodecs.imread(imgUrl, 1);
Mat src_gray = new Mat();
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
List<MatOfPoint> markContours = new ArrayList<MatOfPoint>();
/**图片太小就放大**/
if (src.width() * src.height() < 90000) {
Imgproc.resize(src, src, new Size(800, 600));
}
Mat src_all = src.clone();
//彩色图转灰度图
Imgproc.cvtColor(src, src_gray, Imgproc.COLOR_RGB2GRAY);
//对图像进行平滑处理
Imgproc.GaussianBlur(src_gray, src_gray, new Size(3, 3), 0);
/**Imgcodecs.imwrite("F:\\output\\EH.jpg", src_gray);**/
Imgproc.Canny(src_gray, src_gray, 112, 255);
/**Imgcodecs.imwrite("F:\\output\\1-2.jpg", src_gray);**/
Mat hierarchy = new Mat();
Imgproc.findContours(src_gray, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_NONE);
for (int i = 0; i < contours.size(); i++) {
MatOfPoint2f newMtx = new MatOfPoint2f(contours.get(i).toArray());
RotatedRect rotRect = Imgproc.minAreaRect(newMtx);
double w = rotRect.size.width;
double h = rotRect.size.height;
double rate = Math.max(w, h) / Math.min(w, h);
/***
* 长短轴比小于1.3,总面积大于60
*/
if (rate < 1.3 && w < src_gray.cols() / 4 && h < src_gray.rows() / 4 && Imgproc.contourArea(contours.get(i)) > 60) {
/***
* 计算层数,二维码角框有五层轮廓(有说六层),这里不计自己这一层,有4个以上子轮廓则标记这一点
*/
double[] ds = hierarchy.get(0, i);
if (ds != null && ds.length > 3) {
int count = 0;
if (ds[3] == -1) {/**最外层轮廓排除*/
continue;
}
/***
* 计算所有子轮廓数量
*/
while ((int) ds[2] != -1) {
++count;
ds = hierarchy.get(0, (int) ds[2]);
}
if (count >= 4) {
markContours.add(contours.get(i));
}
}
}
}
/**
* 这部分代码画框,调试用**/
// for (int i = 0; i < markContours.size(); i++) {
// Imgproc.drawContours(src_all, markContours, i, new Scalar(0, 255, 0), -1);
// }
// Imgcodecs.imwrite("F:\\output\\2-1.jpg", src_all);
/***
* 二维码有三个角轮廓,少于三个的无法定位放弃,多余三个的循环裁剪出来
*/
if (markContours.size() < 3) {
return false;
} else {
return true;
}
}