OpenCV二维码检测与定位

Posted OpenCV学堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV二维码检测与定位相关的知识,希望对你有一定的参考价值。

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

 

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

标准的二维码结构如下:

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

OpenCV二维码检测与定位

三个角上的正方形区域从左到右,从上到下黑白比例为1:1:3:1:1。

OpenCV二维码检测与定位


不管角度如何变化,这个是最显著的特征,通过这个特征我们就可以实现二维码扫描检测与定位。

 

二:算法各部与输出

1. 首先把输入图像转换为灰度图像(cvtColor)

OpenCV二维码检测与定位


2. 通过OTSU转换为二值图像(threshold)

 

OpenCV二维码检测与定位


3. 对二值图像使用轮廓发现得到轮廓(findContours)

 

OpenCV二维码检测与定位


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

 

OpenCV二维码检测与定位


三:程序运行结果演示

 上述程序运行的最终结果,左侧为原图,右侧为检测结果

OpenCV二维码检测与定位

OpenCV二维码检测与定位


四:各个步骤代码实现

 
   
   
 
  1. #include <opencv2/opencv.hpp>

  2. #include <math.h>

  3. #include <iostream>

  4. using namespace cv;

  5. using namespace std;

  6. bool isCorner(Mat &image);

  7. Mat transformCorner(Mat &image, RotatedRect &rect);

  8. int main(int argc, char** argv) {

  9.    Mat src = imread("D:/gloomyfish/qrcode_05.jpg");

  10.    if (src.empty()) {

  11.        printf("could not load image...\n");

  12.        return -1;

  13.    }

  14.    namedWindow("input image", CV_WINDOW_AUTOSIZE);

  15.    imshow("input image", src);

  16.    Mat gray, binary;

  17.    cvtColor(src, gray, COLOR_BGR2GRAY);

  18.    imwrite("D:/gloomyfish/outimage/qrcode_gray.jpg", gray);

  19.    threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);

  20.    imwrite("D:/gloomyfish/outimage/qrcode_binary.jpg", binary);

  21.    // detect rectangle now

  22.    vector<vector<Point>> contours;

  23.    vector<Vec4i> hireachy;

  24.    Moments monents;

  25.    findContours(binary.clone(), contours, hireachy, RETR_LIST, CHAIN_APPROX_SIMPLE, Point());

  26.    Mat result = Mat::zeros(src.size(), CV_8UC3);

  27.    for (size_t t = 0; t < contours.size(); t++) {

  28.        double area = contourArea(contours[t]);

  29.        if (area < 100) continue;

  30.        RotatedRect rect = minAreaRect(contours[t]);

  31.        // 根据矩形特征进行几何分析

  32.        float w = rect.size.width;

  33.        float h = rect.size.height;

  34.        float rate = min(w, h) / max(w, h);

  35.        if (rate > 0.85 && w < src.cols/4 && h<src.rows/4) {

  36.            printf("angle : %.2f\n", rect.angle);

  37.            Mat qr_roi = transformCorner(src, rect);

  38.            if (isCorner(qr_roi)) {

  39.                drawContours(src, contours, static_cast<int>(t), Scalar(255, 0, 0), 2, 8);

  40.                imwrite(format("D:/gloomyfish/outimage/contour_%d.jpg", static_cast<int>(t)), qr_roi);

  41.                drawContours(result, contours, static_cast<int>(t), Scalar(255, 0, 0), 2, 8);

  42.            }

  43.        }

  44.    }

  45.    imshow("result", src);

  46.    imwrite("D:/gloomyfish/outimage/qrcode_patters.jpg", result);

  47.    waitKey(0);

  48.    return 0;

  49. }


功崇惟志,业广惟勤!


关注【OpenCV学堂】

长按或者扫码下面二维码即可关注

+OpenCV学习群 376281510

进群暗号:OpenCV


以上是关于OpenCV二维码检测与定位的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

OPENCV条形码检测与识别

基于opencv 识别定位二维码 (c++版)

基于opencv.js实现二维码定位

基于opencv.js实现二维码定位

pyhton—opencv直线检测(HoughLines)找到最长的一条线