📄 imgenhance.cpp
字号:
#include "stdafx.h"
#include "ImgEnhance.h"
#include <math.h>
CImgEnhance::CImgEnhance()
{
m_nColorTableLengthOut=0;
m_nBitCountOut=0;
m_pImgDataOut=NULL;
m_lpColorTableOut=NULL;
}
CImgEnhance::CImgEnhance(CSize size, int nBitCount, LPRGBQUAD lpColorTable, unsigned char *pImgData):
ImgCenterDib(size, nBitCount, lpColorTable, pImgData)
{
m_nBitCountOut=0;
m_pImgDataOut=NULL;
m_lpColorTableOut=NULL;
m_nColorTableLengthOut=0;
}
CImgEnhance::~CImgEnhance()
{
if(m_pImgDataOut!=NULL){
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
if(m_lpColorTableOut==NULL){
delete []m_lpColorTableOut;
m_lpColorTableOut=NULL;
}
}
/**********************************************************************
*
* 函数名称:
* AddPepperSaltNoise()
*
* 参数:
* void
*
* 返回值:
* void
*
* 说明:
* 在view中图像添加椒盐噪声
*
**********************************************************************/
void CImgEnhance::AddPepperSaltNoise()
{
unsigned char* pDIB;
int bytecount,i;
if(m_pImgDataOut!=NULL)
{
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
pDIB=m_pImgData;
if(m_nBitCount==8||m_nBitCount==24)
{
bytecount = m_imgWidth * m_imgHeight *m_nBitCount/8; //获取位图数据区的字节数
}
else
{
AfxMessageBox("只能处理真彩色和8位灰度图像!");
return ;
}
if (m_nBitCount==8) //处理灰度图像
{
for (i=0;i<bytecount;i++)
{
if(rand()>32000) pDIB[i]=0;
if(rand()<200) pDIB[i]=255;
}
}
else //24位真彩色图像
{
for (i=0;i<bytecount;i=i+3)
{
int num=rand();
if (num>32000)
{
pDIB[i]=(rand())%255; //处理每一个像素的RGB值
pDIB[i+1]=(rand())%255;
pDIB[i+2]=(rand())%255;
}
if (num<200)
{
pDIB[i]=(rand())%255;
pDIB[i+1]=(rand())%255;
pDIB[i+2]=(rand())%255;
}
}
}
//生成新的DIB位图
m_nBitCountOut=m_nBitCount;
int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4;
if (!m_pImgDataOut)
{
m_pImgDataOut=new unsigned char[lineByteOut*m_imgHeight];
}
int j, pixelByte=m_nBitCountOut/8;
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth*pixelByte;j++)
*(m_pImgDataOut+i*lineByteOut+j)= *(pDIB+i*lineByteOut+j);
}
}
/**********************************************************************
*
* 函数名称:
* AddRandomNoise()
*
* 参数:
* void
*
* 返回值:
* void
*
* 说明:
* 在view中图像添加随机噪声
*
**********************************************************************/
void CImgEnhance::AddRandomNoise()
{
unsigned char* pDIB;
int bytecount,i;
if(m_pImgDataOut!=NULL)
{
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
pDIB=m_pImgData;
if(m_nBitCount==8)
{
bytecount = m_imgWidth * m_imgHeight *m_nBitCount/8; //获取位图数据区的字节数
}
else
{
AfxMessageBox("只能处理8位灰度图像!");
return ;
}
//DIB中添加随机噪声
for( i=0;i<bytecount;i++)
{
LONG Temp=rand();
Temp = pDIB[i]*224/256+Temp/512;
pDIB[i] = Temp >= 255 ? 255 : Temp;
}
m_nBitCountOut=m_nBitCount;
int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4;
if (!m_pImgDataOut)
{
m_pImgDataOut=new unsigned char[lineByteOut*m_imgHeight];
}
int j, pixelByte=m_nBitCountOut/8;
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth*pixelByte;j++)
*(m_pImgDataOut+i*lineByteOut+j)= *(pDIB+i*lineByteOut+j);
}
}
/**********************************************************************
*
* 函数名称:
* AvgTemplate(int TempH, int TempW, int TempCX, int TempCY, float *fpTempArray, float fCoef)
*
* 参数:
* int TempH 模板的高度
* int TempW 模板的宽度
* int TempCX 模板的中心元素X坐标 ( < iTempW - 1)
* int TempCY 模板的中心元素Y坐标 ( < iTempH - 1)
* float *fpTempArray 指向模板数组的指针
* float f 模板系数
*
* 返回值:
* void
*
* 说明:
* 该函数用指定的模板(任意大小)来对图像进行操作,参数TempH指定模板
* 的高度,参数TempW指定模板的宽度,参数TempCX和iTempCY指定模板的中心
* 元素坐标,参数fpTempArray指定模板元素,f指定系数。
*
**********************************************************************/
void CImgEnhance::AvgTemplate(int TempH, int TempW, int TempCX, int TempCY, float *fpTempArray, float f)
{
unsigned char* pSrc;
unsigned char* pDst;
int i,j,k,l;
float value;
if(m_pImgDataOut != NULL)
{
delete []m_pImgDataOut;
m_pImgDataOut = NULL;
}
int lineByte = (m_imgWidth * m_nBitCount / 8 + 3) / 4 * 4;
if(m_nBitCount != 8)
{
AfxMessageBox("只能处理8位灰度图像!");
return ;
}
//创建要复制的图像区域
m_nBitCountOut = m_nBitCount;
int lineByteOut = (m_imgWidth*m_nBitCountOut / 8 + 3) / 4 * 4;
if (!m_pImgDataOut)
{
m_pImgDataOut = new unsigned char[lineByteOut*m_imgHeight];
}
int pixelByte = m_nBitCountOut / 8;
for(i = 0; i < m_imgHeight; i++){
for(j = 0; j < m_imgWidth * pixelByte; j++)
*(m_pImgDataOut+i*lineByteOut+j)= *(m_pImgData+i*lineByteOut+j);
}
//行处理(去掉边缘几行)
for (i = TempCY; i < m_imgHeight - TempH + TempCY + 1; i++)
{
//列处理(去掉边缘几列)
for (j = TempCX; j < m_imgWidth - TempW + TempCX + 1; j++)
{
//指向新DIB第i行第j列的像素的指针
pDst = m_pImgDataOut + lineByte * (m_imgHeight - 1 - i) + j;
value=0;
//计算
for (k = 0; k < TempH; k++)
{
for (l = 0; l < TempW; l++)
{
pSrc = m_pImgData + lineByte * (m_imgHeight - 1 - i
+ TempCY - k) + j - TempCX + l;
//计算加权平均,保存像素值
value += (*pSrc) * fpTempArray[k * TempW + l];
}
}
//乘以系数
value*=f;
//取结果的绝对值
value=(float)fabs(value);
if (value > 255)
{
*pDst = 255;
}
else
{
*pDst = (unsigned char)(value + 0.5);
}
}
}
}
/**********************************************************************
*
* 函数名称:
* FindMedianValue(unsigned char* pbArray,int ArrayLen)
*
* 参数:
* unsigned char* pbArray 指向模板数组首地址的指针
* int ArrayLen 模板数组的长度
*
* 返回值:
* unsigned char
*
* 说明:
* /中值滤波中查找模版中像素中值的算法_利用冒泡排序
*
**********************************************************************/
unsigned char CImgEnhance::FindMedianValue(unsigned char* pbArray,int ArrayLen)
{
int i,j;
unsigned char Temp;
for(j =0; j<ArrayLen; j++)
{
for(i =0; i <ArrayLen-j-1; i++)
{
if(pbArray[i]>pbArray[i+1])
{
Temp=pbArray[i];
pbArray[i]=pbArray[i+1];
pbArray[i+1]=Temp;
}
}
}
if ((ArrayLen&1)>0)
{
Temp=pbArray[(ArrayLen+1)/2];
}
else
{
Temp=(pbArray[ArrayLen/2]+pbArray[ArrayLen/2+1])/2;
}
return Temp;
}
/**********************************************************************
*
* 函数名称:
* MedianFilter(int FilterH, int FilterW, int FilterCX, int FilterCY)
*
* 参数:
* int FilterH 模板的高度
* int FilterW 模板的宽度
* int FilterCX 模板的中心元素X坐标 ( < FilterW - 1)
* int FilterCY 模板的中心元素Y坐标 ( < FilterH - 1)
*
* 返回值:
* void
*
* 说明:
* 中值滤波的算法
*
**********************************************************************/
void CImgEnhance::MedianFilter(int FilterH, int FilterW, int FilterCX, int FilterCY)
{
unsigned char* pSrc;
unsigned char* pDst;
int i,j,k,l;
unsigned char* value; //指向滤波器数组的指针
if(m_pImgDataOut != NULL)
{
delete []m_pImgDataOut;
m_pImgDataOut = NULL;
}
//计算图像每行的字节数
int lineByte = (m_imgWidth * m_nBitCount / 8 + 3) / 4 * 4;
if(m_nBitCount != 8)
{
AfxMessageBox("只能处理8位灰度图像!");
return ;
}
//分配内存,以保存新图像
m_nBitCountOut = m_nBitCount;
int lineByteOut = (m_imgWidth * m_nBitCountOut / 8 + 3) / 4 * 4;
if (!m_pImgDataOut)
{
//为处理后的图像分配内存空间
m_pImgDataOut = new unsigned char[lineByteOut * m_imgHeight];
}
int pixelByte = m_nBitCountOut / 8;
for(i = 0; i < m_imgHeight; i++){
for(j = 0; j < m_imgWidth * pixelByte; j++)
*(m_pImgDataOut + i * lineByteOut +j) = *(m_pImgData + i * lineByteOut + j);
}
//暂时分配内存,以保存滤波器数组
value = new unsigned char[FilterH * FilterW];
for (i = FilterCY; i < m_imgHeight - FilterH ; i++)//+ FilterCY + 1
{
for (j = FilterCX; j < m_imgWidth - FilterW ; j++)//+ FilterCX + 1
{
pDst = m_pImgDataOut + lineByte * (m_imgHeight - 1 - i) + j;
for (k = 0; k < FilterH; k++)
{
for (l = 0; l < FilterW; l++)
{
pSrc = m_pImgData + lineByte * (m_imgHeight - l - i
+ FilterCY - k) + j - FilterCX + l;
value[k * FilterW + l] = *pSrc;
}
}
*pDst = FindMedianValue(value,FilterW * FilterH);
}
}
}
/*************************************************************************
* 函数名称:
* GradSharp()
* 参数:
* BYTE bThre - 阈值
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
* 说明:
* 该函数用来对图像进行梯度锐化,设定梯度锐化的阈值为30
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -