用OpenCV和Zbar进行二维码的定位+追踪

首页 / 技术 / 正文

OpenCV是一个广泛用于图像处理机器视觉领域的C++库。近期接到一个室内飞行器定位的需求,大概是在天花板上有一个摄像头,下方是一些无人机,要如何在摄像头采集的图像中定位到这些无人机?(一开始我直接想到的是使用人脸检测,在无人机上贴人脸,然后对其进行检测,但或许有点太骚了?)于是我想到了使用二维码进行定位,并写了个程序测试了一下,效果还算不错。

思路

二维码的检测与定位

二维码检测有非常多的库可供使用,我尝试了使用OpenCV里的ObjDetect内置的二维码识别,结果效果很糟糕,所以就换用了ZBar,效果不错。

二维码的跟踪

如果对每一帧图像都只使用检测的方法,那么在二维码离得比较远的情况下,检测就会失效。因此,需要编写一个逻辑,在检测算法无法检测到二维码的情况下,换用目标跟踪算法进行跟踪

实现

我将以上思路使用C++进行了实现,并封装成了类,方便进行调用,效果不错。项目使用了Qt的qmake进行开发,需要用Qt Creator打开项目。如果需要使用其中封装好的类,只需将QRDetectorAndTracker取出即可。

项目源码:

https://github.com/huanghaozi/QRDetectorAndTracker

效果:

其中方框为绿色时表示正在使用目标跟踪算法,为蓝色时表示正在使用检测算法。

扩展

多目标跟踪

已集成至原程序,Github已更新

使用说明

加入包含文件及链接库依赖

1. 首先需要将opencv和zlib文件夹复制到自己的项目目录下

2. 需要在项目的Include Path中加入opencv/include、zlib/include

3. 需要将opencv/bin、zlib/bin下的dll文件加入项目的动态链接库中,或直接将其复制到与exe相同的目录下

包含头文件

需要将该Repo中的QRDetectorAndTracker.cpp及QRDetectorAndTracker.h文件加入自己的项目中

在需要用到的地方添加


#include "QRDetectorAndTracker.h"

类的结构

变量


    //默认从摄像头获取图像

    std::vector<int> x, y; //二维码的坐标,考虑到存在多个二维码,所以用容器

    cv::Mat pic; //含有方框标记的输出图像,执行drawBound后此变量才有内容

    std::vector<bool> xyAvailable; //是否识别到二维码,即坐标是否可用

    std::vector<std::string> qrChars; //二维码的内容,考虑到存在多个二维码,所以用容器

函数


    void detect(); //检测函数,将从摄像头读取一帧图像并检测,将检测的坐标、内容存入上述变量中

    void drawBound(); //在检测到二维码的位置画个方框,存入pic变量中

    void showPic(cv::String s); //显示图像窗口,其中参数s为窗口标题

示例


    //初始化

    QRDetectorAndTracker qr;

    while(1) //主循环

    {

        //检测坐标

        qr.detect();

        //绘制方框并显示

        qr.drawBound();

        qr.showPic("Window");

        //输出坐标,遍历xyAvailable

        for(int i=0;i<std::distance(qr.xyAvailable.begin(), qr.xyAvailable.end());i++)

        {

            if(qr.xyAvailable[i]) //若坐标可用则输出

                std::cout << qr.qrChars[i] << ": " << qr.x[i] << ", " << qr.y[i] << std::endl;

        }

        //循环延时,不加会卡死

        if(cv::waitKey(1)==27)

            break;

    }
打赏
评论区
头像