您当前的位置: 首页 > 

暂无认证

  • 0浏览

    0关注

    98568博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

二维码识别的原理?

发布时间:2020-07-07 08:40:25 ,浏览量:0

点击上方“3D视觉工坊”,选择“星标”

干货第一时间送达

整理:公众号@图像处理与计算机视觉

本文仅做学术分享,如有侵权,请联系删除。

二维码的特征定位和信息识别 背景介绍

视觉的方法可以用来估计位置和姿态。最容易想到的是在目标上布置多个容易识别的特征,这样使用opencv相机标定和、相机畸变矫正、轮廓提取、solvepnp来获取目标相对于相机的位姿。在实际使用中只要相机和目标一方是估计的,那就可以得到全局坐标。如果相机和靶标都在移动,那只能获取到相对坐标。但是受限于相机视角和景深,这样多个特征的识别虽然精度可以很高,但是范围却很小。

对于如何扩大范围,使用二维码是一个很好的思路。首先,二维码本身具有多个特征,单个二维码可以用来实现上述方法的功能。其次,二维码本身带有信息,如果二维码的布置事先已知,那么位置和姿态估计的范围将只受限于二维码的数量。

本文主要是二维码的特征识别和信息识别。

二维码的的生成

二维码是在一个网站上生成的,经过手机的测试,生成的二维码没有问题。http://www.liantu.com/,该网站是免费的,生成的图片及二维码各种参数可以自定义。  本文的测试图片有20张,是数字1到5,每个数字隔90度旋转各一张。

二维码的特征识别

二维码特征识别的思路是:第一步,寻找二维码的三个角的定位角点,需要对图片进行平滑滤波,二值化,寻找轮廓,筛选轮廓中有两个子轮廓的特征,从筛选后的轮廓中找到面积最接近的3个即是二维码的定位角点。第二步:判断3个角点处于什么位置,主要用来对图片进行透视校正(相机拍到的图片)或者仿射校正(对网站上生成的图片进行缩放拉伸旋转等操作后得到的图片)。需要判断三个角点围成的三角形的最大的角就是二维码左上角的点。然后根据这个角的两个边的角度差确定另外两个角点的左下和右上位置。第三步,根据这些特征识别二维码的范围。  具体的代码:

       Mat src = imread( "pic\\456.jpg", 1 );        if(src.empty())  
        {  
            fprintf(stderr, "Can not load image!\n");  
            return 0;  
        }  

        Mat src_all=src.clone();  

        //彩色图转灰度图  
        Mat src_gray;
        cvtColor( src, src_gray, CV_BGR2GRAY );  

        //对图像进行平滑处理  
        blur( src_gray, src_gray, Size(3,3) );  

        //使灰度图象直方图均衡化  
        equalizeHist( src_gray, src_gray );  

        namedWindow("src_gray");  
        imshow("src_gray",src_gray);         //灰度图

        //指定112阀值进行二值化
        Mat threshold_output;
        threshold( src_gray, threshold_output, 112, 255, THRESH_BINARY );

#ifdef DEBUG
        namedWindow("二值化后输出");  
        imshow("二值化后输出",threshold_output);   //二值化后输出#endif

        //需要的变量定义
        Scalar color = Scalar(1,1,255 );  
        vectorcontours,contours2;  
        vectorhierarchy;  
        Mat drawing = Mat::zeros( src.size(), CV_8UC3 );  
        //Mat drawing2 = Mat::zeros( src.size(), CV_8UC3 );  
        Mat drawingAllContours = Mat::zeros( src.size(), CV_8UC3 );

        //利用二值化输出寻找轮廓
        findContours(threshold_output, contours, hierarchy,  CV_RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0) );  

        //寻找轮廓的方法
        int tempindex1 = 0;        int tempindex2 = 0;        for(int i = 0;ia1];            vectorout2Contours = contours[it->a2];            double lenth1 = arcLength(out1Contours,1);            double lenth2 = arcLength(out2Contours,1);            if(abs(lenth1/lenth2-2)>1)
            {
                it = vin.erase(it);
            }            else
            {
                drawContours( drawing, contours, it->a1,  CV_RGB(255,255,255) , CV_FILLED, 8);
                it++;
            }
        }        //获取三个定位角的中心坐标  
        Point point[3];        int i = 0;        vectorpointthree;        for(it = vin.begin(),i = 0;it != vin.end();i++,it++)
        {
            point[i] = Center_cal( contours, it->a1 );
            pointthree.push_back(point[i]);
        }        if(pointthree.size() <3)
        {            cout << "找到的定位角点不足3个"<            
关注
打赏
1655516835
查看更多评论
立即登录/注册

微信扫码登录

0.0516s