📄 transeform.cpp
字号:
#include "stdafx.h"
#include "transeform.h"
#include <math.h>
#include "WaveletApi.h"
#include "FilterApi.h"
#include "DIBapi.h"
#pragma comment(lib, "wavelet_3_8.lib")
transeform_wavelet::transeform_wavelet()
{
m_nColorTableLengthOut=0;
m_nScale = 0;
m_nBitCountOut=0;
m_pImgDataOut=NULL;
m_pColorTableOut=NULL;
pCoeff = NULL;
}
transeform_wavelet::transeform_wavelet(CSize size, int nBitCount, LPRGBQUAD lpColorTable, unsigned char *pImgData):
ImgCenterDib(size, nBitCount, lpColorTable, pImgData)
{
m_nBitCountOut=m_nBitCount;
m_pColorTableOut=m_lpColorTable;
int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;
m_pImgDataOut=new unsigned char[lineByte*m_imgHeight];
for(int i=0 ; i < m_imgWidth ; i++)
for ( int j = 0 ; j < m_imgHeight ; j++)
m_pImgDataOut[j * lineByte + i]=pImgData[j * lineByte + i];
pCoeff = NULL;
}
transeform_wavelet::~transeform_wavelet()
{
if (m_pImgDataOut!=NULL){
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
if (pCoeff != NULL)
{
delete[] pCoeff;
pCoeff = NULL;
}
}
/**********************************************************************
*
* 函数名称:
* MatrixRegionCopy()
*
* 参数:
* unsigned char *matrixRegion 源矩阵数组指针
* int heightRegion 复制区域的高度
* int widthRegion 复制区域的宽度
* unsigned char *matrixDest 目的矩阵数组指针
* int heightDest 目的矩阵区域的高度
* int widthDest 目的矩阵区域的宽度
*
* 返回值:
* void
*
* 说明:
* 将源矩阵的指定区域数据复制到目的矩阵的指定区域
*
**********************************************************************/
void transeform_wavelet::MatrixRegionCopy(unsigned char *matrixRegion, int heightRegion, int widthRegion,
unsigned char *matrixDest, int heightDest, int widthDest)
{
//计算区域高度和宽度
int heightMin = heightRegion>heightDest ? heightDest : heightRegion;
int widthMin = widthRegion>widthDest ? widthDest : widthRegion;
int h, w;
for (h=0; h<heightMin; h++)
{
for (w=0; w<widthMin; w++)
{
matrixDest[h * widthDest + w] = matrixRegion[h * widthRegion + w];
}
}
}
/**********************************************************************
*
* 函数名称:
* MatrixSub()
*
* 参数:
* unsigned char *matrixA 待求差矩阵A数组指针
* unsigned char *matrixB 待求差矩阵B数组指针
* int height 高度
* int width 宽度
* unsigned char *result 差矩阵数组指针
*
* 返回值:
* void
*
* 说明:
* 将输入的两个矩阵A和B求差
*
**********************************************************************/
void transeform_wavelet::MatrixSub(unsigned char *matrixA, unsigned char *matrixB, int height, int width, unsigned char *result)
{
unsigned char temp;
int h, w;
for (h=0; h<height; h++)
{
for (w=0; w<width; w++)
{
temp = matrixA[h * width + w] - matrixB[h * width + w] + 128;
result[h * width + w] = temp;
}
}
}
/**********************************************************************
*
* 函数名称:
* MatrixSampleRow()
*
* 参数:
* unsigned char *matrixInput 待采样矩阵数组指针
* unsigned char *matrixOutputOdd 奇数行采样生成的矩阵
* unsigned char *matrixOutputEven 偶数行采样生成的矩阵
* int heightOutput 输出矩阵高度
* int widthOutput 输出矩阵宽度
* int widthInput 输入矩阵宽度
*
* 返回值:
* void
*
* 说明:
* 对输入矩阵进行行抽点采样
*
**********************************************************************/
void transeform_wavelet::MatrixSampleRow(unsigned char *matrixInput, unsigned char *matrixOutputOdd,
unsigned char *matrixOutputEven, int heightOutput, int widthOutput, int widthInput)
{
int h, w;
for (h=0; h<heightOutput; h++)
{
for (w=0; w<widthOutput; w++)
{
matrixOutputEven[h * widthOutput + w] = matrixInput[h * 2 * widthInput + w];
matrixOutputOdd[h * widthOutput + w] = matrixInput[(h * 2 + 1) * widthInput + w];
}
}
}
/**********************************************************************
*
* 函数名称:
* MatrixSampleLine()
*
* 参数:
* unsigned char *matrixInput 待采样矩阵数组指针
* unsigned char *matrixOutputOdd 奇数列采样生成的矩阵
* unsigned char *matrixOutputEven 偶数列采样生成的矩阵
* int heightOutput 输出矩阵高度
* int widthOutput 输出矩阵宽度
* int widthInput 输入矩阵宽度
*
* 返回值:
* void
*
* 说明:
* 对输入矩阵进行列抽点采样
*
**********************************************************************/
void transeform_wavelet::MatrixSampleLine(unsigned char *matrixInput, unsigned char *matrixOutputOdd,
unsigned char *matrixOutputEven, int heightOutput, int widthOutput, int widthInput)
{
int h, w;
for (h=0; h<heightOutput; h++)
{
for (w=0; w<widthOutput; w++)
{
matrixOutputEven[h * widthOutput + w] = matrixInput[h * widthInput + w * 2];
matrixOutputOdd[h * widthOutput + w] = matrixInput[h * widthInput + w * 2 + 1];
}
}
}
/**********************************************************************
*
* 函数名称:
* MatrixSub()
*
* 参数:
* unsigned char *matrixA 待求和矩阵A数组指针
* unsigned char *matrixB 待求和矩阵B数组指针
* int height 高度
* int width 宽度
* unsigned char *result 和矩阵数组指针
*
* 返回值:
* void
*
* 说明:
* 将输入的两个矩阵A和B求和
*
**********************************************************************/
void transeform_wavelet::MatrixPlus(unsigned char *matrixA, unsigned char *matrixB, int height, int width, unsigned char *result)
{
unsigned char temp;
int h, w;
for (h=0; h<height; h++)
{
for (w=0; w<width; w++)
{
temp = matrixA[h * width + w] + matrixB[h * width + w] - 128;
result[h * width + w] = temp;
}
}
}
/**********************************************************************
*
* 函数名称:
* MatrixInsertRow()
*
* 参数:
* unsigned char *matrixInputOdd 输入奇数行采样生成的矩阵
* unsigned char *matrixInputEven 输入偶数行采样生成的矩阵
* unsigned char *matrixOutput 输出待插点矩阵数组指针
* int heightInput 输入矩阵高度
* int widthInput 输入矩阵宽度
* int widthOutput 输出矩阵宽度
*
* 返回值:
* void
*
* 说明:
* 对输入矩阵进行行插点采样
*
**********************************************************************/
void transeform_wavelet::MatrixInsertRow(unsigned char *matrixInputOdd, unsigned char *matrixInputEven,
unsigned char *matrixOutput, int heightInput, int widthInput, int widthOutput)
{
int h, w;
for (h=0; h<heightInput*2; h++)
{
for (w=0; w<widthInput; w++)
{
if (h%2 == 0)
{
matrixOutput[h * widthOutput + w] = matrixInputEven[(int)(h/2) * widthInput + w];
}
else
{
matrixOutput[h * widthOutput + w] = matrixInputOdd[(int)(h/2) * widthInput + w];
}
}
}
}
/**********************************************************************
*
* 函数名称:
* MatrixInsertLine()
*
* 参数:
* unsigned char *matrixInputOdd 输入奇数列采样生成的矩阵
* unsigned char *matrixInputEven 输入偶数列采样生成的矩阵
* unsigned char *matrixOutput 输出待插点矩阵数组指针
* int heightInput 输入矩阵高度
* int widthInput 输入矩阵宽度
* int widthOutput 输出矩阵宽度
*
* 返回值:
* void
*
* 说明:
* 对输入矩阵进行列插点采样
*
**********************************************************************/
void transeform_wavelet::MatrixInsertLine(unsigned char *matrixInputOdd, unsigned char *matrixInputEven,
unsigned char *matrixOutput, int heightInput, int widthInput, int widthOutput)
{
int h, w;
for (h=0; h<heightInput; h++)
{
for (w=0; w<widthOutput; w++)
{
if (w%2 == 0)
{
matrixOutput[h * widthOutput + w] = matrixInputEven[h * widthInput + w/2];
}
else
{
matrixOutput[h * widthOutput + w] = matrixInputOdd[h * widthInput + w/2];
}
}
}
}
/**********************************************************************
*
* 函数名称:
* Trans()
*
* 参数:
* unsigned char *inputData 输入矩阵数组指针
* int inputHeight 输入矩阵高度
* int inputWidth 输入矩阵宽度
* int lineByte 矩阵行字节数
* int scale 分解尺度
* unsigned char *outputData 输出矩阵数组指针
*
* 返回值:
* void
*
* 说明:
* 进行一遍小波分解
*
**********************************************************************/
void transeform_wavelet::Trans(unsigned char *inputData, int inputHeight, int inputWidth, int lineByte, int scale, unsigned char *outputData)
{
unsigned char *buff = new unsigned char[lineByte*m_imgHeight];
int imageHeight = inputHeight;
int imageWidth = inputWidth;
unsigned char *temp1 = new unsigned char[imageWidth * (int)(imageHeight/2)];
unsigned char *temp2 = new unsigned char[imageWidth * (int)(imageHeight/2)];
//对图像矩阵进行行采样
this->MatrixSampleRow(inputData, temp1, temp2, (imageHeight/2), imageWidth, lineByte);
//行差分,得到高频与低频数据
this->MatrixSub(temp1, temp2, (imageHeight/2), imageWidth, temp1);
unsigned char *temp00 = new unsigned char[(imageWidth/2) * (imageHeight/2)];
unsigned char *temp01 = new unsigned char[(imageWidth/2) * (imageHeight/2)];
//对低频数据进行列采样
this->MatrixSampleLine(temp2, temp01, temp00, (imageHeight/2), (imageWidth/2), imageWidth);
//列差分得到LL和LH
this->MatrixSub(temp01, temp00, (imageHeight/2), (imageWidth/2), temp01);
unsigned char *temp10 = new unsigned char[(imageWidth/2) * (imageHeight/2)];
unsigned char *temp11 = new unsigned char[(imageWidth/2) * (imageHeight/2)];
//对高频数据进行列采样
this->MatrixSampleLine(temp1, temp11, temp10, (imageHeight/2), (imageWidth/2), imageWidth);
//列差分,得到HL和HH
this->MatrixSub(temp11, temp10, (imageHeight/2), (imageWidth/2), temp11);
this->MatrixRegionCopy(temp01, (imageHeight/2), (imageWidth/2),
buff+lineByte*(int)(imageHeight/2)+(int)(imageWidth/2), imageHeight, lineByte);
this->MatrixRegionCopy(temp10, (imageHeight/2), (imageWidth/2), buff, imageHeight, lineByte);
this->MatrixRegionCopy(temp11, (imageHeight/2), (imageWidth/2), buff+(int)(imageWidth/2), imageHeight, lineByte);
//释放空间
delete[] temp1;
delete[] temp2;
delete[] temp01;
delete[] temp10;
delete[] temp11;
scale--;
//继续对LL进行递归分解
if (scale > 0)
{
this->Trans(temp00, imageHeight/2, imageWidth/2, imageWidth/2, scale, temp00);
}
this->MatrixRegionCopy(temp00, (imageHeight/2), (imageWidth/2), buff+lineByte*(int)(imageHeight/2),
imageHeight, lineByte);
delete[] temp00;
//把最后的结果拷贝到m_pImgDataOut
memcpy(outputData, buff, lineByte * inputHeight);
delete[] buff;
}
/**********************************************************************
*
* 函数名称:
* SimpleWaveletTrans()
*
* 参数:
* int scale 分解尺度,默认为1
*
* 返回值:
* void
*
* 说明:
* 对图像数据进行给定尺度的小波分解
*
**********************************************************************/
void transeform_wavelet::SimpleWaveletTrans(int scale = 1)
{
if (scale<1 || scale>5)
{
return;
}
if(m_pImgDataOut!=NULL){
delete[] m_pImgDataOut;
m_pImgDataOut=NULL;
}
this->m_nScale = scale;
int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;
m_pImgDataOut=new unsigned char[lineByte*m_imgHeight];
this->Trans(m_pImgData, m_imgHeight, m_imgWidth, lineByte, scale, m_pImgDataOut);
}
/**********************************************************************
*
* 函数名称:
* Reverse()
*
* 参数:
* unsigned char *inputData 输入矩阵数组指针
* int inputHeight 输入矩阵高度
* int inputWidth 输入矩阵宽度
* int lineByte 矩阵行字节数
* int scale 分解尺度
* unsigned char *outputData 输出矩阵数组指针
*
* 返回值:
* void
*
* 说明:
* 进行一遍小波重构
*
**********************************************************************/
void transeform_wavelet::Reverse(unsigned char *inputData, int inputHeight, int inputWidth, int lineByte,
int scale, unsigned char *outputData)
{
unsigned char *buff = new unsigned char[lineByte*m_imgHeight];
int imageHeight = inputHeight;
int imageWidth = inputWidth;
unsigned char *temp10 = new unsigned char[(imageWidth/2) * (imageHeight/2)];
unsigned char *temp11 = new unsigned char[(imageWidth/2) * (imageHeight/2)];
this->MatrixRegionCopy(inputData, imageHeight, lineByte, temp10, (imageHeight/2), (imageWidth/2));
this->MatrixRegionCopy(inputData+(int)(imageWidth/2), imageHeight, lineByte, temp11, (imageHeight/2), (imageWidth/2));
this->MatrixPlus(temp11, temp10, (imageHeight/2), (imageWidth/2), temp11);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -