图像处理二维码识别的设计_基准图像对比 图像识别算法 二维码 - CSDN
  • 二维码识别算法

    热门讨论 2020-07-29 23:06:17
    针对解码识别过程,详细分析了基于图像处理的预处理方法,包括二维码灰度化处理、图像平滑和二值化过程,同时针对二维码实际情况,设计了基于Canny和Hough变换的二维码旋转校正算法,几何形变校正算法,并通过QR...
  • [Matlab][图像处理]二维码识别二维码识别简介二维码识别系统界面以及运行结果源代码联系作者 二维码识别简介 二维码识别系统界面以及运行结果 源代码联系作者 QQ 3538518672

    二维码识别简介

    二维码识别系统界面以及运行结果

    在这里插入图片描述

    源代码联系作者

    QQ 3538518672

    展开全文
  • opencv二维码识别解码

    万次阅读 2017-08-25 15:17:38
    使用opencv库识别QR二维码,框出图片中的二维码,并使用开源库Zxing解码,在这过程中学习理解opencv库相应的函数。 环境: 1. window7系统  2. QT create 1.准备 首先安装QT和QT create开发环境,window下使用...

    目的:

    使用opencv库识别QR二维码,框出图片中的二维码,并使用开源库Zxing解码,在这过程中学习理解opencv库相应的函数。

    环境:

    1. window7系统

          2. QT create

    1.准备

    首先安装QT和QT create开发环境,window下使用cmake编译opencv生产lib库。这部分内容网上很多资料,直接搜索安装就行。

    2.工程代码

    QT create配置使用opencv库。在工程的pro文件下面添加指定opencv库的头文件和lib的路径。如下:
    INCLUDEPATH+=C:\Qt\opencv\include\opencv\
                 C:\Qt\opencv\include\opencv2\
                 C:\Qt\opencv\include
    
    LIBS+=C:\Qt\opencv\lib\libopencv_calib3d320.dll.a\
          C:\Qt\opencv\lib\libopencv_core320.dll.a\
          C:\Qt\opencv\lib\libopencv_features2d320.dll.a\
          C:\Qt\opencv\lib\libopencv_flann320.dll.a\
          C:\Qt\opencv\lib\libopencv_highgui320.dll.a\
          C:\Qt\opencv\lib\libopencv_imgcodecs320.dll.a\
          C:\Qt\opencv\lib\libopencv_imgproc320.dll.a\
          C:\Qt\opencv\lib\libopencv_ml320.dll.a\
          C:\Qt\opencv\lib\libopencv_objdetect320.dll.a\
          C:\Qt\opencv\lib\libopencv_photo320.dll.a\
          C:\Qt\opencv\lib\libopencv_shape320.dll.a\
          C:\Qt\opencv\lib\libopencv_stitching320.dll.a\
          C:\Qt\opencv\lib\libopencv_superres320.dll.a\
          C:\Qt\opencv\lib\libopencv_video320.dll.a\
          C:\Qt\opencv\lib\libopencv_videoio320.dll.a\
          C:\Qt\opencv\lib\libopencv_videostab320.dll.a

    opencv识别定位二维码的代码如下:
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    #include <QDebug>
    
    using namespace cv;
    using namespace std;
    
    
    Mat src; Mat src_gray;
    
    
    RNG rng(12345);
    //Scalar colorful = CV_RGB(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
    
    //获取轮廓的中心点
    Point Center_cal(vector<vector<Point> > contours,int i)
    {
          int centerx=0,centery=0,n=contours[i].size();
          //在提取的小正方形的边界上每隔周长个像素提取一个点的坐标,
          //求所提取四个点的平均坐标(即为小正方形的大致中心)
          centerx = (contours[i][n/4].x + contours[i][n*2/4].x + contours[i][3*n/4].x + contours[i][n-1].x)/4;
          centery = (contours[i][n/4].y + contours[i][n*2/4].y + contours[i][3*n/4].y + contours[i][n-1].y)/4;
          Point point1=Point(centerx,centery);
          return point1;
    }
    
    
    int main( int argc, char** argv[] )
    {
        src = imread( "core.jpg", 1 );
        Mat src_all=src.clone();
    
    
        //彩色图转灰度图
        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);
    
    
        Scalar color = Scalar(1,1,255 );
        Mat threshold_output;
        vector<vector<Point> > contours,contours2;
        vector<Vec4i> hierarchy;
        Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
        Mat drawing2 = Mat::zeros( src.size(), CV_8UC3 );
        Mat drawingAllContours = Mat::zeros( src.size(), CV_8UC3 );
    
        //指定112阀值进行二值化
        threshold( src_gray, threshold_output, 112, 255, THRESH_BINARY );
    
        namedWindow("Threshold_output");
        imshow("Threshold_output",threshold_output);
    
    
        /*查找轮廓
         *  参数说明
            输入图像image必须为一个2值单通道图像
            contours参数为检测的轮廓数组,每一个轮廓用一个point类型的vector表示
            hiararchy参数和轮廓个数相同,每个轮廓contours[ i ]对应4个hierarchy元素hierarchy[ i ][ 0 ] ~hierarchy[ i ][ 3 ],
                分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,该值设置为负数。
            mode表示轮廓的检索模式
                CV_RETR_EXTERNAL 表示只检测外轮廓
                CV_RETR_LIST 检测的轮廓不建立等级关系
                CV_RETR_CCOMP 建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
                CV_RETR_TREE 建立一个等级树结构的轮廓。具体参考contours.c这个demo
            method为轮廓的近似办法
                CV_CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
                CV_CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
                CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 使用teh-Chinl chain 近似算法
            offset表示代表轮廓点的偏移量,可以设置为任意值。对ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数还是很有用的。
         */
        findContours( threshold_output, contours, hierarchy,  CV_RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0) );
    
        int c=0,ic=0,k=0,area=0;
    
        //通过黑色定位角作为父轮廓,有两个子轮廓的特点,筛选出三个定位角
        int parentIdx=-1;
        for( int i = 0; i< contours.size(); i++ )
        {
            //画出所以轮廓图
            drawContours( drawingAllContours, contours, parentIdx,  CV_RGB(255,255,255) , 1, 8);
            if (hierarchy[i][2] != -1 && ic==0)
            {
                parentIdx = i;
                ic++;
            }
            else if (hierarchy[i][2] != -1)
            {
                ic++;
            }
            else if(hierarchy[i][2] == -1)
            {
                ic = 0;
                parentIdx = -1;
            }
    
            //有两个子轮廓
            if ( ic >= 2)
            {
                //保存找到的三个黑色定位角
                contours2.push_back(contours[parentIdx]);
                //画出三个黑色定位角的轮廓
                drawContours( drawing, contours, parentIdx,  CV_RGB(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)) , 1, 8);
                ic = 0;
                parentIdx = -1;
            }
        }
    
        //填充的方式画出三个黑色定位角的轮廓
        for(int i=0; i<contours2.size(); i++)
            drawContours( drawing2, contours2, i,  CV_RGB(rng.uniform(100,255),rng.uniform(100,255),rng.uniform(100,255)) , -1, 4, hierarchy[k][2], 0, Point() );
    
        //获取三个定位角的中心坐标
        Point point[3];
        for(int i=0; i<contours2.size(); i++)
        {
            point[i] = Center_cal( contours2, i );
        }
    
        //计算轮廓的面积,计算定位角的面积,从而计算出边长
        area = contourArea(contours2[1]);
        int area_side = cvRound (sqrt (double(area)));
        for(int i=0; i<contours2.size(); i++)
        {
            //画出三个定位角的中心连线
            line(drawing2,point[i%contours2.size()],point[(i+1)%contours2.size()],color,area_side/2,8);
        }
    
        namedWindow("DrawingAllContours");
        imshow( "DrawingAllContours", drawingAllContours );
    
        namedWindow("Drawing2");
        imshow( "Drawing2", drawing2 );
    
        namedWindow("Drawing");
        imshow( "Drawing", drawing );
    
    
        //接下来要框出这整个二维码
        Mat gray_all,threshold_output_all;
        vector<vector<Point> > contours_all;
        vector<Vec4i> hierarchy_all;
        cvtColor( drawing2, gray_all, CV_BGR2GRAY );
    
    
        threshold( gray_all, threshold_output_all, 45, 255, THRESH_BINARY );
        findContours( threshold_output_all, contours_all, hierarchy_all,  RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0) );//RETR_EXTERNAL表示只寻找最外层轮廓
    
    
        Point2f fourPoint2f[4];
        //求最小包围矩形
        RotatedRect rectPoint = minAreaRect(contours_all[0]);
    
        //将rectPoint变量中存储的坐标值放到 fourPoint的数组中
        rectPoint.points(fourPoint2f);
    
    
        for (int i = 0; i < 4; i++)
        {
            line(src_all, fourPoint2f[i%4], fourPoint2f[(i + 1)%4]
                , Scalar(20,21,237), 3);
        }
    
        namedWindow("Src_all");
        imshow( "Src_all", src_all );
    
        //框出二维码后,就可以提取出二维码,然后使用解码库zxing,解出码的信息。
        //或者研究二维码的排布规则,自己写解码部分
    
        waitKey(0);
        return(0);
    }
    

    下面是代码运行的图片,代码处理过程的图片都有,包括二值化图片,轮廓图,找到的定位角图和最终的框出二维码图都显示出来了。如下:


    这部分的代码主要是修改自guanyonglai博主的代码,在此基础上学习了相应的opencv库函数,并根据自己的理解添加了一些注释。实现的主要功能是根据QR二维码三个定位角的特点找出定位角的坐标,并框出整个QR二维码。
    框出二维码后能做的事情就多了,可以使用相应的开源解码库解出二维码的信息,比如Zxing库,libdmtx库。Zxing库能解码的格式和支持的语音格式挺多的,网址:https://github.com/zxing/zxing。libdmtx库主要解码data matrix二维码,网址:http://libdmtx.sourceforge.net/这个库我使用过,很简单,直接调用几个函数就可以解出码的信息。
    解码部分使用libdmtx库的方式已经实现的了,有时间再补充。去除opencv库,直接用算法处理图片并定位二维码并解码的也写了demo,这部分内容较多,有时间再补充,需要大概思路的可以留言。

    展开全文
  • 二维码识别的原理?

    2020-07-08 00:20:04
    点击上方“3D视觉工坊”,选择“星标”干货第一时间送达整理:公众号@图像处理与计算机视觉本文仅做学术分享,如有侵权,请联系删除。二维码的特征定位和信息识别背景介绍视觉的方法可以用来估计位...

    点击上方“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 );  
            vector<vector<Point>> contours,contours2;  
            vector<Vec4i> hierarchy;  
            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;i<contours.size();i++)
            {            if(hierarchy[i][2] == -1)                continue;            else
                    tempindex1 = hierarchy[i][2];                //第一个子轮廓的索引
    
                if(hierarchy[tempindex1][2] == -1)                continue;            else
                {
                    tempindex2 = hierarchy[tempindex1][2];        //第二个子轮廓的索引
                    //记录搜索到的有两个子轮廓的轮廓并把他们的编号存储
                    in.a1 = i;
                    in.a2 = tempindex1;
                    in.a3 = tempindex2;
                    vin.push_back(in);
                }
            }        //按面积比例搜索
            vector<index>::iterator it;        for(it = vin.begin();it != vin.end();)
            {            vector<Point> out1Contours = contours[it->a1];            vector<Point> out2Contours = 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;        vector<Point> pointthree;        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个"<<endl;            return 0;  
            }        //计算轮廓的面积,计算定位角的面积,从而计算出边长
            double area = contourArea(contours[vin[0].a1]);        int area_side = cvRound (sqrt (double(area)));  
            for(int i=0; i<3; i++)  
            {  
                //画出三个定位角的中心连线  
                line(drawing,point[i%3],point[(i+1)%3],color,area_side/10,8);  
            }  
    
            //清除找到的3个点,以便处理下一幅图片使用
            vin.clear();        //由3个定位角校正图片
            //=========================================
            //找到角度最大的点
            double ca[2];        double cb[2];
    
            ca[0] =  pointthree[1].x - pointthree[0].x;
            ca[1] =  pointthree[1].y - pointthree[0].y;
            cb[0] =  pointthree[2].x - pointthree[0].x;
            cb[1] =  pointthree[2].y - pointthree[0].y;        double angle1 = 180/3.1415*acos((ca[0]*cb[0]+ca[1]*cb[1])/(sqrt(ca[0]*ca[0]+ca[1]*ca[1])*sqrt(cb[0]*cb[0]+cb[1]*cb[1])));        double ccw1;        if(ca[0]*cb[1] - ca[1]*cb[0] > 0) ccw1 = 0;        else ccw1 = 1;
    
            ca[0] =  pointthree[0].x - pointthree[1].x;
            ca[1] =  pointthree[0].y - pointthree[1].y;
            cb[0] =  pointthree[2].x - pointthree[1].x;
            cb[1] =  pointthree[2].y - pointthree[1].y;        double angle2 = 180/3.1415*acos((ca[0]*cb[0]+ca[1]*cb[1])/(sqrt(ca[0]*ca[0]+ca[1]*ca[1])*sqrt(cb[0]*cb[0]+cb[1]*cb[1])));        double ccw2;        if(ca[0]*cb[1] - ca[1]*cb[0] > 0) ccw2 = 0;        else ccw2 = 1;
    
            ca[0] =  pointthree[1].x - pointthree[2].x;
            ca[1] =  pointthree[1].y - pointthree[2].y;
            cb[0] =  pointthree[0].x - pointthree[2].x;
            cb[1] =  pointthree[0].y - pointthree[2].y;        double angle3 = 180/3.1415*acos((ca[0]*cb[0]+ca[1]*cb[1])/(sqrt(ca[0]*ca[0]+ca[1]*ca[1])*sqrt(cb[0]*cb[0]+cb[1]*cb[1])));        double ccw3;        if(ca[0]*cb[1] - ca[1]*cb[0] > 0) ccw3 = 0;        else ccw3 = 1;
    
            CvPoint2D32f poly[4];        if(angle3>angle2 && angle3>angle1)
            {            if(ccw3)
                {
                    poly[1] = pointthree[1];
                    poly[3] = pointthree[0];
                }            else
                {
                    poly[1] = pointthree[0];
                    poly[3] = pointthree[1];
                }
                poly[0] = pointthree[2];
                Point temp(pointthree[0].x + pointthree[1].x - pointthree[2].x , pointthree[0].y + pointthree[1].y - pointthree[2].y );
                poly[2] = temp;
            }        else if(angle2>angle1 && angle2>angle3)
            {            if(ccw2)
                {
                    poly[1] = pointthree[0];
                    poly[3] = pointthree[2];
                }            else
                {
                    poly[1] = pointthree[2];
                    poly[3] = pointthree[0];
                }
                poly[0] = pointthree[1];
                Point temp(pointthree[0].x + pointthree[2].x - pointthree[1].x , pointthree[0].y + pointthree[2].y - pointthree[1].y );
                poly[2] = temp;
            }        else if(angle1>angle2 && angle1 > angle3)
            {            if(ccw1)
                {
                    poly[1] = pointthree[1];
                    poly[3] = pointthree[2];
                }            else
                {
                    poly[1] = pointthree[2];
                    poly[3] = pointthree[1];
                }
                poly[0] = pointthree[0];
                Point temp(pointthree[1].x + pointthree[2].x - pointthree[0].x , pointthree[1].y + pointthree[2].y - pointthree[0].y );
                poly[2] = temp;
            }
    
            CvPoint2D32f trans[4];        int temp = 50;
            trans[0] = Point2f(0+temp,0+temp);  
            trans[1] = Point2f(0+temp,100+temp);  
            trans[2] = Point2f(100+temp,100+temp);  
            trans[3] = Point2f(100+temp,0+temp);        //获取透视投影变换矩阵
            CvMat *warp_mat = cvCreateMat(3, 3, CV_32FC1);
            cvGetPerspectiveTransform(poly, trans, warp_mat);        //计算变换结果
            IplImage ipl_img(src_all);
            IplImage *dst = cvCreateImage(cvSize(1000, 1000), 8, 3);
            cvWarpPerspective(&ipl_img,dst,warp_mat);        //=========================================#ifdef DEBUG
            namedWindow("透视变换后的图");  
            cvShowImage("透视变换后的图",dst);         //透视变换后的图
    
            drawContours( drawingAllContours, contours, -1,  CV_RGB(255,255,255) , 1, 8);
            namedWindow("DrawingAllContours");  
            imshow( "DrawingAllContours", drawingAllContours );  
    
            namedWindow(pathtemp);  
            imshow(pathtemp , drawing );    //3个角点填充#endif
    
            //接下来要框出这整个二维码  
            Mat gray_all,threshold_output_all;  
            vector<vector<Point> > contours_all;  
            vector<Vec4i> hierarchy_all;  
            cvtColor( drawing, gray_all, CV_BGR2GRAY );  
    
            threshold( gray_all, threshold_output_all, 45, 255, THRESH_BINARY );
    
            findContours( threshold_output_all, contours_all, hierarchy_all,  RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0) );//RETR_EXTERNAL表示只寻找最外层轮廓  
    
            Point2f fourPoint2f[4];  
            //求最小包围矩形  
            RotatedRect rectPoint = minAreaRect(contours_all[0]);  
    
            //将rectPoint变量中存储的坐标值放到 fourPoint的数组中  
            rectPoint.points(fourPoint2f);  
            for (int i = 0; i < 4; i++)  
            {  
                line(src_all, fourPoint2f[i%4], fourPoint2f[(i + 1)%4],
                    Scalar(20,21,237), 3);  
            }  
    
            namedWindow(pathtemp);  
            imshow(pathtemp , src_all );
    
            //截取二维码区域
            CvSize size= cvSize(200,200);//区域大小
            cvSetImageROI(dst,cvRect(0,0,size.width, size.height));//设置源图像ROI
            IplImage* pDest = cvCreateImage(size,dst->depth,dst->nChannels);//创建目标图像
            cvCopy(dst,pDest); //复制图像
            cvSaveImage("Roi.jpg",pDest);//保存目标图像
    

    二维码的信息识别

    二维码的信息识别使用的是zbar,一个开源的二维码识别库,经过测试,对图像进行平滑,灰度等处理后识别效率还是很高的。zbar的算法流程简介:http://blog.csdn.net/u013738531/article/details/54574262。

            //对截取后的区域进行解码
            Mat imageSource = cv::Mat(pDest);
            cvResetImageROI(pDest);//源图像用完后,清空ROI
            cvtColor( imageSource, imageSource, CV_BGR2GRAY );  //zbar需要输入灰度图像才能很好的识别
    
            //Zbar二维码识别
            ImageScanner scanner;
            scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);  
            int width1 = imageSource.cols;        
            int height1 = imageSource.rows;        
            uchar *raw = (uchar *)imageSource.data;    
    
            Image imageZbar(width1, height1, "Y800", raw, width1 * height1);          
            scanner.scan(imageZbar); //扫描条码      
            Image::SymbolIterator symbol = imageZbar.symbol_begin();    
            if(imageZbar.symbol_begin()==imageZbar.symbol_end())    
            {    
                cout<<"查询条码失败,请检查图片!"<<endl;    
            }    
    
            for(;symbol != imageZbar.symbol_end();++symbol)      
            {        
                cout<<"类型:"<<endl<<symbol->get_type_name()<<endl;      
                cout<<"条码:"<<endl<<symbol->get_data()<<endl;        
            }
    
            imageZbar.set_data(NULL,0);    
    

    程序运行结果

    运行结果1:网站上生成的二维码,依次是原图,二值化,角点定位,旋转矫正,识别结果。

    运行结果2:相机拍摄的名片上二维码,依次是灰度图,二值化,角点定位,透视矫正,识别结果。

    推荐阅读

    重磅!3DCVer-学术论文写作投稿 交流群已成立

    扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

    同时也可申请加入我们的细分方向交流群,目前主要有3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流等微信群,请扫描下面微信号加群,备注:”研究方向+学校/公司+昵称“,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进去相关微信群。原创投稿也请联系。

    ▲长按加微信群或投稿

    ▲长按关注公众号

    3D视觉从入门到精通知识星球:针对3D视觉领域的知识点汇总、入门进阶学习路线、最新paper分享、疑问解答四个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近1000+星球成员为创造更好的AI世界共同进步,知识星球入口:

    学习3D视觉核心技术,扫描查看介绍,3天内无条件退款

     圈里有高质量教程资料、可答疑解惑、助你高效解决问题

    展开全文
  • 二维条码从类别上分为两大类,一类是以 PDF417 为代表的堆叠式二维条码, 还包括 CODE49 、 CODE 16K 等,其原理都是建立在一维条码的基础上。另一类是 以 ...是一些比较

    二维码分成两类:一类就是PDF417为代表的堆叠式条形二维码;另外的就是以QR为代表的矩阵式二维条码。

    PDF417是“便携式数据文件”的缩写。最少三层,最多90层。包括左右空白区,起始符,终止符,左右层指示符号字符等。它的具体架构如下:

    QR码:由编码区和功能区两个大块组成。

                  编码区由版本格式、数据、纠错编码等信息组成;

                  功能区由位置探测图形、校正图像和位置探测图像等。

                  QR条码的3位置探测图像是其快速识别的关键。

       

    数字图像的采集过程:

    在对二维码进行图像处理的时候需要的是:

            初级图像处理:图像去噪和图像锐化;

            中级图像处理:图像分割与边缘提取;

             高级图像处理:识别图像所包含的信息。


    二维码图像采集的方式:光笔(更多地用于一维码),激光(一维码和二维矩阵码),线阵(LED组成的矩阵)和图像。





    展开全文
  • 数字图像处理二维码图像提取算法(二)

    万次阅读 多人点赞 2014-11-06 13:28:01
    图像输入-> 图像预处理-> 二维码图像切割(定位)-> 二维码图像校正-> 译码 译码:二维码码字提取-> 纠错译码-> 信息译码 纠错译码:求解伴随因子(判断)  正确码字=Yji ^ 错误码字。; 信息译码:...
  • MATLAB二维码识别平台

    2020-07-30 23:30:27
    数字图像处理应用实例,利用matlab编程,实现二维码识别,包含灰度化,二值化,去噪滤波等
  • 51单片机二维码识别

    千次阅读 2019-07-29 18:15:18
    现在在做一个硬件项目,主要是用“高端的”51单片机连一个摄像头完成二维码识别的问题。 目录: 一、解决方案 二、详细分析 一、解决方案: 现在的需求是:给出二维码(可能存在图像偏移、旋转等问题),输出...
  • 提出了一种条码的初步定位算法,能够迅速的定位二维条码的大致范围,并将其切割出来,去掉大部分无用的背景信息,既能够减少干扰,提高识别率,又能够减少后续图像处理的时间,提高译码速度。   相较于其他的...
  • 视觉图像处理识别二维码。内附测试图片以及源码,适合视觉新手学习。
  • Android开发技巧——五分钟实现二维码识别

    万次阅读 热门讨论 2016-06-07 23:16:49
    二维码扫描解析现在已经成为一个综合型APP所不可或缺的一个功能了,有很多入门的开发者或许会苦恼二维码识别肯定是得会图像分析技术呀,难道还得学opencv吗?NO,Google早已想到这一点,因此也开源了二维码扫描、...
  • 前言 因工作需要,需要定位图片中的二维码;我遂查阅了相关资料,也...定位二维码,不仅需要图像处理相关知识,还需要分析二维码的特性,本文先从二维码的特性讲起。 1 二维码特性 二维码设计之初就考虑到了识...
  • 树莓派python实现二维码识别——ZBar

    千次阅读 2019-05-16 19:10:00
    在本文中,采用树莓派进行二维码识别,支持中英文的二维码或者一维条码的识别。硬件由树莓派3Bplus和usb摄像头组成,软件由python、二维码识别开源工具zbar和opencv组成。通过本文,可以学习如何正确快速安装zbar及...
  • Opencv+Zbar二维码识别(二维码校正)

    万次阅读 热门讨论 2016-08-12 23:43:01
    二维码和车牌识别基本都会涉及到图像的校正,主要是形变和倾斜角度的校正,一种二维码的畸变如下图: 这个码用微信扫了一下,识别不出来,但是用Zbar还是可以准确识别的~~。 这里介绍一种二维码校正方法,思路:...
  • Atitit java 二维码识别 图片识别

    千次阅读 2016-10-29 02:48:50
    Atitit java 二维码识别 图片识别 1.1. 解码 1 1.2. 首先,我们先说一下二维码一共有40个尺寸。官方叫版本Version。 1 1.3. 二维码的样例: 2 1.4. 定位图案 2 1.5. 数据编码 3 1.6. 错误修正容量L水平...
  • 二维码 二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”...
  • Opencv+Zbar二维码识别(标准条形码/二维码识别

    万次阅读 多人点赞 2016-08-05 23:13:40
    使用Opencv+Zbar组合可以很容易的识别图片中的二维码,特别是标准的二维码,这里标准值的是二维码成像清晰,图片中二维码的空间占比在40%~100%之间,这样标准的图片,Zbar识别起来很容易,不需要Opencv额外的处理。...
  • 【Android】二维码识别性能优化

    千次阅读 2017-06-19 13:49:23
    发现公司App的二维码识别效率不高 一查,居然每次识别要耗差不多1s,好吧 可以好好优化下了。。处理地方:1.data数据横竖屏转换对的,全世界都是这段代码,真没几个去优化下,但这里真的很慢,几百ms,不是开玩笑的...
  • 继上一次使用做二维码识别,公司需要高识别率的二维码识别,但ZXING实在是太弱了,对于那种二维码占比很小、图片对比度不高的,识别率低的令人咋舌,后来引入了opencv,加上恶补了一些图像处理的基础知识,总算有一...
  • 模糊二维码识别

    千次阅读 2020-06-29 17:48:13
    模糊二维码识别如果不想看累赘啰嗦的可直接点下面已搭建好的环境进行识别二维码,目前只开放了QR Code 如果不想看累赘啰嗦的可直接点下面已搭建好的环境进行识别二维码,目前只开放了QR Code 首先 大概说一下工业...
1 2 3 4 5 ... 20
收藏数 9,846
精华内容 3,938
关键字:

图像处理二维码识别的设计