// barcode.cpp : 定义控制台应用程序的入口点。
//
// tiaomadingwei.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"cv.h"
#include"highgui.h"
#include"iostream"
#include"math.h"
using namespace std;
//计算子区域图像对比度
int Contrast(IplImage* pImg,int Threshold)
{
int contrast=0;
int HistogramBlock = 256;
float HistogramRange1[2]={0,255};
float *HistogramRange[1]={&HistogramRange1[0]};
CvHistogram *Histogram1;
Histogram1 = cvCreateHist(1,&HistogramBlock,CV_HIST_ARRAY,HistogramRange);
cvCalcHist(&pImg,Histogram1);
double L[256];
memset(L,0,256*sizeof(double));
for(int i=0;i<256;i++)
{
L[i]=cvGetReal1D(Histogram1->bins,i)/(pImg->width*pImg->height);
}
double dark=0;
double light=0;
for(int a=1;a<256;a++)
{
for( int b=0;b<a;b++)
{
dark=dark+L[b];
}
for( int c=a;c<256;c++)
{
light=light+L[c];
}
if (abs(dark-light)<=0.7&&dark!=0&&light!=0)
{
double dark_quan=0;
double light_quan=0;
int Threshold=a;
for (int b=0;b<Threshold;b++)
{
dark_quan+=b*L[b];
}
for (int c=Threshold;c<256;c++)
{
light_quan+=c*L[c];
}
double g_dark=dark_quan/dark;
double g_light=light_quan/light;
contrast=int(g_light-g_dark);
break;
}
else
{
dark=0;
light=0;
}
}
if (contrast>Threshold)
return 255;
else
return 0;
}
//将图像区域分块
IplImage* Mat2Cell(IplImage* pImg,int BlockSize,int indexH,int indexW)
{
IplImage* pSubImg;
pSubImg=cvCreateImage(cvSize(BlockSize,BlockSize),IPL_DEPTH_8U,1);
for(int m=0;m<BlockSize;m++)
{
for(int n=0;n<BlockSize;n++)
{
pSubImg->imageData[m*BlockSize+n]=pImg->imageData[(indexH*BlockSize+m)*pImg->width+(indexW*BlockSize+n)];
}
}
return pSubImg;
}
//根据标记做图像处理
int Show_Barcode(IplImage* pImg,int BlockSize,WORD *matrix,int Max_Label,IplImage *ShowImg)
{
for(int aa=0;aa<pImg->width*pImg->height;aa++)
{
ShowImg->imageData[aa]=0;
}
int NN=pImg->width/BlockSize; //宽度分块
int MM=pImg->height/BlockSize; //高度分块
for(int i=0;i<MM;i++)
{
for(int j=0;j<NN;j++)
{
if(matrix[i*NN+j]==Max_Label)
{
for(int m=0;m<BlockSize;m++)
{
for(int n=0;n<BlockSize;n++)
{
ShowImg->imageData[(i*BlockSize+m)*pImg->width+(j*BlockSize+n)]=pImg->imageData[(i*BlockSize+m)*pImg->width+(j*BlockSize+n)];
}
}
}
}
}
return 1;
}
IplImage * Imgae_Contrast(IplImage* pImg,int BlockSize,int contrast_threshold)
{
IplImage *Isbarcode;
int NN=pImg->width/BlockSize; //宽度分块
int MM=pImg->height/BlockSize; //高度分块
Isbarcode=cvCreateImage(cvSize(MM,NN),IPL_DEPTH_8U,1);
IplImage *pSubImg;
for(int i=0;i<MM;i++)
{
for(int j=0;j<NN;j++)
{
pSubImg=Mat2Cell(pImg,BlockSize,i,j);
Isbarcode->imageData[i*NN+j]=Contrast(pSubImg,contrast_threshold);
}
}
cvReleaseImage(&pSubImg);
return Isbarcode;
}
//输入:mask为标记模板指针,img1为待标记二值图像指针
//返回值为连通区域数
int label( WORD *mask,IplImage *img1)
{
BYTE *pb1=(BYTE*)img1->imageData;
int height=img1->height;
int width=img1->width;
int k,j;
for( k=0; k<width*height; k++)
mask[k]=0;
int cw=100;//初始区域数目
loop:
bool *col=new bool[cw*cw];
for(k=0; k<cw*cw; k++)
col[k]=false;
//第一次扫描
int lab=1;
for(k=1;k<height;k++)
for( j=1;j<width-1;j++)
if(pb1[k*width+j]==255)
if((mask[k*width+j-1]+mask[(k-1)*width+j-1]+mask[(k-1)*width+j]+mask[(k-1)*width+j+1])==0)
{
mask[k*width+j]=lab;
lab=lab+1;
if(lab>cw)
{
delete col;
cw+=200;
goto loop;
}
}
else
{
if(mask[k*width+j-1]!=0)
mask[k*width+j]=mask[k*width+j-1];
if(mask[(k-1)*width+j-1]!=0)
if(mask[k*width+j]==0)
mask[k*width+j]=mask[(k-1)*width+j-1];
else
{
col[mask[k*width+j]*cw+mask[(k-1)*width+j-1]]=true;
col[mask[(k-1)*width+j-1]*cw+mask[k*width+j]]=true;
}
if(mask[(k-1)*width+j]!=0)
if(mask[k*width+j]==0)
mask[k*width+j]=mask[(k-1)*width+j];
else
{
col[mask[k*width+j]*cw+mask[(k-1)*width+j]]=true;
col[mask[(k-1)*width+j]*cw+mask[k*width+j]]=true;
}
if(mask[(k-1)*width+j+1]!=0)
if(mask[k*width+j]==0)
mask[k*width+j]=mask[(k-1)*width+j+1];
else
{
col[mask[k*width+j]*cw+mask[(k-1)*width+j+1]]=true;
col[mask[(k-1)*width+j+1]*cw+mask[k*width+j]]=true;
}
}
if(lab==1)
return 0;
//等价关系合并
bool *col2=new bool[lab*lab];
for(k=0; k<lab*lab; k++)
col2[k]=false;
for(k=1;k<lab;k++)
for(j=1;j<lab;j++)
if(col[k*cw+j]==true||k==j)
col2[k*lab+j]=true;
delete[] col;
for(k=1;k<lab;k++)
for(j=1;j<lab;j++)
if(col2[j*lab+k]==true)
for(int i=1;i<lab;i++)
col2[j*lab+i]=col2[j*lab+i]||col2[k*lab+i];
WORD *col3=new WORD[lab];
WORD *col3_s=new WORD[lab];
for(k=1;k<lab;k++)
{
int c1, c2;
for(j=1;j<lab;j++)
if(col2[k*lab+j]==true)
{
c1=j;
break;
}
for(j=1;j<lab;j++)
if(col2[j*lab+k]==true)
{
c2=j;
break;
}
col3[k]=min(c1,c2);
col3_s[k]=col3[k];
}
for(k=1;k<lab-1;k++)
{
WORD t;
for(j=1;j<lab-k;j++)
if(col3_s[j]>col3_s[j+1])
{
t=col3_s[j];
col3_s[j]=col3_s[j+1];
col3_s[j+1]=t;
}
}
WORD *ind=new WORD[lab];
ind[col3_s[1]]=1;
int c=2;
for(k=1;k<lab-1;k++)
if(col3_s[k+1]!=col3_s[k])
{
ind[col3_s[k+1]]=c;
c++;
}
//第2次扫描
for(k=1;k<height;k++)
for( j=1;j<width-1;j++)
if(mask[k*width+j]!=0)
mask[k*width+j]=ind[col3[mask[k*width+j]]];
delete[] col2;
delete[] col3;
delete[] col3_s;
delete[] ind;
return(c-1);//返回区域数目
}
//矩阵数据直方图统计,得到最大的标记区域
int MatrixHist(WORD *matrix,int length,int Num)
{
int *count,Label_Num;
count=new int[Num];
memset(count,0,Num*sizeof(int));
for(int m=0;m<Num;m++)
{
for(int i=0;i<length;i++)
{
if(matrix[i]==m)
{
count[m]++;
}
}
}
Label_Num=0;
for(int n=0;n<Num;n++)
{
for(int m=n+1;m<Num;m++)
{
if(count[n]<count[m])
{
Label_Num=m;
}
}
}
delete [] count;
return Label_Num;
}
//得到条码区域
IplImage * Get_destimg(IplImage *barcodeimg,IplImage* originimg)
{
IplImage *destimg;
CvRect rect;
rect.x=0;
rect.y=0;
rect.width=barcodeimg->width;
rect.height=barcodeimg->height;
int *Sum_col,*Sum_row;
Sum_col=new int[barcodeimg->width];
Sum_row=new int[barcodeimg->height];
for(int i=0;i<barcodeimg->width;i++)
{
for(int j=0;j<barcodeimg->height;j++)
{
Sum_col[i]+=barcodeimg->imageData[j*barcodeimg->width+i];
}
}
for(int i=0;i<barcodeimg->height;i++)
{
for(int j=0;j<barcodeimg->width;j++)
{
Sum_row[i]+=barcodeimg->imageData[i*barcodeimg->width+j];
}
}
for(int i=2;i<barcodeimg->width;i++)
{
if(Sum_col[i-1]==0&&Sum_col[i]!=0)
{
rect.x=i;
break;
}
}
for(int i=barcodeimg->width;i<2;i++)
{
if(Sum_col[i]==0&&Sum_col[i-1]!=0)
{
rect.width=i-rect.x;
break;
}
}
for(int i=2;i<barcodeimg->height;i++)
{
if(Sum_row[i-1]==0&&Sum_row[i]!=0)
{
rect.y=i;
break;
}
}
for(int i=barcodeimg->height;i<2;i++)
{
if(Sum_row[i]==0&&Sum_row[i-1]!=0)
{
rect.height=i-rect.y;
break;
}
}
CvRect rect1;
rect1.x=rect.x+rect.width/2-50;
rect1.y=rect.y+rect.height/2-50;
rect1.width=100;
rect1.height=100;
destimg=cvCreateImage(cvSize(rect1.width,rect1.height),IPL_DEPTH_8U,1);
for(int i=0;i<destimg->heig
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
1.版本:matlab2022A,包含仿真操作录像,中文word报告,操作录像使用windows media player播放。 2.领域:条形码矫正 3.内容:通过Otsu算法实现条形码的角度矫正带GUI界面和实验报告,原理介绍,测试分析,matlab2022A仿真 4.注意事项:注意MATLAB左侧当前文件夹路径,必须是程序所在文件夹位置,具体可以参考视频录。
资源推荐
资源详情
资源评论
收起资源包目录
基于Otsu算法的条形码的角度矫正算法matlab仿真,带GUI界面.rar (14个子文件)
仿真操作录像0019.avi 28.41MB
1.jpg 40KB
实验报告.rar 287KB
code
tiaomajiaozheng.fig 6KB
matrix_hist.m 712B
barcode.cpp 13KB
rotate.m 1KB
Correction.m 2KB
1.jpg 22KB
Contrast.m 1KB
Get_destimg.m 541B
houghtheta.m 1KB
tiaomajiaozheng.m 4KB
Otsu.m 2KB
共 14 条
- 1
资源评论
fpga和matlab
- 粉丝: 16w+
- 资源: 2557
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功