#include "Bitmap.h"
void CBitmap::Init(char *szInfile,int &nFlag)
{
infile.open(szInfile,ios::in|ios::binary);
if(!infile)
{
cout<<"不能成功打开文件"<<szInfile<<endl;
nFlag=1;
return;
}
infile.read((char *)&strHead,sizeof(strHead));
if(strHead.bfType!=0x4d42)
{
cout<<"该图不是位图\n";
nFlag=1;
return;
}
else
{
int filesize;
int* p = (int*)strHead.bfSize;
filesize=*p;
cout<<"文件大小:"<<'\t'<<filesize<<'\n'
<<"点阵偏移量:"<<'\t'<<strHead.bfOffBits<<endl;
cout<<"\n矩阵大小:"<<filesize-sizeof(RGBQUAD)-sizeof(strHead)-sizeof(strInfo)<<endl;
}
infile.read((char *)&strInfo,sizeof(strInfo));
if(strInfo.biBitCount!=8)
{
cout<<"使用的颜色数:"<<strInfo.biClrUsed<<"像素点阵大小:"<<strInfo.biSizeImage
<<"像素位深:"<<strInfo.biBitCount<<endl;
cout<<"非256色\n";
nFlag=1;
return;
}
cout<<endl;
cout<<"使用的颜色数:"<<'\t'<<strInfo.biClrUsed<<'\n'
<<"像素点阵大小:"<<'\t'<<strInfo.biSizeImage<<'\n'
<<"像素位深:"<<'\t'<<strInfo.biBitCount<<'\n'
<<"图像大小\n宽"<<'\t'<<strInfo.biWidth<<'\n'
<<"高"<<'\t'<<strInfo.biHeight<<endl;
for(int i=0;i<256;i++)
infile.read((char *)&straPla[i],sizeof(RGBQUAD));
// infile.close();
nFlag=0;
return;
}
void CBitmap::LBG()
{
int i;
unsigned char **data;//输入lena
unsigned char **codebk;//码书
int m_sig=strInfo.biHeight;
int n_sig=strInfo.biWidth;//图长 宽
int wordSize = 4;
int bookSize = 64;//码书长度
cout<<"Word Size:\t";
cin>>wordSize;
cout<<"Book Size:\t";
cin>>bookSize;
int hnum = m_sig/wordSize;//
int wnum = n_sig/wordSize;
int ss = wordSize*wordSize;//码字
int nn = hnum*wnum;//子图个数
unsigned char **re_sig;
// unsigned char re_re_sig[512+1][512+1];// 使用data替换
cout<<"\n正在 LBG ... ... \n请稍等... ...\n";
if((data = (unsigned char **) malloc((m_sig+1) * sizeof(unsigned char*)))==NULL)
{
fprintf(stderr,"内存不足!\n");//no more memory
exit(1);
}
for(i=0;i<=m_sig;i++)//训练向量数目
if((data[i] = (unsigned char *) malloc((n_sig+1) * sizeof(unsigned char)))==NULL)// 维数
{
fprintf(stderr,"内存不足!\n");
exit(1);
}
if((codebk = (unsigned char **) malloc((bookSize+1) * sizeof(unsigned char*)))==NULL)
{
fprintf(stderr,"内存不足!\n");//no more memory
exit(1);
}
for(i=0;i<=bookSize;i++)//训练向量数目
if((codebk[i] = (unsigned char *) malloc((ss+1) * sizeof(unsigned char)))==NULL)// 维数
{
fprintf(stderr,"内存不足!\n");
exit(1);
}
if((re_sig = (unsigned char **) malloc((nn+1) * sizeof(unsigned char*)))==NULL)
{
fprintf(stderr,"内存不足!\n");//no more memory
exit(1);
}
for(i=0;i<=nn;i++)//训练向量数目
if((re_sig[i] = (unsigned char *) malloc((ss+1) * sizeof(unsigned char)))==NULL)// 维数
{
fprintf(stderr,"内存不足!\n");
exit(1);
}
infile.seekg(strHead.bfOffBits,ios::beg);//读入
for(i=1;i<=m_sig;i++)
infile.read((char *)&data[i][1],n_sig*sizeof(char));
infile.close();
for(i=1;i<=m_sig;i++)//切割图片
for(int j=1;j<=n_sig;j++)
{
int f1=floor(i/wordSize);
int m1=i%wordSize;
if(m1==0)//
{
m1=wordSize;
f1--;
}
int f2=floor(j/wordSize);
int m2=j%wordSize;
if(m2==0)
{
m2=wordSize;
f2--;
}
re_sig[hnum*f1+f2+1][wordSize*(m1-1)+m2]=data[i][j];
}
//////显示随机找出的码书
cout<<"在所有的数据中随机的找出的码书:"<<endl;
for(i=1;i<=bookSize;i++){
for(int j=1;j<=ss;j++)
{
int r=get_rand(nn);
codebk[i][j]=re_sig[r][j];
cout<<(float)codebk[i][j]<<" ";
}
cout<<endl;
}
/**
*LBG训练法
*d0 d1 用于存放各训练矢量与其码书中最相近的码字的距离平方之和
*sea 用于存放迭代精度
**/
double d0=0.0;//每个输入向量与codebk[1]的距离
for(i=1;i<=nn;i++)
for(int ti=1;ti<=ss;ti++)
d0=d0+pow((int)re_sig[i][ti]-(int)codebk[1][ti],2);
while(1)
{
// int vectorNumber[64+1];
int *vectorNumber;
if((vectorNumber = (int *) malloc((bookSize+1) * sizeof(int)))==NULL)
{
fprintf(stderr,"内存不足!\n");
exit(1);
}
// int codeNumber[512*512/16+1];
int *codeNumber;
if((codeNumber = (int *) malloc((nn+1) * sizeof(int)))==NULL)
{
fprintf(stderr,"内存不足!\n");
exit(1);
}
double d1 = 0.0;
for(i=1;i<=bookSize;i++)
vectorNumber[i]=0;//初始化为零
for(i=1;i<=nn;i++)//对于所有的输入向量
{
codeNumber[i]=1;
double min =0.0;
for(int ti=1;ti<=ss;ti++)
min=min+pow((int)re_sig[i][ti]-(int)codebk[1][ti],2);
// if(min<0)
// system("pause");
for(int j=1;j<=bookSize;j++)//求最小的值
{
double d=0.0;
for(int pp=1;pp<=ss;pp++)
{
d = d+pow((int)re_sig[i][pp]-(int)codebk[j][pp],2);
if (d>=min)
break;
}
if(d<min)
{ min=d;
codeNumber[i]=j;
}
}//与 i距离最小的索引
int temp=codeNumber[i];
vectorNumber[temp]=vectorNumber[temp]+1;
d1+=min;
}
double sea=(d0-d1)/d1;
if(sea<=0.0001)
break;
d0=d1;
for(int j=1;j<=bookSize;j++)
{
if(vectorNumber[j]!=0)
{
// int dd[16+1];//dd[ss]
int *dd;
if((dd = (int *) malloc((ss+1) * sizeof(int)))==NULL)
{
fprintf(stderr,"内存不足!\n");
exit(1);
}
for(int l=1;l<=nn;l++)
{ if(codeNumber[l]==j)
{ for(int k=1;k<=ss;k++)
dd[k]=dd[k]+re_sig[l][k];
}
}
for(int k=1;k<=ss;k++)
codebk[j][k]=dd[k]/vectorNumber[j];
}
else
{ int l=floor(get_rand(nn));
for(int tt=1;tt<=ss;tt++)
codebk[j][tt]=re_sig[l][tt];
}
}
free(vectorNumber);
vectorNumber=NULL;
free(codeNumber);
codeNumber=NULL;
}
//////显示最优码书
cout<<"设计的码书是:"<<endl;
for(i=1;i<=bookSize;i++){
for(int j=1;j<=ss;j++)
{
cout<<(float)codebk[i][j]<<" ";
}
cout<<endl;
}
/////////////////// save codebk
ofstream codeBookfile("LBGcodeBook.png",ios::out|ios::binary);
if(!codeBookfile)
{
cout<<"处理失败!\n";
return;
}
for(i=1;i<=bookSize;i++)//save codebk
codeBookfile.write((char *)&codebk[i][1],ss);
codeBookfile.close();
/////////////////// save codebk
double d1=0.0;
// char codeNumber[512*512/16+1];//int
unsigned char * codeNumber;//int
if((codeNumber = (unsigned char *) malloc((nn+1) * sizeof(unsigned char)))==NULL)// 维数
{
fprintf(stderr,"内存不足!\n");
exit(1);
}
for(i=1;i<=nn;i++)
{
codeNumber[i]=1;
double min=0.0;
for(int ti=1;ti<=ss;ti++)
min=min+pow((int)re_sig[i][ti]-(int)codebk[1][ti],2);
for(int j=2;j<=bookSize;j++)
{
double d=0.0;
for(int l=1;l<=ss;l++)
{
d =d+pow((int)re_sig[i][l]-(int)codebk[j][l],2);
if (d>=min)
break;
}
if(d<min)
{
min=d;
codeNumber[i]=j;
}
}
d1=d1+min;
}
/////////////////////////////////////////////////
ofstream codeNOFile("LBGcodeNumber.jpg",ios::out|ios::binary);
if(!codeNOFile)
{
cout<<"处理失败!\n";
return;
}
for(i=1;i<nn+1;i++)//save codeNumber
codeNOFile.write((char *)&codeNumber[i],sizeof(char));//int
codeNOFile.close();
/////////////////////////////////////////////////
//重建图像
for(i=1;i<=nn;i++)
for(int j=1;j<=ss;j++)
{
int temp=codeNumber[i];
re_sig[i][j]=codebk[temp][j];
}
for(i=0;i<=bookSize;i++)//训练向量数目
free(codebk[i]);// 维数
free(codebk);
codebk=NULL;
free(codeNumber);
codeNumber=NULL;
ofstream outfile("LBG.bmp",ios::out|ios::binary);
if(!outfile)
{
cout<<"处理失败!\n";
return;
}
outfile.write((char *)&strHead,sizeof(strHead));//将位图文件头和调色板复制到新建文件
outfile.write((char *)&strInfo,sizeof(strInfo));
for(i=0;i<256;i++)
outfile.write((char *)&straPla[i],sizeof(RGBQUAD))
LBG.rar_LBG_carib-080911-773_lgb
版权申诉
63 浏览量
2022-09-21
09:00:29
上传
评论
收藏 284KB RAR 举报
周楷雯
- 粉丝: 78
- 资源: 1万+
最新资源
- DrawDB 是一个健壮且用户友好的数据库实体关系 (DBER) 编辑器,直接位于您的浏览器中
- PHP库通过返回原始SQL来实现ActiveRecord 用于PHP5.3和NO PDO场景的yii2 ORM移植
- 5152单片机proteus仿真和源码用数组作函数参数控制流水花样
- 2024年全域电商矩阵109节线上课-课程网盘链接提取码下载 .txt
- 对 sqlite 的使用进行简单封装,仅涉及简单的单表 增删改查,基于 FMDB, 操作基于 model
- 5152单片机proteus仿真和源码用函数型指针控制P1口灯花样
- 对Hibernate框架的二次封装,简化对数据库的操作
- 5152单片机proteus仿真和源码用定时器T1查询方式控制单片机发出1KHz音频
- 由 Top10 开发和使用的惯用 Scala Redis 客户端 这是一项正在进行的工作,虽然在生产中使用,但应将其视为在生产中
- SwiftUI - SceanAppDelegate
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0