精华内容
下载资源
问答
  • 一维条码,二维条码解码资料集.包含多篇论文涉及到 一维条码,二维条码解码解码算法,条码的亚像素超分辨率解码
  • 新人报道。。。 开个玩笑。...因为大部分的时候一维条码算法用于移动终端较多,基于图像的这种处理方式,会有个比较明显的缺点,就是一般的算法只能在摄像机聚焦后才能解码,也即只有在获取清晰地图...

     

    新人报道。。。

    开个玩笑。瓜农叔叔带你们收割,请大家准备好装备,大炮一定要记得带着。。。

      之前看过很多关于一维条码的算法,但效果都不行,也下过很多开源库,比如ZXing和Zbar,但这两个对于模糊条码的处理基本没作用。因为大部分的时候一维条码的算法用于移动终端较多,基于图像的这种处理方式,会有个比较明显的缺点,就是一般的算法只能在摄像机聚焦后才能解码,也即只有在获取清晰地图像之后才能解码。但摄像机的聚焦需要时间,快则1-2秒,慢则3-4秒,再加上解码以及镜头调整的时间,会导致这款应用的用户体验很差。

      之所以在这里说这么多废话,是给那些新同学看的,老同学就算了。你们可以忽略上述废话。

    这里提到的模糊条码是指摄像机没有聚焦的情况下,导致摄像机拍出的图片或者视频流中的条码部分不清晰。如下图所示:

                                            

                                                                                                       图 1

     

     

      ZXing和ZBar是无法解码上述图像的,因为仔细看了他们的代码就可以知晓一二了,他们的处理就是从图像中找出一条穿越整个条码的线(或者几条取平均值)。这样的处理就等于默认图像是清晰的。但图像如上图一所示时,这两个算法就显得无能为力了。在做这个算法之前,我也对此很是苦恼。(这就等于说你需要半年或许更久去研究新的算法并自己实现)。目前市场上比较流行的有我查查、redlaser(已经被ebay收购),这两个应用是可以扫描模糊的条码的。有兴趣的同学可以去下载玩玩看。但这两个应用对他们的算法细节只字未提,redlaser对开发者而言是可以购买的,具体的金额不太记得了,貌似挺贵的,是按照你的应用被多少终端使用来计算的,貌似需要0.06美元一个,也就是用户每次下载一个你的应用,你就需要向redlaser支付0.36RMB,其实这还是挺贵的。如果你的应用下载次数为一百万,那么就需要向他支付36万RMB,当然,作为一款这样的应用,如果只被下载一百万次,那么你的盈利肯定是不多的。据说我查查已经有一千两百万用户了,而redlaser在全球有2亿设备在使用。

      扯远了,回归主题。看了很多论文,但是真正有用的却屈指可数,于是找了一篇实现了下,感觉效果还不错,大体上已经脱离opencv了,但是条码定位部分还没将opencv的源码抠出来,现在也懒得做,因为手机端只要一个窗口对准条码部分就行了,这部分做只是浪费时间而已。文章名为"Reading 1-D Barcodes with Mobile Phones Using Deformable Templates",大致意思就是使用可变模型在手机上面进行以为条形码的解码,翻译的不太好,望见谅。

      文章的大体就是介绍一维条码的解码算法。重点就是算法使用的是full gray-level information,也就是说并不进行二值化(binarize)。将穿越条码的一条或者几条线拿出来做分析,并进行模板匹配,当然还有一些如何使得接触的码是正确的条码数字的算法。

      可恨的是文章给出的算法还是有很多缺陷的,比如对于光照比较强烈的时候导致的大光斑,如图2所示:

                               

                                                                                                      图 2

      图2所示的这些图片使用正常的算法是很难解码的, 使用上述文章的算法也比较困难。因此本人在实现算法的基础上加了一些其他的东西,比如如何将这些光斑去除,以及球面图像的校正算法。当然对于整个的框架作用并不是那么巨大。只是锦上添花的作用而已(这部分的功能暂不完整,还在处于调试的阶段)。

      很晚了,叔叔要睡觉了。明天继续part2。将会讲解一下关于算法的知识。

      转载请注明出处,否则追究版权责任!

     

     

     

     

     

     

     

     

    转载于:https://www.cnblogs.com/GNSS/p/barcode_decoder.html

    展开全文
  • 本文详细讲解了不同二维码的编码与解码算法
  • QR二维码编码解码原理算法介绍

    万次阅读 2013-03-08 13:41:32
    一、什么是二维码: 二维码 (2-dimensional bar code),是用某种特定...在许多种类的二维条码中,常用的码制有:Data Matrix, Maxi Code, Aztec, QR Code, Vericode, PDF417, Ultracode, Code 49, Code 16K等。  1
    一、什么是二维码:
    二维码 (2-dimensional bar code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的。
    在许多种类的二维条码中,常用的码制有:Data Matrix, Maxi Code, Aztec, QR Code, Vericode, PDF417, Ultracode, Code 49, Code 16K等。
      1.堆叠式/行排式二维条码,如,Code 16K、Code 49、PDF417(如下图)等
    PDF417
        2.矩阵式二维码,最流行莫过于QR CODE
    二维码的名称是相对与一维码来说的,比如以前的条形码就是一个“一维码”,
    它的优点有:二维码存储的数据量更大;可以包含数字、字符,及中文文本等混合内容;有一定的容错性(在部分损坏以后可以正常读取);空间利用率高等。
    二、QR CODE 介绍
    QR(Quick-Response) code是被广泛使用的一种二维码,解码速度快。
    它可以存储多用类型
    qrcode基本结构
    展开全文
  • -rs执行Reed-Solomon错误检测和纠正(请注意,RS错误纠正算法无法纠正pbm图像解码器引入的某些错误,例如由于多次检测到同一行而导致插入伪码字)。 安装 要编译解码器,只需执行“ make”即可。 假设您有合适的C...
  • 条码解析

    千次阅读 2013-03-14 17:49:56
    /* 所有解码函数返回值: 1:成功 2:检查码不对 0:失败 3:非本类条码 */   //-----------EAN13码解码算法---------------------------------------------------------------

    http://blog.csdn.net/billanking/article/details/5641563


    /*
    所有解码函数返回值: 1:成功 2:检查码不对 0:失败 3:非本类条码
    */

     


    //-----------EAN13码解码算法------------------------------------------------------------------------------
    /*
    EAN_13主要用在零售市场上,尤其在超级市场上。
    为一固定长度13的数字条码。
    编码原则:
    1:左护码,表示EAN_13的开始
    2:中护码,用来区隔左资料与右资料
    3:右护码,表示EAN_13的结束
    4:左资料码,包括6个数字资料,包括国家代码和厂商代码
    5:右资料码,包括5个数字资料,代表产品的代码,固定使用C组来编码
    6:检查码,1个数字,由导入值及左资料码,右资料码总共12位数字运算得来

    7:导入值,非条码,其资料来源是依照左资料码的排列次序得来的。也就是第一个数字,固定为A编码

    导入值 N1 N2 N3 N4 N5 N6
    0 A A A A A A
    1 A A B A B B
    2 A A B B A B
    3 A A B B B A
    4 A B A A B B
    5 A B B A A B
    6 A B B B A A
    7 A B A B A B
    8 A B A B B A
    9 A B B A B A
    8:ENA_13是一种(7,2)码,即每个数字都含有7个区间,每个码固定有2个空白,及2条细条
    */

    /*
    返回值: 1:成功 2:检查码不对 0:失败 3:非本类条码
    */
    int CodeBarParse::EAN13(unsigned char *sbar)
    {
    unsigned char Drz; //导入值
    unsigned char LCode[10][7]={"AAAAAA","AABABB","AABBAB","AABBBA","ABAABB","ABBAAB","ABBBAA","ABABAB","ABABBA","ABBABA"};
    unsigned char AB_Code[31][8]={"0001101","0011001","0010011","0111101","0100011","0110001","0101111","0111011","0110111","0001011",
    "0100111","0110011","1011011","0100001","0011101","0111001","0000101","0010001","0001001","0010111",
    "1110010","1100110","1101100","1000010","1011100","1001110","1010000","1000100","1001000","1110100"};
    int c=0;
    int sbar_p=0,sbar_p_c;
    unsigned char cr,cj,abp,j;
    unsigned char LB[7];
    barcode_ip = 1;
    //-----------------导入值-----------------------
    for(Drz=0;Drz<10;Drz++){
    sbar_p = 3;
    c = 0;
    for(cr=0;cr<7;cr++){
    if(sbar[sbar_p++]!=AB_Code[Drz][cr]){
    c = 1;break;
    }
    }
    if(c==0) break;
    }
    if((c==1)&&(Drz>=10)) return 0;
    barcode[barcode_ip++] = Drz;
    //-----------------左资料--------------------------
    j = 20;
    for(cj=1;cj<6;cj++){
    abp = 0;
    sbar_p_c = sbar_p;
    for(;abp<j;abp++){
    sbar_p = sbar_p_c;
    c = 0;
    for(cr=0;cr<7;cr++){
    if(sbar[sbar_p++]!=AB_Code[abp][cr]){
    c = 1;break;
    }
    }
    if(c==0) break;
    }
    if((c==1)&&(abp>=j)) return 0;
    if(abp<10) LB[cj] = 'A';
    else LB[cj] = 'B';
    barcode[barcode_ip++] = (abp%10);
    }
    sbar_p+=5;
    for(cj=0;cj<10;cj++){
    c=0;
    for(cr=1;cr<6;cr++){
    if(LCode[cj][cr]!=LB[cr]){
    c =1;
    break;
    }
    }
    if(c==0) break;
    }
    if((c==1)&&(cj>=10)) return 0;
    barcode[0] = cj;
    //-----------------右资料-----------------------------
    j = 30;
    for(cj=0;cj<6;cj++){
    abp = 20;
    sbar_p_c = sbar_p;
    for(;abp<j;abp++){
    sbar_p = sbar_p_c;
    c = 0;
    for(cr=0;cr<7;cr++){
    if(sbar[sbar_p++]!=AB_Code[abp][cr]){
    c = 1;break;
    }
    }
    if(c==0) break;
    }
    if((c==1)&&(abp>=j)) return 0;
    barcode[barcode_ip++] = (abp%10);
    }
    //-----------------检查码----------------------------------
    abp = 0;
    abp=(barcode[11]+barcode[9]+barcode[7]+barcode[5]+barcode[3]+barcode[1])*3;
    abp = abp + (barcode[0]+barcode[2]+barcode[4]+barcode[6]+barcode[8]+barcode[10]);
    abp = abp%10;
    for(c=0;c<barcode_ip;c++) barcode[c] |= 0x30;
    if(abp==0) abp = 0x30;
    else abp = (10-abp)+0x30;
    barcode[13] = 0;
    if(abp!=barcode[12]){
    return 2;
    }
    return 1;

    }
    //-----------EAN13码解码算法END----------------------------------------------------------------------------

    //-----------UPC_A码解码算法-------------------------------------------------------------------------------
    /*
    UPC_A的前6个字符都是由A集编码组成,后6个由C集编码组成。
    UPC-A条码是EAN-13条码的一种特殊形式,UPC-A条码与EAN-13码中N1='0'兼容。

    */
    int CodeBarParse::UPC_A(unsigned char *sbar)
    {
    unsigned char LCode[10][7]={"AAAAAA","AABABB","AABBAB","AABBBA","ABAABB","ABBAAB","ABBBAA","ABABAB","ABABBA","ABBABA"};
    unsigned char AB_Code[31][8]={"0001101","0011001","0010011","0111101","0100011","0110001","0101111","0111011","0110111","0001011",
    "0100111","0110011","1011011","0100001","0011101","0111001","0000101","0010001","0001001","0010111",
    "1110010","1100110","1101100","1000010","1011100","1001110","1010000","1000100","1001000","1110100"};
    int c=0;
    int sbar_p=0,sbar_p_c;
    unsigned char cr,cj,abp,j;
    unsigned char LB[7];
    barcode_ip = 0;
    //-----------------左资料--------------------------
    j = 20;
    sbar_p = 3;
    for(cj=0;cj<6;cj++){
    abp = 0;
    sbar_p_c = sbar_p;
    for(;abp<j;abp++){
    sbar_p = sbar_p_c;
    c = 0;
    for(cr=0;cr<7;cr++){
    if(sbar[sbar_p++]!=AB_Code[abp][cr]){
    c = 1;break;
    }
    }
    if(c==0) break;
    }
    if((c==1)&&(abp>=j)) return 0;
    if(abp<10) LB[cj] = 'A';
    else LB[cj] = 'B';
    barcode[barcode_ip++] = (abp%10);
    }
    sbar_p+=5;
    //-----------------右资料-----------------------------
    j = 30;
    for(cj=0;cj<6;cj++){
    abp = 20;
    sbar_p_c = sbar_p;
    for(;abp<j;abp++){
    sbar_p = sbar_p_c;
    c = 0;
    for(cr=0;cr<7;cr++){
    if(sbar[sbar_p++]!=AB_Code[abp][cr]){
    c = 1;break;
    }
    }
    if(c==0) break;
    }
    if((c==1)&&(abp>=j)) return 0;
    barcode[barcode_ip++] = (abp%10);
    }
    //-----------------检查码----------------------------------
    abp = 0;
    abp=(barcode[11]+barcode[9]+barcode[7]+barcode[5]+barcode[3]+barcode[1])*3;
    abp = abp + (barcode[0]+barcode[2]+barcode[4]+barcode[6]+barcode[8]+barcode[10]);
    abp = abp%10;
    for(c=0;c<barcode_ip;c++) barcode[c] |= 0x30;
    if(abp==0) abp = 0x30;
    else abp = (10-abp)+0x30;
    barcode[13] = 0;
    if(abp!=barcode[12]){
    return 2;
    }
    return 1;
    }
    //-----------UPC_A码解码算法END----------------------------------------------------------------------------

    //-----------UPC_E码解码算法-------------------------------------------------------------------------------
    /*
    UPC-E码只用於国别码为0的商品
    左护线:为辅助码,不具任何意义,仅供列印时作为识别之用,逻辑型态为010101,其中0代表细白,1代表细黑。
    右护线:同UPC-A码,逻辑型态为101。
    检查码:为UPC-A码原形的检查码,其作用为一导入值,并不属於资料码的一部份。
    资料码:扣除第一码固定为0外,UPC-E实际参与编码的部份只有六码,其编码方式,视检查码的值来决定,如表 2.3所示。奇资料码与偶资料码的逻辑值如表 2.4所示。
    sprintf((char*)bar,"101 0010001 0110111 0100001 0100011 0001011 0110011 010101");
    */
    int CodeBarParse::UPC_E(unsigned char *sbar,unsigned int ssl)
    {
    unsigned char checks[10][7]={"BBBAAA","BBABAA","BBAABA","BBAAAB","BABBAA","BAABBA","BAAABB","BABABA","BABAAB","BAABAB"};
    unsigned char CodeI[20][8]={"0001101","0011001","0010011","0111101","0100011","0110001","0101111","0111011","0110111","0001011",
    "0100111","0110011","0011011","0101001","0011101","0111001","0100101","0010001","0001001","0010111"};

    unsigned char checksum[7];
    unsigned char c_p=0,c;
    unsigned short i,abp,cr;
    unsigned char shar_p,shar_p_c;
    shar_p = 3;
    barcode_ip = 0;
    for(i=0;i<6;i++){
    if(shar_p>ssl)break;
    shar_p_c = shar_p;
    for(abp=0;abp<20;abp++){
    shar_p = shar_p_c;
    c = 0;
    for(cr=0;cr<7;cr++){
    if(sbar[shar_p++]!=CodeI[abp][cr]){
    c = 1;break;
    }
    }
    if(c==0) break;
    }
    if((c==1)&&(abp>=20)) return 0;
    cr = abp%10;
    barcode[barcode_ip++] = cr+0x30;
    if(abp>9) checksum[c_p++] = 'B';
    else checksum[c_p++] = 'A';
    }
    barcode[barcode_ip++] = 0;
    if(c_p>=6){
    for(abp=0;abp<10;abp++){
    c = 0;
    for(cr=0;cr<6;cr++){
    if(checksum[cr]!=checks[abp][cr]){
    c = 1;break;
    }
    }
    if(c==0) break;
    }
    if(c==1 && abp>=10) return 2;
    else return 1;
    }
    else return 0;
    return 1;
    }
    //-----------UPC_E码解码算法END----------------------------------------------------------------------------

    //-----------EAN8码解码算法--------------------------------------------------------------------------------
    int CodeBarParse::EAN8(unsigned char *sbar)
    {
    unsigned char LCode[10][7]={"AAAAAA","AABABB","AABBAB","AABBBA","ABAABB","ABBAAB","ABBBAA","ABABAB","ABABBA","ABBABA"};
    unsigned char AB_Code[31][8]={"0001101","0011001","0010011","0111101","0100011","0110001","0101111","0111011","0110111","0001011",
    "0100111","0110011","0011011","0100001","0011101","0111001","0000101","0010001","0001001","0010111",
    "1110010","1100110","1101100","1000010","1011100","1001110","1010000","1000100","1001000","1110100"};
    int c=0;
    int sbar_p=0,sbar_p_c;
    unsigned char cr,cj,abp,j;
    unsigned char LB[7];
    barcode_ip = 0;
    //-----------------左资料--------------------------
    j = 20;
    sbar_p = 3;
    for(cj=0;cj<4;cj++){
    abp = 0;
    sbar_p_c = sbar_p;
    for(;abp<j;abp++){
    sbar_p = sbar_p_c;
    c = 0;
    for(cr=0;cr<7;cr++){
    if(sbar[sbar_p++]!=AB_Code[abp][cr]){
    c = 1;break;
    }
    }
    if(c==0) break;
    }
    if((c==1)&&(abp>=j)) return 0;
    if(abp<10) LB[cj] = 'A';
    else LB[cj] = 'B';
    barcode[barcode_ip++] = (abp%10);
    }
    sbar_p+=5;
    //-----------------右资料-----------------------------
    j = 30;
    for(cj=0;cj<4;cj++){
    abp = 20;
    sbar_p_c = sbar_p;
    for(;abp<j;abp++){
    sbar_p = sbar_p_c;
    c = 0;
    for(cr=0;cr<7;cr++){
    if(sbar[sbar_p++]!=AB_Code[abp][cr]){
    c = 1;break;
    }
    }
    if(c==0) break;
    }
    if((c==1)&&(abp>=j)) return 0;
    barcode[barcode_ip++] = (abp%10);
    }
    //-----------------检查码----------------------------------
    abp = 0;
    abp=(barcode[1]+barcode[3]+barcode[5]);
    abp = abp + (barcode[0]+barcode[2]+barcode[4]+barcode[6])*3;
    abp = abp%10;
    if(abp==0) abp = 0x30;
    else abp = (10-abp)+0x30;
    for(c=0;c<barcode_ip;c++) barcode[c] |= 0x30;
    barcode[8] = 0;
    if(abp!=barcode[7]){
    return 2;
    }
    return 1;
    }
    //-----------EAN8码解码算法END----------------------------------------------------------------------------

    //-----------Code39码解码算法------------------------------------------------------------------------------
    /*
    1:每一个Code 39码字元条码,都由五条细线及四条空白构成。
    2:每个字元条码的最前字元及最后字元都由细线包裹起来。
    3:每个条码字符共9个单元,其中3个宽单元和6个窄单无,共包括5个条和4个空。
    4:Code39码是目前应用最广泛的条码,包含了数字及英文字母(大写)共44种字元。被广泛应用于超级市场及零售业。
    5:每个条码字符占12个单位的条宽
    6:Code39码可以通过两个字符来组合表示128个字符。
    7:39码必须包含一个不具任何意义的空白(或细白,其逻辑值为0)
    8:起始码+资料码+终止码
    9:校验字符为所有的资料码的字符序值和除以43的余数所对应字符
    10:可进行双向译码。
    */
    int CodeBarParse::Code39(unsigned char *sbar,unsigned int slen)
    {
    unsigned char CodeI[44][13]={"101001101101","110100101011","101100101011","110110010101","101001101011","110100110101","101100110101","101001011011","110100101101","101100101101",
    "110101001011","101101001011","110110100101","101011001011","110101100101","101101110101","101010011011","110101001101",
    "101101001101","101011001101","110101010011","101101010011","110110101001","101011010011","110101101001","101101101001",
    "101010110011","110101011001","101101011001","101011011001","110010101011","100110101011","110011010101","100101101011",
    "110010110101","100110110101",
    "100101011011","110010101101","100110101101","100100100101","100100101001","100101001001","101001001001","100101101101"
    };
    //-(36) . 空白  $ / + % *
    int si,t,k,t_c=1000;
    unsigned char flag=0;//状态(1:开始符,2:结束符)
    unsigned char c=0;
    unsigned int si_c;
    unsigned long checksum=0;
    barcode_ip = 0;
    for(si=0;si<slen;){
    si_c = si;
    for(t=0;t<44;t++){
    c = 0;
    si = si_c;
    for(k=0;k<12;k++){
    if(CodeI[t][k]!=sbar[si++]){
    c = 1;
    break;
    }
    }
    if(c==0)break;
    }
    if((c==1)&&(t>=44)) return 0;
    if(t==43){
    if(flag==0) flag++;
    else if(flag==1){
    flag++;
    break;
    }
    }
    else{
    if(flag>0){
    if((checksum%43!=t) || (barcode_ip==0)){ //校验
    while(1){
    if(t_c<500){
    c = t;
    t = t_c;
    t_c = 2000;
    }
    else if(t_c==2000){
    t = c;
    t_c = 1000;
    }
    checksum += t;
    if(t<10) barcode[barcode_ip++] = t+48;
    else if((t>=10)&&(t<36)) barcode[barcode_ip++] = t+55;
    else if(t==36) barcode[barcode_ip++] = '-';
    else if(t==37) barcode[barcode_ip++] = '.';
    else if(t==38) barcode[barcode_ip++] = ' ';
    else if(t==39) barcode[barcode_ip++] = '

    ;
    else if(t==40) barcode[barcode_ip++] = 0x25;
    else if(t==41) barcode[barcode_ip++] = '+';
    else if(t==42) barcode[barcode_ip++] = 0x2F;
    else if(t==43) barcode[barcode_ip++] = '*';
    if(t_c==1000) break;
    }
    }
    else{
    t_c=t;
    }
    }
    }
    if(sbar[si++]!='0') return 2;
    }
    barcode[barcode_ip++] = 0;
    if(flag==2) return 1;
    else return 2;
    }
    //-----------Code39码解码算法END--------------------------------------------------------------------------------

     

    //-----------Code128码解码算法----------------------------------------------------------------------------------
    /*
    1:具有A,B,C三种编码,提供标准的ASCII的128个字符的编码
    2:可双向扫描处理
    3:可自行加上检查码
    4:条码长度可自由调整,但包括起码和终止码在內,不可超过232个字元
    5:同一个128码,可以采用不同的方式进行编码。藉由A、B、C三种不同编码规则的互换可扩大字符选择的范围,也可缩短编码的长度。

    128码的编码方式
      128码有三种不同类型的编码方式,对于选择何种编码方式,则决定于起始码的內容。
       起始码

    编码类别 逻辑型态 相对值
    CODE A 11010000100 103
    CODE B 11010010000 104
    CODE C 11010011100 105

       终止码
    无论是采用A、B、C何种编码方式,128码的终止码均为固定的一种性能,其逻辑型态皆为1100011101011。
    6:Code128与Code39码具有很大的相似性。都广泛运用在企业内部管理、生产流程、物流控制系统方面。
    不同的在于Code 128比Code 39能表现更多的字符,单位长度里的编码密度更高。
    7:每个字符由3个条、3个空、11个单元构成,字符串可变长;
    8:字符集
    字符集A:{大写字母,数字字符,标点字符,控制字符(ASCII值为00到95的字符),7个控制字符(字符值96~102)}
    字符集B:{大写字母,数字字符,标点字符,小写字母字符(ASCII值为32到127的字符),7个控制字符(字符值96~102)}
    字符集C:{100个数字(00~99),以及3个特殊字符},适用字符集C时,用一个符号字符表示两个数字。

    9:切换字符和转换字符。(控制字符序列中)
    A:切换字符CodeA(B或C)将符号字符集从先前确定的字符集转变到切换字符指定的新的字符集。
    这种转变适用于切换字符之后的所有字符址到符号结束或遇到另一个切换字符或转换字符。
    B:转换字符SHIFT将转换字符之后和(一个字符)从字符集A转换到字符集B,或从字符集B转换到字符集A。
    在被转换字符后边的字符将恢复为转换字符前定义的字符集A或字符集B,被转换的符号字符不能是切换字符或转换字符。
    10:符号检验字符

    */
    int CodeBarParse::Code128(unsigned char *sbar,unsigned int slen)
    {
    unsigned char CodeI[107][12]={"11011001100","11001101100","11001100110","10010011000","10010001100","10001001100","10011001000","10011000100","10001100100","11001001000","11001000100",
    "11000100100","10110011100","10011011100","10011001100","10111001100","10011101100","10011100110","11001110010","11001011100","11001001110","11011100100",
    "11001110100","11101101110","11101001100","11100101100","11100100110","11101100100","11100110100","11100110010","11011011000","11011000110","11000110110",
    "10100011100","10001011000","10001000110","10110001000","10001101000","10001100010","11010001000","11000101000","11000100010","10110111000","10110111000",
    "10001101110","10111011000","10111000110","10001110110","11101110110","11010001110","11000100110","11011101000","11011100010","11011101110","11101011000",
    "11101000110","11100010110","11101101000","11101100010","11100011010","11101111010","11001000010","11110001010","10100110000","10100001100","10010110000",
    "10010000110","10000101100","10000100110","10110010000","10110000100","10011010000","10011001010","10000110100","10000110010","11000010010","11001010000",
    "11110111010","11000010100","10001111010","10100111100","10010111100","10010011110","10111100100","10011110100","10011110010","11110100100","11110010100",
    "11110010010","11011011110","11011110110","11110110110","10101111000","10100011110","10001011110","10111101000","10111100010","11110101000","11110100010",
    "10111011110","10111101110","11101011110","11110101110","11010000100","11010010000","11010011100","11000111010"};

    unsigned char bm_flag,cur_bm; //编码方式
    unsigned char shitf_s=0;
    unsigned char c,cs;
    unsigned int si=0,si_c;
    unsigned int t,k;

    unsigned long checksum=0;
    unsigned short cid=1;
    unsigned char check=0;
    barcode_ip = 0;
    for(si=0;si<slen;si++){
    si_c = si;
    for(t=0;t<107;t++){
    c = 0;
    si = si_c;
    for(k=0;k<11;k++){
    if(CodeI[t][k]!=sbar[si++]){
    c = 1;
    break;
    }
    }
    if(c==0){ si--;break;}
    }
    if((c==1)&&(t>=107)) return 0;
    if(t<103){
    if(cur_bm==1){
    if(t<=63) cs = t+32;
    else{
    if((t>=64) && (t<=95)) cs = t-64;
    else cs = 0x20;
    }
    }
    else if(cur_bm==2){
    if(t<=95) cs = t+32;
    else cs = 0x20;
    }
    else if(cur_bm==3){
    cs = t;
    }
    if((checksum%103)==t) check=1;
    else check=0;
    checksum = checksum + (cid*t);
    cid++;
    if(cur_bm==3){
    if(t>9){
    barcode[barcode_ip++] = (t/10)+0x30;
    t = t%10;
    }
    barcode[barcode_ip++] = t+0x30;
    }
    else barcode[barcode_ip++] = cs;
    if(shitf_s==1){
    shitf_s = 0;
    cur_bm = bm_flag;
    }
    }
    else if(t==103){ bm_flag = 1; cur_bm = bm_flag; checksum = 103;}
    else if(t==104){ bm_flag = 2; cur_bm = bm_flag; checksum = 104;}
    else if(t==105){ bm_flag = 3; cur_bm = bm_flag; checksum = 105;}
    else if(t==98){
    shitf_s = 1;
    if(bm_flag==1) cur_bm = 2;
    else cur_bm = 1;
    }
    else if(t==106){
    break;
    //if(sbar[si++]=='1')
    //if(sbar[si++]=='1')
    }
    }
    if(check==1){
    if(barcode_ip>0){
    if((cs>9) && (cur_bm==3)) barcode_ip--;
    barcode_ip--;
    }
    }
    barcode[barcode_ip] = 0;
    return 1;
    }
    //-----------Code128码解码算法END-------------------------------------------------------------------------------


    //-----------交插25码解码算法E---------------------------------------------------------------------------------
    /*
    interleaved 2 of 5 bar code
    密度较高,适用于运输,仓库,工业生产线,图书情报等领域。
    是一种连续型,非定长,具有自检验功能,且条空都且示信息的双向条码

    A:条码符号由左侧空白区,超始符,数据符,终止符及右空白区构成。它的每个条码数据符都由5个单元组成。其中二个是宽
     单元(1表示),其余是窄单无(0表示)
    B:组成条码符号的条码数据符个数为偶数
    C:条码符号从左到右,表示奇数位字符的条码数据符由条组成,表示偶数位字符的条码数据符由空组成。
    D:条码数据符所表示的字符个数为奇数时,庆在字符串左端添加'0'.
    E:起始符包括两个窄条和两个窄空。
    F:终止符包括两个条(一个宽,一个窄条)
    */

    int CodeBarParse::Interleaved25(unsigned char *sbar,unsigned int slen)
    {
    unsigned char CodeI[10][6]={"00110","10001","01001","11000","00101","10100","01100","00011","10010","01010"};
    unsigned char ca[6],cb[6];
    unsigned char cab_p=0;
    int jo=0;
    unsigned int si=4;

    unsigned char c;
    unsigned int i,j;
    barcode_ip = 0;
    ca[0] = 0; cb[0] = 0;
    for(;si<slen;si++){
    if(sbar[si]=='1'){
    if(jo<0){
    if(jo<-1)cb[cab_p] = '1';
    else cb[cab_p] = '0';
    cab_p++;
    if(cab_p>=5){
    for(i=0;i<10;i++){
    c = 0;
    for(j=0;j<5;j++){
    if(CodeI[i][j]!=ca[j]){
    c = 1;
    break;
    }
    }
    if(c==0) break;
    }
    if(c==1 && i>=10) return 0;
    if(barcode_ip==0){
    if(i!=0) barcode[barcode_ip++] = i+0x30;
    }
    else barcode[barcode_ip++] = i+0x30;
    //------------------------------
    for(i=0;i<10;i++){
    c = 0;
    for(j=0;j<5;j++){
    if(CodeI[i][j]!=cb[j]){
    c = 1;
    break;
    }
    }
    if(c==0) break;
    }
    if(c==1 && i>=10) return 0;
    barcode[barcode_ip++] = i+0x30;
    cab_p = 0; ca[0] = 0; cb[0] = 0;
    }
    jo=1;
    }
    else jo++;
    }
    else{
    if(jo>0){
    if(jo>1) ca[cab_p] = '1';
    else ca[cab_p] = '0';

    jo=-1;
    }
    else jo--;
    }
    }
    barcode[barcode_ip++] = 0;
    if(ca[0]!='1') return 2;
    if(cb[0]!='0') return 2;
    return 1;
    }
    //-----------交插25码解码算法END-------------------------------------------------------------------------------

    //-----------Codebar码解码算法---------------------------------------------------------------------------------
    /*

    1:适用于医疗卫生,图书情报等领域
    2:库德巴条码是一种非连续型,非定长,具有自校验功能的双向条码。由条码字符及对庆的人供人识别的字符组成
    3:由左侧空白区,起始符,数据符,终止符,及右侧空白区构成。它的每一个条码字符由七个单元组成,四个条和三个空组成,
     其中两个或三个单元是宽单元(用1表示),其余是窄单元(用0表示)。
    */
    int CodeBarParse::Codebar(unsigned char *sbar,unsigned int slen)
    {
    unsigned char CodeI[20][8]={"0001001","0010001","0001010","1000100","0100001","1000001","0001100","0010100","0100100","1000010",
    "0100010","0010010","1011000","1101000","1110000","0111000","0100011","0001110","0001011","0010011"};

    unsigned char ca[8];
    unsigned char ca_p=0;
    unsigned char flag=0;
    short jo=0;
    unsigned int si=0;

    unsigned char c;
    unsigned int i,j;
    unsigned char con=0;
    barcode_ip = 0;
    for(si=0;si<slen;si++){
    if(sbar[si]=='1'){
    if(jo<0){
    if(jo<-1) flag = '1';
    else flag = '0';
    if(ca_p==1) ca[4] = flag;
    else if(ca_p==3) ca[5] = flag;
    else if(ca_p==5) ca[6] = flag;
    ca_p++;
    jo=1;
    }
    else jo++;
    if(si==slen-1) con = 1;
    else con=0;
    }
    else con = 1;
    if(con==1){
    if(jo>0){
    if(jo>1) flag='1';
    else flag = '0';
    if(ca_p==0) ca[0] = flag;
    else if(ca_p==2) ca[1] = flag;
    else if(ca_p==4) ca[2] = flag;
    else if(ca_p==6) ca[3] = flag;
    ca_p++;
    jo = -1;
    if(ca_p>6){
    for(i=0;i<20;i++){
    c = 0;
    for(j=0;j<7;j++){
    if(CodeI[i][j]!=ca[j]){
    c = 1; break;
    }
    }
    if(c==0)break;
    }
    if(c==1 && i>=20){
    if(barcode_ip==0) return 3;
    else return 0;
    }
    if(i<10) barcode[barcode_ip++] = i+0x30;
    else if(i==10) barcode[barcode_ip++] = '

    ;
    else if(i==11) barcode[barcode_ip++] = '-';
    else if(i==12) barcode[barcode_ip++] = ':';
    else if(i==13) barcode[barcode_ip++] = 0x2F;
    else if(i==14) barcode[barcode_ip++] = '.';
    else if(i==15) barcode[barcode_ip++] = '+';
    ca_p=0;
    jo=0;
    }
    }
    else jo--;
    }
    }
    barcode[barcode_ip++] = 0;
    return 1;
    }

    //-----------Codebar码解码算法END-------------------------------------------------------------------------------

    //-----------Code93码解码算法-------------------------------------------------------------------------------
    /*
    1:密度比39码要高点,采用双校验法,安全性要高
    2:每个字符由三个条三个空组成。
    3:左侧空白区,起始码,资料区,检查码C,检查码K,结束码,右侧空白区组成
    4:可表示0~9,A~Z,符号(-,.,空格,$,/,+,%),控制码($,%,/+)-(!,#,&,@)
    5:结束符为1010111101

    存在一点问题(K检验对不上位)
    */
    int CodeBarParse::Code93(unsigned char *sbar,unsigned int slen)
    {
    unsigned char CodeI[49][10]={"100010100","101001000","101000100","101000010","100101000","100100100","100100010","101010000","100010010","100001010",
    "110101000","110100100","110100010","110010100","110010010","110001010","101101000","101100100","101100010","100110100",
    "100011010","101011000","101001100","101000110","100101100","100010110","110110100","110110010","110101100","110100110",
    "110010110","110011010","101101100","101100110","100110110","100111010","100101110","111010100","111010010","111001010",
    "101101110","101101110","110101110","100100110","111011010","111010110","100110010","101011110","101011110"};

    int si,t,k;
    unsigned char flag=1;//状态(1:开始符,2:结束符)
    unsigned char c=0;
    unsigned int si_c;
    unsigned long checksumC=0,checksumK;
    barcode_ip = 0;
    for(si=9;si<slen;){
    si_c = si;
    for(t=0;t<49;t++){
    c = 0;
    si = si_c;
    for(k=0;k<9;k++){
    if(CodeI[t][k]!=sbar[si++]){
    c = 1;
    break;
    }
    }
    if(c==0)break;
    }
    if((c==1)&&(t>=49)) {
    if(barcode_ip>3) break;
    else return 0;
    }
    if(t==47){
    if((si+1)==slen){ flag++; break;}
    flag = 1;
    }
    else if(t==48){
    flag++;
    break;
    }
    else{
    barcode[barcode_ip++] = t;
    }
    }
    t = 1;
    if(barcode_ip<3) return 3;
    for(si=barcode_ip-3;si>=0;){
    checksumC = checksumC + (barcode[si]*t);
    t++;
    if(t>20) t=1;
    if(si==0) break;
    else si--;
    }
    t = 2;
    checksumC = checksumC%47;
    checksumK = checksumC;
    for(si=barcode_ip-3;si>=0;){
    checksumK = checksumK + (barcode[si]*t);
    t++;
    if(t>15) t=1;
    if(si==0) break;
    else si--;
    }
    checksumK = checksumK%47;
    if(barcode[barcode_ip-2]==checksumC) c = 0;
    else c=1;
    barcode_ip = barcode_ip - 2;
    for(si=0;si<barcode_ip;si++){
    if(t<10) barcode[si] = barcode[si]+48;
    else if((t>=10)&&(t<36)) barcode[si] = barcode[si]+55;
    else if(t==36) barcode[si] = '-';
    else if(t==37) barcode[si] = '.';
    else if(t==38) barcode[si] = ' ';
    else if(t==39) barcode[si] = '

    ;
    else if(t==40) barcode[si] = 0x25;
    else if(t==41) barcode[si] = '+';
    else if(t==42) barcode[si] = 0x2F;
    }
    barcode[barcode_ip++] = 0;
    if(flag==2){
    if(c==1) return 2;
    return 1;
    }
    else return 2;
    }
    //-----------Code93码解码算法END-------------------------------------------------------------------------------


    //------------UCC/EAN-128码解码算法----------------------------------------------------------------------------
    /*
    在code128的基础上,起始符后跟一个功能符,来表示与Code128的不同。

    */
    int CodeBarParse::UCC_EAN128(unsigned char *sbar,unsigned int slen)
    {
    return 1;
    }

    //------------UCC/EAN-128码解码算法END----------------------------------------------------------------------------

    //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@编码@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    int CodeBarParse::Ecode39(unsigned char *data,unsigned char *bar)
    {
    unsigned char CodeI[44][13]={"101001101101","110100101011","101100101011","110110010101","101001101011","110100110101","101100110101","101001011011","110100101101","101100101101",
    "110101001011","101101001011","110110100101","101011001011","110101100101","101101100101","101010011011","110101001101",
    "101101001101","101011001101","110101010011","101101010011","110110101001","101011010011","110101101001","101101101001",
    "101010110011","110101011001","101101011001","101011011001","110010101011","100110101011","110011010101","100101101011",
    "110010110101","100110110101",
    "100101011011","110010101101","100110101101","100100100101","100100101001","100101001001","101001001001","100101101101"
    };
    unsigned int i;
    unsigned short cip=0;
    unsigned int bar_i=0;
    unsigned int datal,k;
    unsigned long checksum=0;

    datal = strlen((char*)data);
    cip = 43;
    for(i=0;i<12;i++) bar[bar_i++] = CodeI[cip][i];
    bar[bar_i++] = '0';
    for(k=0;k<datal;k++){
    if(data[k]>=48 &&data[k]<58) cip = data[k]-48;
    else if((data[k]>=65)&&(data[k]<92)) cip = data[k]-55;
    else if(data[k]==0x2D) cip = 36;
    else if(data[k]=='.') cip = 37;
    else if(data[k]==' ') cip = 38;
    else if(data[k]=='

    ) cip = 39;
    else if(data[k]==0x25) cip= 40;
    else if(data[k]=='+') cip = 41;
    else if(data[k]==0x2F) cip = 42;
    else if(data[k]=='*') cip = 43;
    checksum += cip;
    for(i=0;i<12;i++) bar[bar_i++] = CodeI[cip][i];
    bar[bar_i++] = '0';
    }
    cip = checksum%43;
    for(i=0;i<12;i++) bar[bar_i++] = CodeI[cip][i];
    bar[bar_i++] = '0';
    cip = 43;
    for(i=0;i<12;i++) bar[bar_i++] = CodeI[cip][i];
    bar[bar_i++] = 0;
    return bar_i;
    }

     


    展开全文
  • 采用较低量化阶数的防伪掩模进行解码后,利用图像形态学相关算法成功恢复出原二维条码的准确编码信息,进而通过二维条码解码得到原始的文本和图像。该设计方法不但有效解决了传统光学相位编码方法的物理实现难题,而且...
  • 整个系统由低到高分为三个层次:条码识别的硬件平台、μC/OS—II操作系统、条码译码核心算法。最底层硬件平台采用Altera公司的Cylone II EP2C35与ADI公司的视频解码芯片ADV7181B,具有8 MB的Flash存储器,1.MB的...
  • 本文着重以图像处理的方法来解决上述二维条码识别中遇到的各种问题,研究最佳识别...同时,研究二维条码中常用的差错控制算法,Reed-Solomon纠错算法;外,本文还介绍各二维条码的数据编码、解码方式,提出了实现方案。
  • 本文提出了一种基于局部透视变换的图像矫正算法,将圆柱体侧表面PDF417条码分割为若干子区域,然后对各个子区域分别进行透视变换,将各个子区域分别矫正之后再行拼接,最后得到平面PDF417条码的图像。实验结果表明,该...
  • 水准仪编解码困难,提出一套新的编解码方案,采用混合编码,基于面阵CCD接收器,利用二维信号的优越性,解决视距太小不能满足条码样本数与视距太大图像分辫率低的矛盾,研究水准测量的技术核心问题,并通过算法优化,达到...
  • 黑白条码由于数据容量的局限性已无法满足用户需求,据此在Gzip压缩算法的基础上设计了一种彩色QR码的生成和识别方法。该方法的编码颜色为2k种时,每个模块可编码k个二进制数据。通过增加编码颜色和Gzip压缩算法显著...
  • 二维码采用黑白相间的平面几何图形通过相应的编码算法来记录文字、图片、网址等信息的条码图片
  • 使用数码相机、手机、电脑摄像头等通用摄入设备采集的条码图像普遍存在有高光区、阴影...本文以摄像头拍摄的有散焦模糊等噪声影响的QR码图像为例,研究了在一定复杂度限制的条码图像处理技术,提出了完整的预处理算法
  • QRCode编码解码标准.doc

    2019-08-23 14:53:19
    它规定了QR码模式2符号的特征,数据字符编码,符号格式,尺寸特征,纠错规则,参考译码算法,符号质量要求,以及可由用户选择的应用参数,在附录中给出了QR码模式1符号不同于模式2的特性。 2 一致性 QR码符号(及...
  • 二维码采集与识别

    2014-03-09 21:41:01
    然后分析了基于图像处理的二维码解码算法的一般过程,并对图像预处理、二维码的定位于校正以及数据纠错过程中涉及到的关键算法进行分析比较。针对快速响应矩阵码(QR code),详细设计基于图像处理的QR码解码的算法...
  • QR+Code论文研究.pdf

    2011-07-21 17:38:44
    本论文研究的目的是通过分析OR码的符号结构,研究QR码的编码规则与纠错 编码算法,完成QR码符号生成软件的设计,并且提出...二维条码解码的正确性以及提高二维条码识别系统的识读率和识读速度等重要指标 具有重要意义。
  • 动态阈值方法收集

    2019-09-22 23:29:41
    在条码识别过程中,虽然Zbar做好的条码解码,但是前期不少工作要自己做,其中就涉及到动态求阈值(虽然最后没有采用求阈值的方法),但是还是需要记录下动态阈值的方法,以后按名字具体找就好 图像处理基本算法 ...

    在条码识别过程中,虽然Zbar做好的条码解码,但是前期不少工作要自己做,其中就涉及到动态求阈值(虽然最后没有采用求阈值的方法),但是还是需要记录下动态阈值的方法,以后按名字具体找就好

    图像处理基本算法 动态阈值分割

    最后采用的是记算波动数量和频率的方法求出是否存在条码的,代码不能贴

    转载于:https://www.cnblogs.com/Jacket-K/p/9137892.html

    展开全文
  • HALCON 的条形码读取器通过高级解码算法得到了改进,该算法提高了读取小尺寸条形码时的解码成功率。因此,HALCON 20.05 中的条形码读取器甚至能够精确读取小于1个像素的条码。 2、更加灵活的基于CPU的深度学习训练 ...
  • [quote][导读] 二维码是二维条形码的一种,可以将网址、文字、照片等信息通过相应的编码算法编译成为一个方块形条码图案,手机用户可以通过摄像头和解码软件将相关信息重新解码并查看内容 php类库PHP QR Code 两句话...
  • 本文基于Windows C# 来开发QR识别和译码程序,运用图像校正、二值化、边缘检测等各种图像处理方法实现条码的预处理,并进行QR码的解码和Reed-Solomon纠错算法,充分利用面向对象的方法,结合图像处理技术,完成了...
  • 二维码是二维条形码的一种,可以将网址、文字、照片等信息通过相应的编码算法编译成为一个方块形条码图案,手机用户可以通过摄像头和解码软件将相关信息重新解码并查看内容。 读取方式: 利用30万画素以上的照相...
  • PHP通过PHP QR Code生成二维码

    千次阅读 2014-09-15 23:25:30
    二维码是二维条形码的一种,可以将网址、文字、照片等信息通过相应的编码算法编译成为一个方块形条码图案,手机用户可以通过摄像头和解码软件将相关信息重新解码并查看内容。通过PHP QR Code如何实现二维码呢?
  • 二维码生成器

    2011-12-29 12:45:57
    【应用信息】二维码是二维条形码的一种,可以将网址、文字、照片等信息通过相应的编码算法编译成为一个方块形条码图案,手机用户可以通过摄像头和解码软件将相关信息重新解码并查看内容。 【应用特点】可以根据...
  • 目录1. 一维码原理1.1 定义:...人们用一些黑白相间的条纹构成的图案叫一维码,也叫条码。 1.2 作用: 它可以很方便的将一些信息,通过算法存储到图案中(编码)。 1.3 解码: 识别一维码,把信息通过算法解析出来。
  • 码规则和识别解码方法, 采用 了 B M 迭代译码算法进行纠错译码; 分 析了在 W i nC E 下 U SB 摄像头采集图像的实现方法 , 研究 了图像预处 理方法 , 采用 了 O T SU 算法选择 阑值 , 并对 图像进行二值化处理 , 利 ...

空空如也

空空如也

1 2 3
收藏数 48
精华内容 19
关键字:

条码解码算法