【opencv4 检测二维码】cv4判断图片是否包含二维码

opencv4.0版本以后,加入了二维码定位解码的功能。下面我们将使用该功能,进行图片二维码检测。

由于 python中cv2模块的imread函数呆以正常读取’jpg’,'png’格式的图片,但是不能处理’gif’图片。可以改用imageio模块来处理。

安装 imageio 模块

pip install imageio

安装 opencv4

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python==4.0.0.21

# -*- coding: utf-8 -*-
import cv2
import os
import imageio

import numpy as np



def readImg(image_path):
    """
    :param image_path: 图片路径
    :return:
    """

    im = cv2.imread(image_path)
    if im is None :
        tmp = imageio.mimread(image_path)
        if tmp is not None:
            imt = np.array(tmp)
            imt = imt[0]
            im = imt[:,:,0:3]
    return im



def cv4_detect_qrcode(image_path):
    """
    :param image_path: 图片路径
    :return: 是否包含二维码
    """
    image_type = []
    try:
        img = readImg(image_path)
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        qrcode = cv2.QRCodeDetector()
        result_detection, transform, straight_qrcode = qrcode.detectAndDecode(img_gray)

        if transform is not None:
            image_type.append(1)
        else:
            image_type.append(0)

    except Exception as e:
        print(e)
        image_type.append(0)

    return image_type[0]








if __name__ == '__main__':

    filepath = 'F:/img_spam/test_pyzbar/'
    for parent, dirnames, filenames in os.walk(filepath):
        for filename in filenames:
            image_path = filepath + filename
            image_type = cv4_detect_qrcode(image_path)
            if image_type==1:
                print(filename,image_type)

我们这里只用到了定位功能,若定位到有二维码,则transform 返回的是坐标。没有定位到坐标,则判断该图片没有二维码。

已标记关键词 清除标记
需求类似发布一条朋友圈,带图片的就要先检测图片是否二维码,有就禁止发布。因为项目有用到zxing就先用zxing去识别,但识别率太低了,因为不是扫码是直接在相册选张图就检测,有的图里的二维码很小就检测不到,最后用OpenCV定位,但虽然比zxing好点,但圆角的二维码就不认识了。 请问有好的识别库推荐吗,不需要解析二维码的内容,只要能知道一张图里是否二维码就行了。 这张图就定位不到二维码 ![图片说明](https://img-ask.csdn.net/upload/202010/23/1603422758_199972.jpg) 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; } } ```
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页