EAN条形码译码器代码.docx

上传人:b****1 文档编号:23167610 上传时间:2023-05-15 格式:DOCX 页数:37 大小:21.35KB
下载 相关 举报
EAN条形码译码器代码.docx_第1页
第1页 / 共37页
EAN条形码译码器代码.docx_第2页
第2页 / 共37页
EAN条形码译码器代码.docx_第3页
第3页 / 共37页
EAN条形码译码器代码.docx_第4页
第4页 / 共37页
EAN条形码译码器代码.docx_第5页
第5页 / 共37页
点击查看更多>>
下载资源
资源描述

EAN条形码译码器代码.docx

《EAN条形码译码器代码.docx》由会员分享,可在线阅读,更多相关《EAN条形码译码器代码.docx(37页珍藏版)》请在冰豆网上搜索。

EAN条形码译码器代码.docx

EAN条形码译码器代码

#include

#include

#include

#include

#include

#defineBI_RGB0L

#defineBI_RLE81L

#defineBI_RLE42L

#defineBI_BITFIELDS3L

typedefstruct{

unsignedcharrgbBlue;

unsignedcharrgbGreen;

unsignedcharrgbRed;

unsignedcharrgbReserved;

}RGBQUAD;

typedefstruct{

unsignedlongbiSize;

longbiWidth;

longbiHeight;

unsignedshortbiPlanes;

unsignedshortbiBitCount;

unsignedlongbiCompression;

unsignedlongbiSizeImage;

longbiXPelsPerMeter;

longbiYPelsPerMeter;

unsignedlongbiClrUsed;

unsignedlongbiClrImportant;

}BITMAPINFOHEADER;

typedefstruct{

BITMAPINFOHEADERbmiHeader;

RGBQUADbmiColors[1];

}BITMAPINFO;

#include/////

typedefstruct{

unsignedshortbfType;

unsignedlongbfSize;

unsignedshortbfReserved1;

unsignedshortbfReserved2;

unsignedlongbfOffBits;

}BITMAPFILEHEADER;

#include

/*

参考BMP文件格式

*/

intReadBMPToBuf(char*FileName,unsignedchar**RawImageData,int*ImageWidth,int*ImageHeight)

{

BITMAPFILEHEADERbmfileh;//BMP文件头变量

BITMAPINFOHEADERbminfoh;//位图信息头

FILE*fp;

intTotalPixelNumber;

fp=fopen(FileName,"rb");//读写打开一个二进制文件,允许读数据

if(fp==NULL)

{

return-1;

}

ints1=sizeof(bmfileh);//求文件头字节数,

ints2=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。

//bfOffBitsSpecifiestheoffset,inbytes,fromtheBITMAPFILEHEADERstructureto

thebitmapbits.

*RawImageData=(unsignedchar*)calloc((TotalPixelNumber),sizeof(unsignedchar));//在内存

的动态存储区中分配连续空间。

fread(*RawImageData,1,TotalPixelNumber,fp);

fclose(fp);

///////////////////////////////////////////////////////////////////////////////////////////////////

//

///////////////////////////////////////////////////////////////////////////////////////////////////

//

if(bminfoh.biHeight>0)

//SpecifiestheImageHeightofthebitmap,inpixels.IfbiHeightispositive,the

bitmapisabottom-upDIBanditsoriginisthelower-leftcorner.IfbiHeightisnegative,the

bitmapisatop-downDIBanditsoriginistheupper-leftcorner.

//IfbiHeightisnegative,indicatingatop-downDIB,biCompressionmustbeeither

BI_RGBorBI_BITFIELDS.Top-downDIBscannotbecompressed.

{

unsignedchar*RowBuffer=NULL;

RowBuffer=(unsignedchar*)calloc((*ImageWidth),sizeof(unsignedchar));

inti,j;

j=*ImageHeight/2;

unsignedchar*ptr1,*ptr2;

ptr1=*RawImageData;//第一行,

ptr2=*RawImageData+(*ImageHeight-1)*(*ImageWidth);//最后一行,

for(i=0;i

{

memcpy(RowBuffer,ptr1,*ImageWidth);

memcpy(ptr1,ptr2,*ImageWidth);

memcpy(ptr2,RowBuffer,*ImageWidth);

ptr1+=*ImageWidth;

ptr2-=*ImageWidth;

}

free(RowBuffer);

RowBuffer=NULL;

}

return0;

}

/*

*cell输入图像数据

nw输入图像宽度

nh输入图像高度

*edge_position输出边界坐标

*edge_num输出边界坐标个数

*/

intGet_Bar_edge(unsignedchar*cellbuf,intnw,intnh,int*edge_position,int*edge_num)

{

inti,j;

int*vertical=newint[nw];//垂直投影值

float*fvertical=newfloat[nw];//归一化后的投影值

intPmax,Pmin,T1,ration;

enumEdgeType{wtb,btw};//定义边界的性质是聪白到黑,还是聪黑到白

EdgeType*edgetype=newEdgeType[nw];

intedgecount=0;//边界的个数

//投影

for(i=0;i

{

vertical[i]=0;

for(j=0;j

{

vertical[i]+=cellbuf[j*nw+i];

}

}

//归一化处理

Pmax=Pmin=vertical[0];

for(i=0;i

{

if(vertical[i]

if(vertical[i]>Pmax)Pmax=vertical[i];

}

ration=Pmax-Pmin;

for(i=0;i

fvertical[i]=(float)(vertical[i]-Pmin)*nh/ration;

//开始寻找边界,定义边界跳变的阈值

T1=nh/3;

//第一个边界一定是从白到黑的

for(i=5;i

if(fvertical[i-1]-fvertical[i+1]>T1)

{

edge_position[edgecount]=i;

edgetype[edgecount]=wtb;

edgecount++;

break;

}

while(i

{

if(fabs(fvertical[i-1]-fvertical[i+1])>T1)

{

if(fvertical[i-1]>fvertical[i+1]&&edgetype[edgecount-1]==btw)

{

edge_position[edgecount]=i;

edgetype[edgecount]=wtb;

edgecount++;

}

if((fvertical[i-1]

{

edge_position[edgecount]=i;

edgetype[edgecount]=btw;

edgecount++;

}

}

i++;

}

*edge_num=edgecount;

////////释放内存

delete[]vertical;

delete[]fvertical;

delete[]edgetype;

return0;

}

//////////////////////////////////////////////////////////////////////

intsgn(floatx)

{

if(x>0)return

(1);

if(x<0)return(-1);

return(0);

}

intGet_Bar_edge_a(unsignedchar*cellbuf,intnw,intnh,int*edge_position,int*edge_num)

{

inti,j,stdh=255,strx,endx,sign,ret;

intPmax,Pmin,T1,ration,edgennum;

enumEdgeType{wtb,btw};

EdgeType*edgetype=newEdgeType[nw];

intedgecount=0;

int*edge=newint[nw];

int*vertical=newint[nw];

int*vertical1=newint[nw];

float*fvertical=newfloat[nw];//归一化后的投影值

int*vdis=newint[nw];

//投影

for(i=0;i

{

vertical[i]=0;

for(j=0;j

{

vertical[i]+=cellbuf[j*nw+i];

}

}

memcpy(vertical1,vertical,nw*sizeof(int));

//对投影排序

for(i=0;i

{

for(j=i+1;j

{

if(vertical1[j]

{

inttmpv=vertical1[j];

vertical1[j]=vertical1[i];

vertical1[i]=tmpv;

}

}

}

intnmeant=nw/20;

//取最小的%5的均值为下限

Pmin=0;

for(i=0;i

{

Pmin+=vertical1[i];

}

Pmin=Pmin/nmeant;

//取最大的%5的均值为上限

Pmax=0;

for(i=nw-nmeant;i

{

Pmax+=vertical1[i];

}

Pmax=Pmax/nmeant;

//Pmax=Pmin=vertical[0];

//

//for(i=0;i

//{

//

//if(vertical[i]

//if(vertical[i]>Pmax)Pmax=vertical[i];

//}

ration=Pmax-Pmin;

if(ration==0)

{

ret=-1;

gotoENDPOINT;

}

//归一化操作

for(i=0;i

{

if(vertical[i]

{

fvertical[i]=0;

}

else

if(vertical[i]>Pmax)

{

fvertical[i]=stdh;

}

else

fvertical[i]=(float)(vertical[i]-Pmin)*stdh/ration;

}

edgecount=0;

T1=stdh/5;//定义为边界的阈值,太大拒识率高,太低误识率高

strx=5;

sign=1;

i=5;

while(i<(nw-5))

{

vdis[i]=abs(fvertical[i+1]-fvertical[i-1]);

intsigne=sgn(fvertical[i+1]-fvertical[i]);

if(signe==sign||signe==0)//如果没有变化,说明是连续的增加或下降

{

i++;

continue;

}

//如果signe发生变化,说明出现了极值点(局部最大值为最小值)

if(fabs(fvertical[i]-fvertical[strx])>T1)//如果变化的幅度超过阈值,说明可能是边界

{

if((i-strx)<2)

edge[edgecount]=i;

else

if((i-strx)<3)

edge[edgecount]=strx+1;

else

{

intmaxvdis=vdis[strx+1];

intmaxedge=strx+1;

for(j=strx+1;j

{

if(vdis[j]>maxvdis)//找出边界投影值跳跃最大的地方,定义为

边界点

{//这个理论不总是正确

maxvdis=vdis[j];

maxedge=j;

}

}

edge[edgecount]=maxedge;

}

if((fvertical[i]-fvertical[strx])>0)//定义边界点的性质

edgetype[edgecount]=btw;

else

edgetype[edgecount]=wtb;

edgecount++;

}

strx=i;

i++;

sign=signe;

}

///////////////////////////////////////////

if(fabs(fvertical[i]-fvertical[strx])>T1)//最后一个边界点

{

if((i-strx)<2)

edge[edgecount]=i;

else

if((i-strx)<3)

edge[edgecount]=strx+1;

else

{

intmaxvdis=vdis[strx+1];

intmaxedge=strx+1;

for(j=strx+1;j

{

if(vdis[j]>maxvdis)

{

maxvdis=vdis[j];

maxedge=j;

}

}

edge[edgecount]=maxedge;

}

if((fvertical[i]-fvertical[strx])>0)

edgetype[edgecount]=btw;

else

edgetype[edgecount]=wtb;

edgecount++;

}

///////////////////////////////////////////////////

i=0;

while

(1)

{

if(i>=edgecount)break;

if(edgetype[i]==wtb)//起始点一定是从空到条,即从白到黑

break;

i++;

}

edgennum=0;

for(;i

{

edge_position[edgennum]=edge[i];

edgennum++;

}

*edge_num=edgennum;

ret=0;

ENDPOINT:

delete[]vdis;

delete[]fvertical;

delete[]vertical;

delete[]vertical1;

delete[]edge;

delete[]edgetype;

returnret;

}

/*

2代表为空

1代表为条

一个数字由两个条两个空组成,总长度为7个单元模块

每个条或者空的宽度最长为4个模块

*/

#defineCELL_LEN7/*9barswithagap*/

/*

根据单元模块查找对应的数字

*/

staticintlook_up(char*one_code)

{

typedefstruct{

charsymbol;

charbarcode[20];

}LOOKUP_ENTRY;

staticLOOKUP_ENTRYlookup_table_ean13[30]={

{'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(inti=0;i<30;i++)

if(strncmp(lookup_table_ean13[i].barcode,one_code,CELL_LEN)==0)

returnlookup_table_ean13[i].symbol;

return(-1);

}

////////////////////////////////////////////////////////////////

/*

确定数字的奇偶性,在这里是指条在单元模块中的比例是奇数还是偶数,比如2221211,因为条的比例是

3,所以是奇数

*/

staticcharCheck_OE(char*one_code)

{

intsum=0;

charsymbol;

for(inti=0;i

{

sum+=one_code[i];

}

if(sum%2==0)

symbol='E';

else

symbol='O';

returnsymbol;

}

///////////////////////////////////////////////////////////////

/*

根据左边六个数字的奇偶性来确定最前面的那个字符

*/

staticintlook_up_ean13_first(char*one_code)

{

typedefstruct{

charsymbol;

charbarcode[20];

}LOOKUP_ENTRY;

static

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 历史学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1