基于OpenCV实现二维码发现与定位

简介: 基于OpenCV实现二维码发现与定位在如今流行扫描的年代,应用程序实现二维码扫描检测与识别已经是应用程序的标配、特别是在移动端、如果你的应用程序不能自动发现检测二维码,自动定位二维码你都不好意思跟别人打招呼,二维码识别与解析基于ZXing包即可。

基于OpenCV实现二维码发现与定位

在如今流行扫描的年代,应用程序实现二维码扫描检测与识别已经是应用程序的标配、特别是在移动端、如果你的应用程序不能自动发现检测二维码,自动定位二维码你都不好意思跟别人打招呼,二维码识别与解析基于ZXing包即可。难点就在于如何从画面中快速而准确的找到二维码区域,寻找到二维码三个匹配模式点。

一:二维码的结构与基本原理

标准的二维码结构如下:
这里写图片描述
特别要关注的是图中三个黑色正方形区域,它们就是用来定位一个二维码的最重要的三个区域,我们二维码扫描与检测首先要做的就是要发现这三个区域,如果找到这个三个区域,我们就成功的发现一个二维码了,就可以对它定位与识别了。二维码其它各个部分的说明如下:
这里写图片描述

三个角上的正方形区域从左到右,从上到下黑白比例为1:1:3:1:1。
这里写图片描述
不管角度如何变化,这个是最显著的特征,通过这个特征我们就可以实现二维码扫描检测与定位。

二:算法各部与输出

1. 首先把输入图像转换为灰度图像
这里写图片描述

2. 通过OTSU转换为二值图像
这里写图片描述

3. 对二值图像使用轮廓发现得到轮廓
这里写图片描述

4. 根据二维码三个区域的特征,对轮廓进行面积与比例过滤得到最终结果显示如下:
这里写图片描述

三:程序运行演示与代码实现

下面的图片左侧为原图、右侧为二维码定位结果
这里写图片描述

这里写图片描述

这里写图片描述

程序各个步骤完整源代码如下

#include <opencv2/opencv.hpp>
#include <math.h>
#include <iostream>

using namespace cv;
using namespace std;

void scanAndDetectQRCode(Mat & image, int index);
bool isXCorner(Mat &image);
bool isYCorner(Mat &image);
Mat transformCorner(Mat &image, RotatedRect &rect);
int main(int argc, char** argv) {
    /*for (int i = 1; i < 25; i++) {
        Mat qrcode_image = imread(format("D:/gloomyfish/qrcode/%d.jpg", i));
        scanAndDetectQRCode(qrcode_image, i);
    }
    return 0;
    */
    Mat src = imread("D:/gloomyfish/qrcode_99.jpg");
    if (src.empty()) {
        printf("could not load image...\n");
        return -1;
    }
    namedWindow("input image", CV_WINDOW_AUTOSIZE);
    imshow("input image", src);

    Mat gray, binary;
    cvtColor(src, gray, COLOR_BGR2GRAY);
    imwrite("D:/gloomyfish/outimage/qrcode_gray.jpg", gray);

    threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
    imwrite("D:/gloomyfish/outimage/qrcode_binary.jpg", binary);

    // detect rectangle now
    vector<vector<Point>> contours;
    vector<Vec4i> hireachy;
    Moments monents;
    findContours(binary.clone(), contours, hireachy, RETR_LIST, CHAIN_APPROX_SIMPLE, Point());
    Mat result = Mat::zeros(src.size(), CV_8UC3);
    for (size_t t = 0; t < contours.size(); t++) {
        double area = contourArea(contours[t]);
        if (area < 100) continue;
        RotatedRect rect = minAreaRect(contours[t]);
        // 根据矩形特征进行几何分析
        float w = rect.size.width;
        float h = rect.size.height;
        float rate = min(w, h) / max(w, h);
        if (rate > 0.85 && w < src.cols/4 && h<src.rows/4) {
            printf("angle : %.2f\n", rect.angle);
            Mat qr_roi = transformCorner(src, rect);
            if (isXCorner(qr_roi) && isYCorner(qr_roi)) {
                drawContours(src, contours, static_cast<int>(t), Scalar(0, 0, 255), 2, 8);
                imwrite(format("D:/gloomyfish/outimage/contour_%d.jpg", static_cast<int>(t)), qr_roi);
                drawContours(result, contours, static_cast<int>(t), Scalar(255, 0, 0), 2, 8);
            }
        }
    }
    imshow("result", src);
    imwrite("D:/gloomyfish/outimage/qrcode_patters.jpg", src);
    waitKey(0);
    return 0;
}

欢迎继续关注本博客,加入OpenCV学习群

目录
相关文章
|
5月前
|
算法 计算机视觉 Python
python+opencv实现车牌定位
python+opencv实现车牌定位
|
机器学习/深度学习 算法 决策智能
ubuntu16.04下ROS操作系统学习笔记(六 )机器视觉-摄像头标定-ROS+OpenCv-人脸识别-物体跟踪-二维码识别(下)
ubuntu16.04下ROS操作系统学习笔记(六 )机器视觉-摄像头标定-ROS+OpenCv-人脸识别-物体跟踪-二维码识别(下)
360 0
|
存储 机器学习/深度学习 编解码
ubuntu16.04下ROS操作系统学习笔记(六 )机器视觉-摄像头标定-ROS+OpenCv-人脸识别-物体跟踪-二维码识别(上)
ubuntu16.04下ROS操作系统学习笔记(六 )机器视觉-摄像头标定-ROS+OpenCv-人脸识别-物体跟踪-二维码识别(上)
413 0
|
机器学习/深度学习 存储 算法
基于Python opencv实现车牌识别及二维码条形码识别系统 附完整源码
基于Python opencv实现车牌识别及二维码条形码识别系统 附完整源码
514 0
基于Python opencv实现车牌识别及二维码条形码识别系统 附完整源码
|
边缘计算 并行计算 算法
Opencv+ZBar识别条形码、二维码
Opencv+ZBar识别条形码、二维码
777 0
Opencv+ZBar识别条形码、二维码
|
计算机视觉
OpenCV定位轮廓的中点
本文将会用三个不同的示例说明用OpenCV如何进行形状的检测与分析。 从这三个示例中我们将会学到如何: 计算一个轮廓或图形区域的中心点,这项小技能会在以后很多的OpenCV项目中将会非常实用。
3111 0
|
计算机视觉
OpenCV使用FindContours进行二维码定位
我使用过FindContours,而且知道有能够直接寻找联通区域的函数。但是我使用的大多只是“最大轮廓”或者"轮廓数目“这些数据。其实轮廓还有另一个很重要的性质,那就是轮廓的相互包含特性。 比如典型的运用在二维码上面     对于它的3个定位点,认为构造了相互包含的轮廓区域,这种特性,在图上只有三处,而且在自然图片中是不容易重复的(当然二维码内部还有校验机制)。
1649 0
|
28天前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
257 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
2月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
45 4
|
2月前
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制