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

📄 huidubianhuandib.cpp

📁 < VC++图像处理程程序设计>>配套光盘,这是第4章的灰度变换的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			}
			gailu[i] = temp[i];
		}
		// 计算规定累计直方图
		for (i = 0; i < bNum; i++)
		{
			if (i == 0)
			{
				temp[0] = fpPu[0];
			}
			else
			{
				temp[i] = temp[i-1] + fpPu[i];
			}
			fpPu[i] = temp[i];
		}
		// 确定映射对应关系
		for (i = 0; i < 256; i++)
		{
			// 最接近的规定直方图灰度级
			int m_r = 0;
			// 最小差值
			float min_value_r = 1.0f;
			// 对规定直方图各灰度进行枚举
			for (j = 0; j < bNum; j++)
			{
				// 当前差值
				float now_value = 0.0f;
				//  计算差值
				if (gailu[i] - fpPu[j] >= 0.0f)
					now_value = gailu[i] - fpPu[j];
				else
					now_value = fpPu[j] - gailu[i];
				// 寻找最接近的规定直方图灰度级
				if (now_value < min_value_r)
				{
					// 最接近的灰度级
					m_r = j;
					// 暂存最小差值
					min_value_r = now_value;
				}
			}
			// 建立灰度映射表
			midu[i] = npNu[m_r];
		}
		// 对各像素进行处理
		for (j = 0; j < height; j ++)
		{
			for (i = 0; i < wide; i ++)
			{
				// 对像素进行单映射规则的直方图规定化映射处理
				unsigned char temp = *((unsigned char *)p_data + wide * j + i);
				*((unsigned char *)p_data + wide * j + i) = midu[temp];
			}
		}
	}
	else		//24位彩色
	{
		// 对灰度密度分布进行统计	
		Midufenbu(midu,midu2,midu3);
		// 对灰度分布概率进行统计
		ZhiFangTu(gailu,gailu2,gailu3);
		
		// 计算原始累计直方图
		for (i = 0; i < 256; i++)
		{
			if (i == 0)
			{
				temp[0] = gailu[0];	
				temp2[0] = gailu2[0];
				temp3[0] = gailu3[0];
			}
			else
			{
				temp[i] = temp[i-1] + gailu[i];
				temp2[i] = temp2[i-1] + gailu2[i];	
				temp3[i] = temp3[i-1] + gailu3[i];	
			}
			gailu[i] = temp[i];
			gailu2[i] = temp2[i];
			gailu3[i] = temp3[i];
			
		}
		// 计算规定累计直方图
		for (i = 0; i < bNum; i++)
		{
			if (i == 0)
			{
				temp[0] = fpPu[0];			
			}
			else
			{
				temp[i] = temp[i-1] + fpPu[i];
			}
			fpPu[i] = temp[i];
		}
		// 确定映射对应关系
		for (i = 0; i < 256; i++)
		{
			// 最接近的规定直方图灰度级
			int m_r = 0;
			int m_g = 0;
			int m_b = 0;		 		
			// 最小差值
			float min_value_r = 1.0f;
			float min_value_g = 1.0f;
			float min_value_b = 1.0f;
			// 对规定直方图各灰度进行枚举
			for (j = 0; j < bNum; j++)
			{
				// 当前差值
				float now_value = 0.0f;
				//  计算差值
				if (gailu[i] - fpPu[j] >= 0.0f)
					now_value = gailu[i] - fpPu[j];
				else
					now_value = fpPu[j] - gailu[i];
				// 寻找最接近的规定直方图灰度级
				if (now_value < min_value_r)
				{
					// 最接近的灰度级
					m_r = j;
					// 暂存最小差值
					min_value_r = now_value;
				}
				//  计算差值
				if (gailu2[i] - fpPu[j] >= 0.0f)
					now_value = gailu2[i] - fpPu[j];
				else
					now_value = fpPu[j] - gailu2[i];
				// 寻找最接近的规定直方图灰度级
				if (now_value < min_value_g)
				{
					// 最接近的灰度级
					m_g = j;
					// 暂存最小差值
					min_value_g = now_value;
				}
				//  计算差值
				if (gailu3[i] - fpPu[j] >= 0.0f)
					now_value = gailu3[i] - fpPu[j];
				else
					now_value = fpPu[j] - gailu3[i];
				// 寻找最接近的规定直方图灰度级
				if (now_value < min_value_b)
				{
					// 最接近的灰度级
					m_b = j;
					// 暂存最小差值
					min_value_b = now_value;
				}
			}
			// 建立灰度映射表
			midu[i] = npNu[m_r];
			midu2[i] = npNu[m_g];
			midu3[i] = npNu[m_b];
		}
		// 对各像素进行处理
		for (j = 0; j < height; j ++)
		{
			for (i = 0; i < wide; i ++)
			{
				// 对像素进行单映射规则的直方图规定化映射处理
				unsigned char temp = *((unsigned char *)p_data + wide * j*3 + i*3);
				*((unsigned char *)p_data + wide * j*3 + i*3) = midu[temp];
				unsigned char temp2 = *((unsigned char *)p_data + wide * j*3 + i*3+1);
				*((unsigned char *)p_data + wide * j*3 + i*3+1) = midu[temp2];
				unsigned char temp3 = *((unsigned char *)p_data + wide * j*3 + i*3+2);
				*((unsigned char *)p_data + wide * j*3 + i*3+2) = midu[temp3];
			}
		}
	}
}

///***************************************************************/           
/*函数名称:Midufenbu()                                        
/*函数类型:void                                      
/*功能:对图像进行密度分布变换。            
/***************************************************************/  
void HuiDuBianHuanDib::Midufenbu(int *nNs_R)
{
	// 循环变量
	LONG i;
	LONG j;
	
	LONG wide;
	LONG height;
	//变量初始化
	memset(nNs_R,0,sizeof(int) * 256);
	// 指向DIB象素指针
	LPBYTE p_data;
	// 找到DIB图像象素起始位置
	p_data = this->GetData();		
    wide=this->GetWidth ();
	// DIB的高度
	height = GetHeight();
	// 对各像素进行灰度转换
	for (j = 0; j < height; j ++)
	{
		for (i = 0; i <wide; i ++)
		{
			// 对各像素进行灰度统计
			unsigned char temp = *((unsigned char *)p_data + wide * j + i);
			nNs_R[temp]++;		
		}
	} 
}

///***************************************************************/           
/*函数名称:Shuipingtouying()                                        
/*函数类型:void                                      
/*功能:对图像进行水平投影。            
/***************************************************************/  
void HuiDuBianHuanDib::Shuipingtouying()
{
	LPBYTE  p_data, p_datatemp;     //原图数据区指针
	int wide,height;				//原图长、宽
	int i,j;						//循环变量
	int lBlackNum  ;
	p_datatemp=this->GetData();
	p_data=p_datatemp;
	if(m_pBitmapInfoHeader->biBitCount<9)		
		wide=this->GetWidth ();
	else
		wide=this->GetDibWidthBytes();
	height=this->GetHeight ();
	//对图像进行二值化
	for(j=0;j<height;j++)
	{
		for(i=0;i<wide;i++)
		{ 
			if (*p_data>128)
				*p_data=255;
			else *p_data=0;
			p_data++;
		}
	}
	p_data=p_datatemp; 
	LPBYTE   temp=new BYTE[wide*height];    //新图像缓冲区
	memset( temp,255,wide*height);			//设定新图像初值为255
	for(j=0;j<height;j++)
	{
		lBlackNum=0;
		for(i=0;i<wide;i++)
		{				 
			if(p_data[wide*j+i]==0)
				lBlackNum++;
		}
		for(i=0;i<lBlackNum;i++)
			temp[wide*j+i]=0;
	}
	memcpy(p_data, temp,wide*height);
	delete  temp;	
}

///***************************************************************/           
/*函数名称:Chuizhitouying()                                      
/*函数类型:void                                      
/*功能:对图像进行垂直投影。            
/***************************************************************/  
void HuiDuBianHuanDib::Chuizhitouying()
{
	LPBYTE  p_data, p_datatemp;     //原图数据区指针
	int wide,height;				//原图长、宽
	int i,j;						//循环变量
	long int lBlackNum;				//图像中每行内黑点的个数
	p_datatemp=this->GetData();
	p_data=p_datatemp;
	if(m_pBitmapInfoHeader->biBitCount<9)	
		wide=this->GetWidth ();
	else
		wide=this->GetDibWidthBytes();
	height=this->GetHeight ();
	//对图像进行二值化
	for(j=0;j<height;j++)
	{
		for(i=0;i<wide;i++)
		{ 
			if (*p_data>128)
				*p_data=255;
			else 
				*p_data=0;
			p_data++;
		}
	}
	p_data=p_datatemp;
	LPBYTE  temp=new BYTE[wide*height];		//新图像缓冲区
	memset( temp,255,wide*height);			//设定新图像初值为255
	for(i=0;i<wide;i++)
	{
		lBlackNum=0;
		for(j=0;j<height;j++)
		{
			
			if(p_data[wide*j+i]==0)
				lBlackNum++;
		}
		for(j=0;j<lBlackNum;j++)
			temp[wide*j+i]=0;
	}
	memcpy(p_data, temp,wide*height);
	delete  temp;		
}

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

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

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

//对24位彩色图像进行灰度概率统计
void HuiDuBianHuanDib::ZhiFangTu(float *tongji1, float *tongji2, float *tongji3)
{
	// 循环变量
	int i;
	int j;
	// 灰度计数
	int huidu1[256],huidu2[256],huidu3[256];    
	int wide,height;    //原图长、宽
	wide=this->GetWidth ();		 
	height=this->GetHeight ();
	// 变量初始化
	memset(huidu1,0,sizeof(huidu1));
	memset(huidu2,0,sizeof(huidu2));
	memset(huidu3,0,sizeof(huidu3));		  
	LPBYTE  temp_pData=new BYTE[wide*height*3];    //新图像缓冲区
	//拷贝原图像到缓存图像
	memcpy(temp_pData,m_pData,wide*height*3);
	// 对各像素进行灰度统计
	for (j = 0; j < height; j ++)
	{
		for (i = 0; i <wide; i ++)
		{
			unsigned char  temp1 = temp_pData[wide*j*3 + i*3] ;
			unsigned char  temp2 = temp_pData[wide*j*3 + i*3+1] ;
			unsigned char  temp3 = temp_pData[wide*j *3+ i*3+2] ;
			// 灰度统计计数
			huidu1[temp1]++;
			huidu2[temp2]++;
			huidu3[temp3]++;
		}
	}
	// 计算灰度分布密度
	for(i=0;i<256;i++)
	{
		tongji1[i] = huidu1[i] / (height * wide *1.0f);	
		tongji2[i] = huidu2[i] / (height * wide *1.0f);	
		tongji3[i] = huidu3[i] / (height * wide *1.0f);	
	}
}

void HuiDuBianHuanDib::Midufenbu(int *nNs_R, int *nNs_G, int *nNs_B)
{
    // 循环变量
	LONG i;
	LONG j;
	LONG wide;
	LONG height;
	//变量初始化
	memset(nNs_R,0,sizeof(int) * 256);
	memset(nNs_G,0,sizeof(int) * 256);
	memset(nNs_B,0,sizeof(int) * 256);
	// 指向DIB象素指针
	LPBYTE p_data;
	// 找到DIB图像象素起始位置
	p_data = this->GetData();		
    wide=this->GetWidth ();
	// DIB的高度
	height = GetHeight();
	// 对各像素进行灰度转换
	for (j= 0;j < height;j ++)
	{
		for (i = 0; i <wide; i ++)
		{
			// 对各像素进行灰度统计
			unsigned char temp = *((unsigned char *)p_data + wide * j*3 + i*3);
			unsigned char temp2 = *((unsigned char *)p_data + wide * j*3 + i*3+1);
			unsigned char temp3 = *((unsigned char *)p_data + wide * j*3 + i*3+2);
			nNs_R[temp]++;		
			nNs_G[temp2]++;
			nNs_B[temp3]++;
		}
	} 
}

⌨️ 快捷键说明

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