EAN条形码译码器代码.doc_第1页
EAN条形码译码器代码.doc_第2页
EAN条形码译码器代码.doc_第3页
EAN条形码译码器代码.doc_第4页
EAN条形码译码器代码.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

#include #include #include #include #include #define BI_RGB 0L#define BI_RLE8 1L#define BI_RLE4 2L#define BI_BITFIELDS 3Ltypedef struct unsigned char rgbBlue;unsigned char rgbGreen;unsigned char rgbRed;unsigned char rgbReserved; RGBQUAD;typedef struct unsigned long biSize;long biWidth;long biHeight;unsigned short biPlanes;unsigned short biBitCount;unsigned long biCompression;unsigned long biSizeImage;long biXPelsPerMeter;long biYPelsPerMeter;unsigned long biClrUsed;unsigned long biClrImportant; BITMAPINFOHEADER;typedef struct BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors1; BITMAPINFO;#include /typedef struct unsigned short bfType;unsigned long bfSize;unsigned short bfReserved1;unsigned short bfReserved2;unsigned long bfOffBits; BITMAPFILEHEADER;#include /* 参考BMP文件格式*/int ReadBMPToBuf(char *FileName,unsigned char *RawImageData,int *ImageWidth,int *ImageHeight)BITMAPFILEHEADER bmfileh;/BMP文件头变量BITMAPINFOHEADER bminfoh;/位图信息头FILE *fp;int TotalPixelNumber;fp = fopen(FileName, rb);/读写打开一个二进制文件,允许读数据if (fp = NULL) return -1;int s1=sizeof(bmfileh);/求文件头字节数,int s2=sizeof(bminfoh);/求位图信息头字节数,fread(&bmfileh, 1, sizeof(bmfileh), fp);fread(&bminfoh, 1, sizeof(bminfoh), fp);*ImageHeight = abs(bminfoh.biHeight);*ImageWidth = bminfoh.biWidth;/TotalPixelNumber = bmih.biHeight*(bmih.biWidth); TotalPixelNumber = bmfileh.bfSize - bmfileh.bfOffBits;fseek(fp,bmfileh.bfOffBits,SEEK_SET);/指针偏移bmfileh.bfoffbits。 /bfOffBits Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits. *RawImageData = (unsigned char *) calloc(TotalPixelNumber),sizeof(unsigned char);/在内存的动态存储区中分配连续空间。fread(*RawImageData, 1,TotalPixelNumber,fp);fclose(fp);/if(bminfoh.biHeight0)/Specifies the ImageHeight of the bitmap, in pixels. If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, the bitmap is a top-down DIB and its origin is the upper-left corner. /If biHeight is negative, indicating a top-down DIB, biCompression must be either BI_RGB or BI_BITFIELDS. Top-down DIBs cannot be compressed. unsigned char *RowBuffer=NULL; RowBuffer = (unsigned char *) calloc(*ImageWidth),sizeof(unsigned char);int i,j;j = *ImageHeight/2;unsigned char *ptr1,*ptr2;ptr1 = *RawImageData;/第一行 ,ptr2 = *RawImageData + (*ImageHeight-1)*(*ImageWidth);/最后一行,for(i=0;ij;i+)memcpy(RowBuffer,ptr1,*ImageWidth);memcpy(ptr1,ptr2,*ImageWidth);memcpy(ptr2,RowBuffer,*ImageWidth);ptr1 += *ImageWidth;ptr2 -= *ImageWidth; free(RowBuffer); RowBuffer = NULL;return 0;/* *cell 输入 图像数据 nw 输入 图像宽度 nh 输入 图像高度 *edge_position 输出 边界坐标 *edge_num 输出 边界坐标个数*/int Get_Bar_edge(unsigned char *cellbuf,int nw,int nh,int *edge_position,int* edge_num) int i,j; int *vertical=new intnw; /垂直投影值float *fvertical=new floatnw; /归一化后的投影值int Pmax,Pmin,T1,ration;enum EdgeTypewtb,btw; /定义边界的性质是聪白到黑,还是聪黑到白 EdgeType *edgetype=new EdgeTypenw; int edgecount=0; /边界的个数/ 投影for (i=0;inw;i+) verticali=0; for (j=0;jnh;j+) verticali+=cellbufj*nw+i; /归一化处理Pmax=Pmin=vertical0;for (i=0;inw;i+)if (verticaliPmax) Pmax=verticali; ration=Pmax-Pmin;for (i=0;inw;i+) fverticali=(float)(verticali-Pmin)*nh/ration; / 开始寻找边界,定义边界跳变的阈值 T1=nh/3; / 第一个边界一定是从白到黑的 for (i=5;iT1) edge_positionedgecount=i;edgetypeedgecount=wtb;edgecount+;break;while (iT1)if (fverticali-1fverticali+1&edgetypeedgecount-1=btw)edge_positionedgecount=i;edgetypeedgecount=wtb;edgecount+;if (fverticali-10) return (1);if (x0) return(-1);return(0);int Get_Bar_edge_a(unsigned char *cellbuf,int nw,int nh,int *edge_position,int* edge_num) int i,j,stdh=255,strx,endx,sign,ret;int Pmax,Pmin,T1,ration,edgennum;enum EdgeTypewtb,btw; EdgeType *edgetype=new EdgeTypenw; int edgecount=0;int *edge=new intnw; int *vertical=new intnw;int *vertical1=new intnw;float *fvertical=new floatnw; /归一化后的投影值int *vdis=new intnw;/投影for (i=0;inw;i+) verticali=0; for (j=0;jnh;j+) verticali+=cellbufj*nw+i; memcpy(vertical1,vertical,nw*sizeof(int);/对投影排序for (i=0;inw-1;i+)for (j=i+1;jnw;j+)if (vertical1jvertical1i) int tmpv=vertical1j; vertical1j=vertical1i; vertical1i=tmpv;int nmeant=nw/20; / 取最小的5的均值为下限 Pmin=0;for (i=0;inmeant;i+) Pmin+=vertical1i;Pmin=Pmin/nmeant;/ 取最大的5的均值为上限 Pmax=0;for (i=nw-nmeant;inw;i+)Pmax+=vertical1i;Pmax=Pmax/nmeant;/ Pmax=Pmin=vertical0;/ / for (i=0;inw;i+)/ / / if (verticaliPmax) Pmax=verticali;/ ration=Pmax-Pmin; if (ration=0) ret=-1; goto ENDPOINT;/归一化操作for (i=0;inw;i+) if (verticaliPmax) fverticali=stdh;else fverticali=(float)(verticali-Pmin)*stdh/ration; edgecount=0; T1=stdh/5; /定义为边界的阈值,太大拒识率高,太低误识率高 strx=5; sign=1; i=5; while (iT1) /如果变化的幅度超过阈值,说明可能是边界 if (i-strx)2) edgeedgecount=i;elseif (i-strx)3) edgeedgecount=strx+1;else int maxvdis=vdisstrx+1; int maxedge=strx+1; for (j=strx+1;jmaxvdis) /找出边界投影值跳跃最大的地方,定义为边界点 /这个理论不总是正确maxvdis=vdisj;maxedge=j; edgeedgecount=maxedge; if (fverticali-fverticalstrx)0) /定义边界点的性质 edgetypeedgecount=btw;elseedgetypeedgecount=wtb; edgecount+; strx=i; i+; sign=signe; / if (fabs(fverticali-fverticalstrx)T1) /最后一个边界点 if (i-strx)2) edgeedgecount=i; else if (i-strx)3) edgeedgecount=strx+1; else int maxvdis=vdisstrx+1; int maxedge=strx+1; for (j=strx+1;jmaxvdis) maxvdis=vdisj; maxedge=j; edgeedgecount=maxedge; if (fverticali-fverticalstrx)0) edgetypeedgecount=btw; else edgetypeedgecount=wtb; edgecount+; / i=0; while (1) if (i=edgecount) break; if (edgetypei=wtb) /起始点一定是从空到条,即从白到黑 break; i+; edgennum=0;for (;iedgecount;i+)edge_positionedgennum=edgei; edgennum+; *edge_num=edgennum; ret=0;ENDPOINT: delete vdis; delete fvertical; delete vertical; delete vertical1; delete edge; delete edgetype; return ret;/* 2 代表为空 1 代表为条 一个数字由两个条两个空组成,总长度为7个单元模块 每个条或者空的宽度最长为4个模块*/#define CELL_LEN 7 /*9 bars with a gap*/* 根据单元模块查找对应的数字*/static intlook_up(char *one_code)typedef struct char symbol;char barcode20; LOOKUP_ENTRY;static LOOKUP_ENTRY lookup_table_ean1330 = 0, 2221121, 0, 2122111, 0, 1112212,1, 2211221, 1, 2112211, 1, 1122112,2, 2212211, 2, 2211211, 2, 1121122,3, 2111121, 3, 2122221, 3, 1222212,4, 2122211, 4, 2211121, 4, 1211122,5, 2112221, 5, 2111221, 5, 1221112,6, 2121111, 6, 2222121, 6, 1212222,7, 2111211, 7, 2212221, 7, 1222122,8, 2112111, 8, 2221221, 8, 1221222,9, 2221211, 9, 2212111, 9, 1112122,;for (int i = 0; i 30; i +)if (strncmp(lookup_table_ean13i.barcode, one_code, CELL_LEN) = 0)return lookup_table_ean13i.symbol;return(-1);/* 确定数字的奇偶性,在这里是指条在单元模块中的比例是奇数还是偶数,比如2221211,因为条的比例是 3,所以是奇数*/static charCheck_OE(char *one_code)int sum=0;char symbol;for (int i=0;iCELL_LEN;i+) sum+=one_codei;if (sum%2=0)symbol=E;else symbol=O;return symbol;/*根据左边六个数字的奇偶性来确定最前面的那个字符*/static intlook_up_ean13_first(char *one_code)typedef struct char symbol;char barcode20; LOOKUP_ENTRY;static LOOKUP_ENTRY lookup_table_EAN13_first12 = 0, OOOOOO, 1, OOEOEE, 2, OOEEOE,3, OOEEEO, 4, OEOOEE, 5, OEEOOE,6, OEEEOO, 7, OEOEOE, 8, OEOEEO,9, OEEOEO;inti;for (i = 0; i 10; i +)if (strncmp(lookup_table_EAN13_firsti.barcode, one_code,6) = 0)return lookup_table_EAN13_firsti.symbol;return -1;/void look_up_closecode_left(int *one_code,int *codew,float T) int i,j; int lookup_close204= 3,2,1,1, 1,1,2,3, 2,2,2,1, 1,2,2,2, 2,1,2,2, 2,2,1,2, 1,4,1,1, 1,1,4,1, 1,1,3,2, 2,3,1,1, 1,2,3,1, 1,3,2,1, 1,1,1,4, 4,1,1,1, 1,3,1,2, 2,1,3,1, 1,2,1,3, 3,1,2,1, 3,1,1,2, 2,1,1,3, ; int mindis=0; int minno20,minnocount=0; int tmpdis=0; for (j=0;j4;j+) mindis+=abs(one_codej-lookup_close0j); for (i = 1; i 20; i +) tmpdis=0; for (j=0;j4;j+) tmpdis+=abs(one_codej-lookup_closeij); if (tmpdismindis) mindis=tmpdis; for (i=0;i20;i+) tmpdis=0; for (j=0;j1) for (j=0;j4;j+) if (lookup_closemin_noj=one_codej) continue; fmindis+=abs(float)lookup_closemin_noj*T-codewj); for (i=1;iminnocount;i+) min_no=minnoi; ftmpdis=0.0; for (j=0;j4;j+) if (lookup_closemin_noj=one_codej) continue; ftmpdis+=abs(lookup_closemin_noj*T-codewj); if (ftmpdisfmindis) fmindis=ftmpdis; fmin_no=min_no; for (j=0;j4;j+) one_codej=lookup_closefmin_noj; void look_up_closecode_right(int *one_code,int *codew,float T) int i,j; int lookup_close104= 3,2,1,1, 2,2,2,1, 2,1,2,2, 1,4,1,1, 1,1,3,2, 1,2,3,1, 1,1,1,4, 1,3,1,2, 1,2,1,3, 3,1,1,2, ; int mindis=0; int minno10,minnocount=0; int tmpdis=0; for (j=0;j4;j+) mindis+=abs(one_codej-lookup_close0j); for (i = 1; i 10; i +) tmpdis=0; for (j=0;j4;j+) tmpdis+=abs(one_codej-lookup_closeij); if (tmpdismindis) mindis=tmpdis; for (i=0;i10;i+) tmpdis=0; for (j=0;j1) for (j=0;j4;j+) if (lookup_closemin_noj=one_codej) continue; fmindis+=abs(float)lookup_closemin_noj*T-codewj); for (i=1;iminnocount;i+) min_no=minnoi; ftmpdis=0.0; for (j=0;j4;j+) if (lookup_closemin_noj=one_codej) continue; ftmpdis+=abs(lookup_closemin_noj*T-codewj); if (ftmpdisfmindis) fmindis=ftmpdis; fmin_no=min_no; for (j=0;j4;j+) one_codej=lookup_closefmin_noj; /*计算一个条或者空在单元符号中的比例*/int bincode(int t,int subt)int ratio = subt*100/t;if (ratio21) return 1; else if (ratio36) return 2; else if (ratio50) return 3; else if (ratio67) return 4; else return -1;/*左边六个符号的译码,得出编码*/int Get_cell_code_left(int *edgeinterval,int str_num,char cell_code) int i,T=0,T1=0,T2; int code4; int codew4; float T3; for (i=0;i4;i+) T+=edgeintervali+str_num; codewi=edgeintervali+str_num; T3=(float)T/7; for (i=0;i4;i+) codei=bincode(T,edgeintervali+str_num); if (codei0) return -1; for (i=0;i4;i+) T1+=codei; if (T1!=7) if (T1=8) look_up_closecode_left(code,codew,T3); else return -1; for (i=0;icode0;i+) cell_codei=2; T1=code0; T2=code0+code1; for (i=T1;iT2;i+) cell_codei=1; T1=T2; T2=T1+code2; for (i=T1;iT2;i+) cell_codei=2; T1=T2; T2=T1+code3; for (i=T1;iT2;i+) cell_codei=1; return 0;/*右边六个符号的译码*/int Get_cell_code_right(int *edgeinterval,int str_num,char cell_code)int i,T=0,T1=0,T2;int code4;int codew4;float T3;for (i=0;i4;i+)T+=edgeintervali+str_num;codewi=edgeintervali+str_num;T3=(float)T/7;for (i=0;i4;i+)codei=bincode(T,edgeintervali+str_num);if (codei0) return -1;for (i=0;i4;i+)T1+=codei;if (T1!=7)if (T1=8)/look_up_close_code(code);look_up_closecode_right(code,codew,T3);elsereturn -1; for (i=0;icode0;i+)cell_codei=1;T1=code0;T2=code0+code1;for (i=T1;iT2;i+)cell_codei=2;T1=T2;T2=T1+code2;for (i=T1;iT2;i+)cell_codei=1;T1=T2;T2=T1+code3;for (i=T1;iT2;i+) cell_codei=2;return 0;/int Decode_ean13(int *edgeinterval,int str_edge,int edge_len,char code)char tc;char cell_code7;char first_code6;int i,j;int ret;i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论