📄 vq.cpp
字号:
// VQ.cpp: implementation of the CVQ class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ShowDib.h"
#include "VQ.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CVQ::CVQ()
{
}
CVQ::~CVQ()
{
}
LPBYTE CVQ::VQAlgorithm(CDib* pSrcImg)
{
CSize sz = pSrcImg->GetDimensions();
int length = pSrcImg->GetDibSaveDim().cx;
int iWidth = sz.cx;
int iHeight = sz.cy;
int i,j,j3,m,n;
long D0,D1;
int iteration;
LPBYTE pDstImgData = (LPBYTE) new char[pSrcImg->m_dwSizeImage];
m_uBlkNum = pSrcImg->m_dwSizeImage/16/3;
SampleVector = new tagCodeWord[m_uBlkNum];
UINT 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++)
{
(*(SampleVector+iBlkIndex)).element[4*m+n] = pSrcImg->GetPixel(i+n,j+m).rgbRed;
}
}
if (iBlkIndex < m_uBlkNum)
{
iBlkIndex++;
}
}
InitialCodeWords();
FindPartitionRegion(m_uBlkNum);
D0 = CalculateDistortion(m_uBlkNum);
for(iteration=0; iteration<10; iteration++)
{
UpdateCodeword(m_uBlkNum);
FindPartitionRegion(m_uBlkNum);
D1 = CalculateDistortion(m_uBlkNum);
if(fabs(((double)D1-D0)/D0) < 0.005)
break;
D0=D1;
}
/*
for (j=0; j<iHeight; j++)
for (i=0; i<iWidth; i++)
{
j3 = length*(iHeight-1-j);//iWidth*(iHeight-1-j)*3;
// int nIndex = pDoc->m_processedDib->GetPixelOffset(i,j);
// pDoc->m_processedDib->m_lpImage[nIndex] = pDoc->m_dib->GetPixel(i,j).rgbRed;
// pDoc->m_processedDib->m_lpImage[nIndex+1] = pDoc->m_dib->GetPixel(i,j).rgbGreen;
// pDoc->m_processedDib->m_lpImage[nIndex+2] = pDoc->m_dib->GetPixel(i,j).rgbBlue;
*(pDstImgData+j3+3*i) = 255-pSrcImg->GetPixel(i,j).rgbGreen;
*(pDstImgData+j3+3*i+1) = 255-pSrcImg->GetPixel(i,j).rgbGreen;
*(pDstImgData+j3+3*i+2) = 255-pSrcImg->GetPixel(i,j).rgbBlue;
}
*/
for(iBlkIndex=0; iBlkIndex<m_uBlkNum; iBlkIndex++)
{
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
(*(SampleVector+iBlkIndex)).element[4*m+n] = CodeWord[(*(SampleVector+iBlkIndex)).label].element[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++)
{
j3 = length*(iHeight-1-j-m);//iWidth*(iHeight-1-j)*3;
*(pDstImgData+j3+3*(i+n)) = (*(SampleVector+iBlkIndex)).element[4*m+n];
// *(pDstImgData+j3+3*(i+n)+1) = (*(SampleVector+iBlkIndex)).element[4*m+n];
// *(pDstImgData+j3+3*(i+n)+2) = (*(SampleVector+iBlkIndex)).element[4*m+n];
}
}
if (iBlkIndex < m_uBlkNum)
{
iBlkIndex++;
}
}
//////////////////////////////////////////////////////////////////////////////////////
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++)
{
(*(SampleVector+iBlkIndex)).element[4*m+n] = pSrcImg->GetPixel(i+n,j+m).rgbGreen;
}
}
if (iBlkIndex < m_uBlkNum)
{
iBlkIndex++;
}
}
InitialCodeWords();
FindPartitionRegion(m_uBlkNum);
D0 = CalculateDistortion(m_uBlkNum);
for(iteration=0; iteration<10; iteration++)
{
UpdateCodeword(m_uBlkNum);
FindPartitionRegion(m_uBlkNum);
D1 = CalculateDistortion(m_uBlkNum);
if(fabs(((double)D1-D0)/D0) < 0.005)
break;
D0=D1;
}
for(iBlkIndex=0; iBlkIndex<m_uBlkNum; iBlkIndex++)
{
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
(*(SampleVector+iBlkIndex)).element[4*m+n] = CodeWord[(*(SampleVector+iBlkIndex)).label].element[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++)
{
j3 = length*(iHeight-1-j-m);
// *(pDstImgData+j3+3*(i+n)) = (*(SampleVector+iBlkIndex)).element[4*m+n];
*(pDstImgData+j3+3*(i+n)+1) = (*(SampleVector+iBlkIndex)).element[4*m+n];
// *(pDstImgData+j3+3*(i+n)+2) = (*(SampleVector+iBlkIndex)).element[4*m+n];
}
}
if (iBlkIndex < m_uBlkNum)
{
iBlkIndex++;
}
}
///////////////////////////////////////////////////////////////////////
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++)
{
(*(SampleVector+iBlkIndex)).element[4*m+n] = pSrcImg->GetPixel(i+n,j+m).rgbBlue;
}
}
if (iBlkIndex < m_uBlkNum)
{
iBlkIndex++;
}
}
InitialCodeWords();
FindPartitionRegion(m_uBlkNum);
D0 = CalculateDistortion(m_uBlkNum);
for(iteration=0; iteration<10; iteration++)
{
UpdateCodeword(m_uBlkNum);
FindPartitionRegion(m_uBlkNum);
D1 = CalculateDistortion(m_uBlkNum);
if(fabs(((double)D1-D0)/D0) < 0.005)
break;
D0=D1;
}
for(iBlkIndex=0; iBlkIndex<m_uBlkNum; iBlkIndex++)
{
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
(*(SampleVector+iBlkIndex)).element[4*m+n] = CodeWord[(*(SampleVector+iBlkIndex)).label].element[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++)
{
j3 = length*(iHeight-1-j-m);//iWidth*(iHeight-1-j)*3;
// *(pDstImgData+j3+3*(i+n)) = (*(SampleVector+iBlkIndex)).element[4*m+n];
// *(pDstImgData+j3+3*(i+n)+1) = (*(SampleVector+iBlkIndex)).element[4*m+n];
*(pDstImgData+j3+3*(i+n)+2) = (*(SampleVector+iBlkIndex)).element[4*m+n];
}
}
if (iBlkIndex < m_uBlkNum)
{
iBlkIndex++;
}
}
/////////////////////////////////////////////////////////////////////////////////////
delete []SampleVector;
return pDstImgData;
}
void CVQ::InitialCodeWords()
{
int i,j;
for(j=0; j<CODEWORD_NUM; j++)
{
CodeWord[j].label = j;
for(i=0; i<16; i++)
{
CodeWord[j].element[i] = 2*j+1;
}
}
}
void CVQ::FindPartitionRegion(UINT blknum)
{
int m,n;
UINT iBlkIndex,iCWIndex;
long int lDiff, lDiffSum=0, lMinSum=100000000;
// tagCodeWord* OneVector = new tagCodeWord;
for(iBlkIndex=0; iBlkIndex < blknum; iBlkIndex++)
{
iCWIndex = 0;
lMinSum=100000000; //////////////////////////////
do
{
lDiffSum = 0; ////////////////////////////////
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
lDiff = abs((*(SampleVector+iBlkIndex)).element[4*m+n] - CodeWord[iCWIndex].element[4*m+n]);
lDiffSum += lDiff*lDiff;
}
}
if (lMinSum > lDiffSum)
{
lMinSum = lDiffSum; //////////////////////////////
(*(SampleVector+iBlkIndex)).label = CodeWord[iCWIndex].label;
// for(m=0; m<16; m++)
// {
// OneVector->element[m] = CodeWord[iCWIndex].element[m];
// }
}
iCWIndex++;
} while(iCWIndex < CODEWORD_NUM);
// (*(SampleVector+iBlkIndex)).label = OneVector->label;
// (*(TempVector+iBlkIndex)).label = OneVector->label;
// for(m=0; m<4; m++)
// {
// for(n=0; n<4; n++)
// {
// (*(TempVector+iBlkIndex)).element[4*m+n] = OneVector->element[4*m+n];
// }
// }
}
// delete OneVector;
}
long CVQ::CalculateDistortion(UINT blknum)
{
long D=0;
int m,n;
UINT iBlkIndex;
long int lDiff, lDiffSum=0;
for(iBlkIndex=0; iBlkIndex < blknum; iBlkIndex++)
{
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
lDiff = abs((*(SampleVector+iBlkIndex)).element[4*m+n] - CodeWord[(*(SampleVector+iBlkIndex)).label].element[4*m+n]);
lDiffSum += lDiff*lDiff;
}
}
}
D = lDiffSum/blknum;
return D;
}
void CVQ::UpdateCodeword(UINT blknum)
{
int m,n;
UINT iBlkIndex;
unsigned char TempLabel;
UINT Count[CODEWORD_NUM]={0};
long Sum[CODEWORD_NUM][16]={0};
for(iBlkIndex=0; iBlkIndex < blknum; iBlkIndex++)
{
TempLabel = (*(SampleVector+iBlkIndex)).label;
Count[TempLabel]++;
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
Sum[TempLabel][4*m+n] += (*(SampleVector+iBlkIndex)).element[4*m+n];
}
}
}
for(TempLabel=0; TempLabel < CODEWORD_NUM; TempLabel++)
{
for(m=0; m<4; m++)
{
for(n=0; n<4; n++)
{
if(Count[TempLabel]!=0)
CodeWord[TempLabel].element[4*m+n] = Sum[TempLabel][4*m+n]/Count[TempLabel];
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -