📄 vqgray.cpp
字号:
// VQgray.cpp: implementation of the VQgray class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ShowDib.h"
#include "VQgray.h"
#include "stdio.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
const int M=128;
const int nDimension = 16;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
VQgray::VQgray()
{
}
VQgray::~VQgray()
{
}
int VQgray::LBGCluster(VQ_VECTOR *X, int N, VQ_CENTER *Y, int M)
{
if(N<M) return 0;
int m, i, j;
double D0, D1;
for( i=0; i<M; i++)
{
Y[i].nDimension = nDimension;
for( j=0; j<nDimension; j++ )
{
Y[i].Data[j] =X[i*N/M].Data[j];//2*i+1; //X[i*N/M].Data[j];
Y[i].SumData[j] = 0;
}
Y[i].Num = 0;
}
PartBelong();
D0=GetDistortion();
for(m=0;m<10;m++)
{
GetCenterCode();
PartBelong();
D1=GetDistortion();
if(fabs(((double)D1-D0)/D0) < 0.005)
break;
D0=D1;
}
return 1;
}
void VQgray::PartBelong()
{
int i,j,k,nCenter;
double Dist;
double *Distance=new double[N];
for(i=0; i<M; i++) // 每次都给sumdata赋初值
{
for( j=0; j<nDimension; j++ )
Y[i].SumData[j] = 0;
Y[i].Num = 0;
}
for(i=0; i<N; i++)
{
Distance[i] = 100000000;
for(int j=0; j<M; j++)
{
Dist = 0;
for( k=0; k<nDimension; k++ )
Dist += (X[i].Data[k]-Y[j].Data[k])*(X[i].Data[k]-Y[j].Data[k]);
if( Dist < Distance[i])
{
nCenter = j;
Distance[i] = Dist;
}
}
X[i].nCluster = nCenter;
for( k=0; k<nDimension; k++ )
Y[nCenter].SumData[k] += X[i].Data[k];
Y[nCenter].Num++;
}
delete []Distance;
}
double VQgray::GetDistortion()
{
int i,k;
double D=0;
for(i=0;i<N;i++)
{
for(k=0;k<M;k++)
D+=(X[i].Data[k]-Y[X[i].nCluster].Data[k])*(X[i].Data[k]-Y[X[i].nCluster].Data[k]);
}
D/=N;
return D;
}
void VQgray::GetCenterCode()
{
int i,k;
for(i=0;i<M;i++)
{
for(k=0;k<16;k++)
{
if(Y[i].Num!=0)
Y[i].Data[k]=Y[i].SumData[k]/Y[i].Num;
}
}
}
LPBYTE VQgray::VQgrayAlgorithm(CDib* pSrcImg)
{
CSize sz = pSrcImg->GetDimensions();
int iWidth = sz.cx;
int iHeight = sz.cy;
//计算每行的字节数
long LineBytes;
LineBytes=WIDTHBYTES(iWidth*8);
int i,j,m,n;
LPBYTE pDstImgData = (LPBYTE) new char[pSrcImg->m_dwSizeImage];
N = pSrcImg->m_dwSizeImage/16;
X = new VQ_VECTOR[N];
M= 128;
Y= new VQ_CENTER[M];
int iBlkIndex=0;
for(j=0; j<iHeight; j=j+4)
for(i=0; i<iWidth; i=i+4)
{
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
unsigned char* lpsrc;
lpsrc=(unsigned char*)pSrcImg->m_lpImage+LineBytes*(iHeight-j-m-1)+(i+n);
(*(X+iBlkIndex)).Data[4*m+n] =*lpsrc;
//(unsigned char*)pSrcImg->m_lpImage+LineBytes*(iHeight-j-m-1)+(i+n);
}
}
if (iBlkIndex<N)
{
iBlkIndex++;
}
}
if(LBGCluster(X, N, Y, M))
{
for(iBlkIndex=0; iBlkIndex<N; iBlkIndex++)
{
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
(*(X+iBlkIndex)).Data[4*m+n] = Y[(*(X+iBlkIndex)).nCluster].Data[4*m+n];
}
}
}
iBlkIndex=0;
for(j=0; j<iHeight; j=j+4)
for(i=0; i<iWidth; i=i+4)
{
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
*(pDstImgData+LineBytes*(iHeight-j-m-1)+(i+n)) = (*(X+iBlkIndex)).Data[4*m+n];
}
}
if (iBlkIndex < N)
{
iBlkIndex++;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////
delete []X;
delete []Y;
return pDstImgData;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -