# 几种常见的图像处理的方法

0.知识储备

typedef struct tagBITMAPFILEHEADER {
WORD    bfType;
DWORD   bfSize;
WORD    bfReserved1;
WORD    bfReserved2;
DWORD   bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{
DWORD      biSize;
LONG       biWidth;
LONG       biHeight;
WORD       biPlanes;
WORD       biBitCount;
DWORD      biCompression;
DWORD      biSizeImage;
LONG       biXPelsPerMeter;
LONG       biYPelsPerMeter;
DWORD      biClrUsed;
DWORD      biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

1.将彩色图像转换为灰度图像

/********************************************
*	   将文件转换成灰度图像		    *
********************************************/
int CBitMapFile::turn2Gray()
{
if (m_imageArray == NULL)
{
return -2;
}

for (int i =0,j= 0,k=0;i<m_sizeImage;)
{
//转换为灰度图像，注意填充的字节
BYTE blue,green,red,gray;

blue = m_imageArray[i];
green = m_imageArray[i+1];
red = m_imageArray[i+2];

m_realColorImageArray[k] = blue;
m_realColorImageArray[k+1] = green;
m_realColorImageArray[k+2] = red;

gray = (BYTE)(0.3*red+0.59*green+0.11*blue);

m_imageArray[i] = gray;
m_imageArray[i+1] = gray;
m_imageArray[i+2] = gray;

m_realImageArray[j] = m_imageArray[i];

i += 3;
k += 3;
j++;

////跳过填充字节
if (j % m_width == 0)
{
}

}

return 1;
}

2.图像转换为ASNII码文件

char* _buf = new char[m_width+2];
memset(_buf,0,m_width+2);
//TRACE(_T("\'\\r\'=%x,\'\\n\'=%x"),'\r','\n');
for (int i = m_height-1;i>=0;i--)
{
for (int j = 0;j<m_width;j++)
{
_buf[j] = txtMap[m_realImageArray[i*m_width+j]>>5];

}

_buf[m_width] = '\r';
_buf[m_width+1] = '\n';

for (int k=0;k<m_width+2;k++)
{
_txtBuf[(m_height-1-i)*m_width+k+(m_height-1-i)*2] = _buf[k];

}
}

txtFile.Write(_txtBuf,sizeof(char)*(m_width*m_height+2*m_height));

delete _txtBuf;
delete _buf;
return 1;
}

3.直方图均衡化

/********************************************
*	对bmp文件的每个像素的灰度值进行统计		*
********************************************/
{
for (int i = 0;i<m_width*m_height;i++)
{
m_grayStatistic[m_realImageArray[i]] += 1;

}
for (int i = 0;i<256;i++)
{
if (m_grayStatistic[i]>m_max)
{
m_max = m_grayStatistic[i];
}

}
//TRACE(_T("m_max = %d\n"),m_max);
return 1;
}
/********************************************
*	对bmp文件的每个像素的灰度值进行归一化	*
*		并计算每个像素灰度值的概率			*
********************************************/
int CBitMapFile::turn2One()
{
for (int i =0;i<256;i++)
{
m_grayTurn2OneData[i] = (double)m_grayStatistic[i]/m_max;
m_grayFrequencyPerLevel[i] = (double)m_grayStatistic[i]/(m_width*m_height);

}
m_maxFrequency = m_max/(m_width*m_height);
return 1;
}

/********************************************
*	清除统计数组、归一化数组、频率数组		*
********************************************/
void CBitMapFile::clearup()
{
memset(m_grayStatistic,0,sizeof(LONG)*256);
memset(m_grayTurn2OneData,0,sizeof(double)*256);
memset(m_grayFrequencyPerLevel,0,sizeof(double)*256);
m_max = 0;
m_maxFrequency = 0.0f;
}
/********************************************
*				灰度均衡化					*
********************************************/
void CBitMapFile::equation(CFile& file)
{
double _temp =0.0f;
double* _array = new double[256];
memset(_array,0,sizeof(double)*256);
int* _intArray = new int[256];
memset(_intArray,0,sizeof(int)*256);
BYTE* _writeArray = new BYTE[m_sizeImage];
memset(_writeArray,0,sizeof(BYTE)*m_sizeImage);
for(int i = 0;i<256;i++)
{
_array[i] = ((m_grayFrequencyPerLevel[i])*255)+_temp;
_temp = _array[i];

}
for (int i = 0;i<256;i++)
{
_intArray[i] = (int)(_array[i]);
}
for (int i = 0,j = 0;i<m_sizeImage;)
{

_writeArray[i] = _intArray[m_realImageArray[j]];
_writeArray[i+1] = _intArray[m_realImageArray[j]];
_writeArray[i+2] = _intArray[m_realImageArray[j]];
j++;
i += 3;
if (j%m_width == 0)
{
for (int k = 0;k<m_addByte;k++)
{
_writeArray[i+k] = 0;

}
}
}
file.Write(_writeArray,sizeof(BYTE)*m_sizeImage);
delete _array;
delete _intArray;
delete _writeArray;
}

4.伽马校正

/********************************************
*				伽马校正					*
********************************************/
void CBitMapFile::gammaCorrection(double gamma,CFile& file)
{
//数据准备
double* _correctData = new double[m_width*m_height];
BYTE* _writeArray = new BYTE[m_sizeImage];
memset(_writeArray,0,sizeof(BYTE)*m_sizeImage);
memset(_correctData,0,sizeof(double)*m_width*m_height);
//算法
for (int i = 0;i<m_width*m_height;i++)
{
_correctData[i] = (double)m_realImageArray[i]/255;

_correctData[i] = pow(_correctData[i],gamma)*255;

}
//写入文件准备
for (int i = 0,j = 0;i<m_sizeImage;)
{
_writeArray[i] = (BYTE)_correctData[j];
_writeArray[i+1] = (BYTE)_correctData[j];
_writeArray[i+2] = (BYTE)_correctData[j];
j++;
i += 3;
if (j%m_width == 0)
{
for (int k = 0;k<m_addByte;k++)
{
_writeArray[i+k] = 0;

}
}
}
//写入文件
file.Write(_writeArray,sizeof(BYTE)*m_sizeImage);

delete _writeArray;
delete _correctData;
}

4.哈尔小波变换（HWT，haar wavelet tansform）

Matrix.h

#pragma once
#define ZERO 0	//零阵
#define IDENTITY 1//单位阵
#define HAAR 2//HAAR小波矩阵
#define UNSQUARE -1//非方阵
#define UNSAME -2//非同型矩阵
#define UNSAME -2//非同型矩阵
#define UNEVEN -3//行列非偶数

class CMatrix
{
public:
CMatrix(int r,int c);
CMatrix(CMatrix& m);
CMatrix(double* d,int r,int c);
CMatrix(BYTE* d,int r,int c);
~CMatrix();
int inital(int type);//初始化为单位阵，或特殊矩阵（以后扩展）
#ifdef _DEBUG
void display();
#endif
//////////////////////////////////////////////////////////////////////////
public:
CMatrix& transpose();//矩阵的转置
void nonZero();
//////////////////////////////////////////////////////////////////////////
public:
CMatrix& operator=(CMatrix& m1);
friend CMatrix operator+(CMatrix& m1,CMatrix& m2);
friend CMatrix operator-(CMatrix& m1,CMatrix& m2);
friend CMatrix operator*(CMatrix& m1,double& a);
friend CMatrix operator*(CMatrix& m1,CMatrix& m2);
//////////////////////////////////////////////////////////////////////////
public:
inline int getRow(){return m_row;}
inline int getCol(){return m_col;}
//inline CString getName(){return m_name;}
inline double getElem(int r,int c){return m_data[r*m_row+c];}
inline double* getData(){return m_data;}
//////////////////////////////////////////////////////////////////////////
protected:
int m_row;
int m_col;
double* m_data;
//	CString m_name;
};


Matrix.cpp

#include "StdAfx.h"

#include "MatrixBase.h"
#ifdef _DEBUG
#include <iostream>
#endif

CMatrix::CMatrix(int r,int c)
{
m_row = r;
m_col = c;
m_data = new double[r*c];
memset(m_data,0,sizeof(double)*r*c);
}
CMatrix::CMatrix(double* d,int r,int c)
{
m_row = r;
m_col = c;
m_data = new double[r*c];
for (int i = 0;i<r*c;i++)
{
m_data[i] = d[i];
}
}
CMatrix::CMatrix(BYTE* d,int r,int c)
{
m_row = r;
m_col = c;
m_data = new double[r*c];
for (int i = 0;i<r*c;i++)
{
m_data[i] = (double)d[i];
}
}
CMatrix::CMatrix(CMatrix& m)
{
this->m_row = m.m_row;
this->m_col = m.m_col;
m_data = new double[m_row*m_col];
for (int i = 0;i<m_row*m_col;i++)
{
this->m_data[i] = m.m_data[i];
TRACE(_T("data[%d]=%f\n"),i,this->m_data[i]);
}
}
CMatrix::~CMatrix()
{
delete[] m_data;
}
int CMatrix::inital(int type)
{

switch(type)
{
case IDENTITY:
if (m_row != m_col)
{
return UNSQUARE;
}
for (int i=0;i<m_col;i++)
{
m_data[i*m_row+i] = 1;
}
break;
case HAAR:
if (m_row != m_col)
{
return UNSQUARE;
}
if (m_row%2 != 0)
{
return UNEVEN;
}
for(int i = 0;i<m_row/2;i++)
{
m_data[i*m_row+i*2] = 1;
m_data[i*m_row+i*2+1] = 1;
}
for (int i = m_row/2,j = 0;i<m_row;i++,j++)
{
m_data[i*m_row+j*2] = -1;
m_data[i*m_row+j*2+1] = 1;
}
break;
default:
break;
}
return type;
}
CMatrix& CMatrix::operator=(CMatrix& m1)
{
ASSERT(m_row == m1.getRow() && m_col == m1.getCol());
for (int i = 0;i<m_row*m_col;i++)
{
m_data[i] = m1.getElem(i/m_row,i%m_row);
TRACE(_T("\'=\'data[%d]=%f\n"),i,m_data[i]);
}
return *this;
}
CMatrix operator+(CMatrix& m1,CMatrix& m2)
{
ASSERT(m1.m_row == m2.m_row && m1.m_col==m2.m_col);
CMatrix ret(m1.m_row,m1.m_col);
for (int i = 0;i<m1.m_row*m1.m_col;i++)
{
ret.m_data[i] = m1.m_data[i]+m2.m_data[i];
TRACE(_T("ret[%d]=%f\n"),i,ret.m_data[i]);
}
return ret;

}
CMatrix operator-(CMatrix& m1,CMatrix& m2)
{
ASSERT(m1.m_row == m2.m_row && m1.m_col==m2.m_col);
CMatrix ret(m1.m_row,m1.m_col);
for (int i = 0;i<m1.m_row*m1.m_col;i++)
{
ret.m_data[i] = m1.m_data[i]-m2.m_data[i];
TRACE(_T("ret[%d]=%f\n"),i,ret.m_data[i]);
}
return ret;
}
CMatrix operator*(CMatrix& m1,double& a)
{
CMatrix ret(m1);
for (int i = 0;i<m1.m_row*m1.m_col;i++)
{
ret.m_data[i] *=a;
TRACE(_T("ret[%d]=%f\n"),i,ret.m_data[i]);
}
return ret;
}
CMatrix operator*(CMatrix& m1,CMatrix& m2)
{
ASSERT(m1.m_col == m2.m_row);
CMatrix ret(m1.m_row,m2.m_col);
for (int i= 0;i<m1.m_row;i++)
{
for (int j = 0;j<m2.m_col;j++)
{
double _temp = 0;
for (int k = 0;k<m1.m_col;k++)
{
_temp += m1.m_data[i*m1.m_row+k]*m2.m_data[k*m2.m_row+j];
}
ret.m_data[i*m1.m_row+j] = _temp;
}
}
return ret;
}
CMatrix& CMatrix::transpose()
{
double* _newData = new double[m_row*m_col];

for (int i = 0;i<m_row;i++)
{
for (int j=0;j<m_col;j++)
{
_newData[j*m_col+i] = m_data[i*m_row+j];
}
}
delete m_data;
m_data = _newData;

return *this;

}
void CMatrix::nonZero()
{
for (int i = 0;i<m_row;i++)
{
for (int j = 0;j<m_col;j++)
{
if(m_data[i*m_row+j]<0)
{
m_data[i*m_row+j]=0;
}
}
}
}
#ifdef _DEBUG
void CMatrix::display()
{
std::cout<<"[\n";
for (int i = 0;i<m_row*m_col;i++)
{
std::cout<<m_data[i]<<" ,";
if ((i+1)%m_row == 0)
{
std::cout<<std::endl;
}
}
std::cout<<"]"<<std::endl;
}
#endif


/********************************************
*				HAAR小波变换				*
********************************************/
void CBitMapFile::haarTransform(CFile& file)
{
CMatrix imageMatrix(m_realImageArray,m_height,m_width);
CMatrix haarMatrix_r(m_height,m_height);
CMatrix haarMatrix_c(m_width,m_width);
#ifdef _DEBUG
imageMatrix.display();
#endif
haarMatrix_c.inital(HAAR);
haarMatrix_c = haarMatrix_c.transpose();
haarMatrix_r.inital(HAAR);
imageMatrix = haarMatrix_r*imageMatrix;
double _d = 0.25*sqrt(2.0);
imageMatrix = imageMatrix*_d;
imageMatrix = imageMatrix*haarMatrix_c;
imageMatrix = imageMatrix*_d;

imageMatrix.nonZero();
#ifdef _DEBUG
imageMatrix.display();
#endif

double* _correctData = imageMatrix.getData();
BYTE* _writeArray = new BYTE[m_sizeImage];
memset(_writeArray,0,sizeof(BYTE)*m_sizeImage);

for (int i = 0,j = 0;i<m_sizeImage;)
{
_writeArray[i] = (BYTE)_correctData[j];
_writeArray[i+1] = (BYTE)_correctData[j];
_writeArray[i+2] = (BYTE)_correctData[j];
j++;
i += 3;
if (j%m_width == 0)
{
for (int k = 0;k<m_addByte;k++)
{
_writeArray[i+k] = 0;

}
}
}
file.Write(_writeArray,sizeof(BYTE)*m_sizeImage);

delete _writeArray;
//delete _correctData;
}

• 本文已收录于以下专栏：

举报原因： 您举报文章：几种常见的图像处理的方法 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)