⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 huidubianhuandib.cpp

📁 < VC++图像处理程程序设计>>配套光盘,这是第4章的灰度变换的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "windowsx.h"
#include "math.h"
#include "HuiDuBianHuanDib.h"
#include "MainFrm.h"
#include "DynSplitView2.h"
 
HuiDuBianHuanDib::HuiDuBianHuanDib()
{
}
HuiDuBianHuanDib::~HuiDuBianHuanDib()
{
}

///***************************************************************/           
/*函数名称:FanSeBianHuan()                                        
/*函数类型:void                                           
/*功能:对图像进行反色变换                            
/***************************************************************/
void HuiDuBianHuanDib::FanSeBianHuan()//对图像进行反色变换
{
	LPBYTE  p_data;     //原图数据区指针
	int wide,height;    //原图长、宽
	p_data=this->GetData ();     //取得原图的数据区指针
	if(m_pBitmapInfoHeader->biBitCount<9)		
		wide=this->GetWidth ();
	else
		wide=this->GetDibWidthBytes();
	height=this->GetHeight ();
	for(int i=0;i<height*wide;i++)
	{
		unsigned char  temp;
		temp=*(p_data+i);
		*(p_data+i)=255- temp;
	}	
}

///***************************************************************/           
/*函数名称:Fei0()												*/
/*函数类型:void												*/
/*功能:对图像进行非零取一运算。								*/
/****************************************************************/
void HuiDuBianHuanDib::Fei0()//对图像进行非零取一运算
{
	LPBYTE p_data;     //原图数据区指针
	int wide,height;    //原图长、宽
	p_data=this->GetData ();     //取得原图的数据区指针
	if(m_pBitmapInfoHeader->biBitCount<9)		
		wide=this->GetWidth ();
	else
		wide=this->GetDibWidthBytes();
	height=this->GetHeight ();
	for(int j=0;j<height;j++)
	{
		for(int i=0;i<wide;i++)    //所有像素依次循环
		{
			if(*p_data!=0)          //若像素值不为0
				*p_data=255;         //将其置为255
			p_data++; 				 
		}
	}
}

/***************************************************************/           
/*函数名称:GuDing(int YuZhi)                                  */      
/*函数类型:void											   */	
/*参数说明:YuZhi 给定阈值                                     */       
/*功能:对图像进行固定阀值运算。                               */
/***************************************************************/
void HuiDuBianHuanDib::GuDing(int YuZhi)//对图像进行固定阀值运算
{
	LPBYTE  p_data;     //原图数据区指针
	int wide,height;    //原图长、宽
	p_data=this->GetData ();     //取得原图的数据区指针
	if(m_pBitmapInfoHeader->biBitCount<9)		
		wide=this->GetWidth ();
	else
		wide=this->GetDibWidthBytes();
	height=this->GetHeight ();
	for(int j=0;j<height;j++)
	{
		for(int i=0;i<wide;i++)
		{
			if(*p_data>YuZhi)          //灰度值大于给定阈值,置为255
				*p_data=255;
			else
				*p_data=0;             //不大于置为0
			p_data++;
		}
	}
}

/***************************************************************/           
/*函数名称:ShuangYu(int YuZhi1,int YuZhi2,int mode)          */
/*参数:int YuZhi1:阈值1;int YuZhi2:阈值2;int mode:处理方式*/
/*函数类型:void                                              */
/*功能:对图像使用双固定阈值法进行二值化。                     */
/***************************************************************/
void HuiDuBianHuanDib::ShuangYu(int YuZhi1,int YuZhi2,int mode)
{
	LPBYTE  p_data;     //原图数据区指针
	int wide,height;    //原图长、宽
	p_data=this->GetData ();
	if(m_pBitmapInfoHeader->biBitCount<9)		
		wide=this->GetWidth ();
	else
		wide=this->GetDibWidthBytes();
	height=this->GetHeight ();
	if(mode==0)    //0-255-0型
	{
		for(int j=0;j<height;j++)
			for(int i=0;i<wide;i++)
			{
				//若该像素的灰度值介于两个阈值之间,这将其置为255
				if(*p_data>=YuZhi1&&*p_data<=YuZhi2)
					*p_data=255;
				else
					*p_data=0;     //否则置0
				p_data++; 			 		
			}	
	}
	if(mode==1)    //255-0-255型
	{
		for(int j=0;j<height;j++)
			for(int i=0;i<wide;i++)
			{
				//若该像素的灰度值介于两个阈值之间,这将其置为0
				if(*p_data>=YuZhi1&&*p_data<=YuZhi2)
					*p_data=0;
				else
					*p_data=255;    //否则置255
				p_data++; 					
			}
	}			 
}

///***************************************************************/           
/*函数名称:ZhiFangTu(float *tongji)                               
/*函数类型:void                                         
/*变量说明:tongji  灰度分布密度统计                                                        
/*功能:对图像进行灰度直方图统计。                     
/***************************************************************/
void HuiDuBianHuanDib::ZhiFangTu(float *tongji)
{
	// 循环变量
	int i;
	int j;
	// 灰度计数
	int huidu[256];    
	int wide,height;    //原图长、宽
	wide=this->GetWidth ();		 
	height=this->GetHeight ();
	// 变量初始化
	memset(huidu,0,sizeof(huidu));
	LPBYTE  temp1=new BYTE[wide*height];    //新图像缓冲区
	//拷贝原图像到缓存图像
	memcpy(temp1,m_pData,wide*height );
	// 对各像素进行灰度统计
	for (j = 0; j < height; j ++)
	{
		for (i = 0; i <wide; i ++)
		{
			unsigned char  temp = temp1[wide* j + i] ;
			// 灰度统计计数
			huidu[temp]++;
		}
	}
	// 计算灰度分布密度
	for(i=0;i<256;i++)
		tongji[i] = huidu[i] / (height * wide *1.0f);	
}

///***************************************************************/           
/*函数名称:Zhexianbianhuan(BYTE bX1,BYTE bY1,BYTE bX2,BYTE bY2)                                           */
/*函数类型:void                                              */
/*变量说明:bX1折点一的原始灰度;bX2bY1折点二的原始灰度
/*          bY1折点一的变换灰度;bY2折点二的变换灰度                                                       
/*功能:对图像进行分段线性变换。                      */
/***************************************************************/ 
void HuiDuBianHuanDib::Zhexianbianhuan(BYTE bX1, BYTE bY1, BYTE bX2, BYTE bY2)
{ 
	// 循环变量
	int i;
	int j;
	int wide;
	int height;
	LPBYTE  p_data;
	p_data=this->GetData ();     //取得原图的数据区指针
	wide=this->GetWidth ();
	height=this->GetHeight ();
	LPBYTE temp=new BYTE[wide*height];    //新图像缓冲区
	//拷贝原图像到缓存图像
	memcpy(temp,p_data,wide*height);
	// 灰度映射表
	BYTE	bMap[256];
	// 计算灰度映射表
	for (i = 0; i <= bX1; i++)	//[0 —— X1]
	{
		// 判断bX1是否大于0(防止分母为0)
		if (bX1 > 0)
		{
			// 线性变换
			bMap[i] = (BYTE) bY1 * i / bX1;
		}
		else
		{
			// 直接赋值为0
			bMap[i] = 0;
		}
	}
	for (; i <= bX2; i++)		//(X1 —— X2]
	{
		// 判断bX1是否等于bX2(防止分母为0)
		if (bX2 != bX1)
		{
			// 线性变换
			bMap[i] = bY1 + (BYTE) ((bY2 - bY1) * (i - bX1) / (bX2 - bX1));
		}
		else
		{
			// 直接赋值为bY1
			bMap[i] = bY1;
		}
	}
	for (; i < 256; i++)		//(X2 —— 256)
	{
		// 判断bX2是否等于255(防止分母为0)
		if (bX2 != 255)
		{
			// 线性变换
			bMap[i] = bY2 + (BYTE) ((255 - bY2) * (i - bX2) / (255 - bX2));
		}
		else
		{
			// 直接赋值为255
			bMap[i] = 255;
		}
	}
	if  (m_pBitmapInfoHeader->biBitCount<9)		//灰度图像
	{
		// 对各像素进行灰度转换
		for (i = 0; i < height; i ++)
		{
			for (j = 0; j < wide; j ++)
			{
				// 对像素进行灰度映射处理
				unsigned char T = temp[ wide * i + j];
				temp[ wide * i + j] = bMap[T];			 
			}
		}
        memcpy(p_data, temp,height*wide); 
	}
	else		//24位彩色
	{
		wide=this->GetDibWidthBytes();
		temp=new BYTE[wide*height]; 
		memcpy(temp,p_data,wide*height);
		// 对各像素进行灰度转换
		for (i = 0; i < height; i ++)
		{
			for (j = 0; j < wide; j ++)
			{
				// 对像素进行灰度映射处理
				unsigned char T = temp[ wide * i + j];
				temp[ wide * i + j] = bMap[T];			 
			}
		}
		memcpy(p_data, temp,height*wide);
	}
}

///***************************************************************/           
/*函数名称:Chuangkoubianhuan(BYTE blow,BYTE bup)                                      
/*函数类型:void                                          
/*变量说明:blow窗口下界 bup窗口上界                                                               
/*功能:对图像进行窗口变换。                    
/***************************************************************/  
void HuiDuBianHuanDib::Chuangkoubianhuan(BYTE bLow, BYTE bUp)
{
    // 循环变量
	int i;
	int j;
	int wide,height;    //原图长、宽
	// 指向源图像的指针
	LPBYTE	lpSrc;
	// 指向DIB象素指针
	LPBYTE  p_data;
	p_data=this->GetData ();     //取得原图的数据区指针
	if (m_pBitmapInfoHeader->biBitCount<9)		
		wide=this->GetWidth ();
	else
		wide=this->GetDibWidthBytes();
	height=this->GetHeight ();
	// 对各像素进行灰度转换
	for(i = 0; i < height; i++)
	{
		// 每列
		for(j = 0; j < wide; j++)
		{
			// 指向DIB第i行,第j个象素的指针
			lpSrc = (LPBYTE)p_data + wide * (height- 1 - i) + j;
			// 判断是否超出范围
			if ((*lpSrc) < bLow)
			{
				// 直接赋值为0
				*lpSrc = 0;
			}
			else if ((*lpSrc) > bUp)
			{
				// 直接赋值为255
				*lpSrc = 255;
			}
		}
	}
}

///***************************************************************/           
/*函数名称:Fenbujunhenghua()                                           
/*函数类型:void                                          
/*变量说明:无                                                               
/*功能:对图像进行灰度分布均衡化处理。                   
/***************************************************************/  
void HuiDuBianHuanDib::Fenbujunhenghua( )
{	
	// 循环变量
	LONG i;
	LONG j;
	//图像的宽和高
	LONG wide;
	LONG height;
	// 灰度分布密度
	float fPs_R[256],fPs_G[256],fPs_B[256];
	// 中间变量
	float temp_r[256],temp_g[256],temp_b[256];
	int nNs_R[256],nNs_G[256],nNs_B[256];
	// 初始化
	memset(temp_r, 0, sizeof(temp_r));
	memset(temp_g, 0, sizeof(temp_g));
	memset(temp_b, 0, sizeof(temp_b));
	// 指向DIB象素指针
	LPBYTE p_data;
	// 找到DIB图像象素起始位置
	p_data = this->GetData();
	wide=this->GetWidth ();	
	// DIB的高度
	height = GetHeight();
	if(m_pBitmapInfoHeader->biBitCount<9)		//灰度图像
	{
		// 获取图像的灰度分布密度
		ZhiFangTu(fPs_R);
		// 进行均衡化处理 
		for(i = 0; i < 256; i++)
		{
			if(i == 0)
			{
				temp_r[0] = fPs_R[0];	 
			}
			else
			{
				temp_r[i] = temp_r[i-1] + fPs_R[i];	 
			}
			nNs_R[i] = (int)(255.0f * temp_r[i] + 0.5f);
		}
	}
	else		//24位彩色
	{
		// 获取图像的灰度分布密度
		ZhiFangTu(fPs_R,fPs_G,fPs_B);
		// 进行均衡化处理 
		for(i = 0; i < 256; i++)
		{
			if(i == 0)
			{
				temp_r[0] = fPs_R[0];
				temp_g[0] = fPs_G[0];
				temp_b[0] = fPs_B[0];
			}
			else
			{
				temp_r[i] = temp_r[i-1] + fPs_R[i];	
				temp_g[i] = temp_g[i-1] + fPs_G[i];	
				temp_b[i] = temp_b[i-1] + fPs_B[i];	
			}
			nNs_R[i] = (int)(255.0f * temp_r[i] + 0.5f);
			nNs_G[i] = (int)(255.0f * temp_g[i] + 0.5f);
			nNs_B[i] = (int)(255.0f * temp_b[i] + 0.5f);
		}
	}
	if (m_pBitmapInfoHeader->biBitCount<9)		//灰度图像
	{ 
		// 对各像素进行灰度转换
		for (j = 0; j < height; j ++)
		{
			for (i = 0; i < wide; i ++)
			{
				// 将转换后的灰度分布写入DIB图像
				unsigned char temp = *((unsigned char *)p_data + wide * j + i);
				*((unsigned char *)p_data + wide * j + i) = nNs_R[temp];			
			}
		}
	}
	else		//24位彩色
	{
		// 对各像素进行灰度转换
		for (j = 0; j < height; j ++)
		{
			for (i = 0; i < wide; i ++)
			{
				// 将转换后的灰度分布写入DIB图像
				unsigned char temp1= *((unsigned char *)p_data + wide * j*3 + i*3);
				*((unsigned char *)p_data + wide * j*3 + i*3) = nNs_R[temp1];
				unsigned char temp2 = *((unsigned char *)p_data + wide * j*3 + i*3+1);
				*((unsigned char *)p_data + wide * j*3 + i*3+1) = nNs_G[temp2];	
				unsigned char temp3 = *((unsigned char *)p_data + wide * j*3 + i*3+2);
				*((unsigned char *)p_data + wide * j*3 + i*3+2) = nNs_B[temp3];	
			}
		}
	}
}

int HuiDuBianHuanDib::GetWidth()
{
	return CDib::GetWidth();
}

///***************************************************************/           
/*函数名称:Pipeibianhuan(BYTE bNum,int *npNu,float*fpPu)                                            */
/*函数类型:void                                              */
/*变量说明:bNum规定直方图灰度级 npNu 直方图映射关系
/*          fpPu灰度分布概率                                                             
/*功能:对图像进行灰度匹配变换。                       */
/***************************************************************/  
void HuiDuBianHuanDib::Pipeibianhuan(BYTE bNum, int *npNu, float *fpPu)
{
	// 循环变量
	LONG i;
	LONG j;
    LONG wide;
	LONG height;
	// 灰度分布密度
	int midu[256],midu2[256],midu3[256];
	// 灰度分布概率
	float gailu[256],gailu2[256],gailu3[256];
	// 中间临时变量
	float temp[256],temp2[256],temp3[256];
	// 指向DIB象素指针
	LPBYTE p_data;
	// 找到DIB图像象素起始位置
	p_data = this->GetData();
	wide=this->GetWidth ();    
	// DIB的高度
	height = GetHeight(); 	
    if (m_pBitmapInfoHeader->biBitCount<9)		//灰度图像
	{   
		// 对灰度密度分布进行统计	
		Midufenbu(midu);
		// 对灰度分布概率进行统计
		ZhiFangTu(gailu);
		
		// 计算原始累计直方图
		for (i = 0; i < 256; i++)
		{
			if (i == 0)
			{
				temp[0] = gailu[0];			 
			}
			else
			{
				temp[i] = temp[i-1] + gailu[i];			 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -