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

📄 grayproc.cpp

📁 电子书《数字图像处理学》Visual C++实现 郎锐编写 所附源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	// 灰度分布密度
	float fPs_R[256];
	float fPs_G[256];
	float fPs_B[256];

	// 中间变量
	float temp_r[256];
	float temp_g[256];
	float temp_b[256];

	int nNs_R[256];
	int nNs_G[256];
	int 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 lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 锁定DIB
	lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);

	// 找到DIB图像象素起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
	
	// 判断是否是24-bpp位图
	if (m_clsDIB.DIBBitCount(lpDIB) != 24)
	{
		// 提示用户
		MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
		
		// 解除锁定 
		::GlobalUnlock((HGLOBAL) hDIB);
		
		// 返回 
		return;
	}	
	
	// 更改光标形状
	BeginWaitCursor();
	
	// 获取图像的灰度分布密度
	GetIntensity(hDIB, 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);
	}

	// DIB的宽度
	LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
	
	// DIB的高度
	LONG lHeight = m_clsDIB.DIBHeight(lpDIB);

	// 计算图像每行的字节数
	LONG lLineBytes = WIDTHBYTES(lWidth * 24);

	// 对各像素进行灰度转换
	for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lLineBytes; j ++)
		{
			// 将搬移后的灰度分布写入DIB图像
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = nNs_R[R];
			j++;
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = nNs_G[G];
			j++;
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = nNs_B[B];
		}
	}

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   GrayStretch()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *	 BYTE bX1			- 折点一的原始灰度
 *	 BYTE bY1			- 折点一的变换灰度
 *	 BYTE bX2			- 折点二的原始灰度
 *   BYTE bY2			- 折点二的对应灰度
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像进行灰度折线变换
 *
 ************************************************************************/

void CGrayProc::GrayStretch(HDIB hDIB, BYTE bX1, BYTE bY1, BYTE bX2, BYTE bY2)
{
	// 循环变量
	LONG i;
	LONG j;

	// 指向DIB的指针 
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;

	// 锁定DIB
	lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);

	// 找到DIB图像象素起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
	
	// 判断是否是24-bpp位图
	if (m_clsDIB.DIBBitCount(lpDIB) != 24)
	{
		// 提示用户
		MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
		
		// 解除锁定
		::GlobalUnlock((HGLOBAL) hDIB);
		
		// 返回
		return;
	}
	
	// 更改光标形状
	BeginWaitCursor();
	
	// DIB的宽度
	LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
	
	// DIB的高度
	LONG lHeight = m_clsDIB.DIBHeight(lpDIB);

	// 计算图像每行的字节数
	LONG lLineBytes = WIDTHBYTES(lWidth * 24);

	// 灰度映射表
	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;
		}
	}
	
	// 对各像素进行灰度转换
	for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lLineBytes; j ++)
		{
			// 对像素各颜色分量进行灰度映射处理
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = bMap[R];
			j++;
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = bMap[G];
			j++;

			// 在此如用lWidth * 3则有彩色效果,如用lLineBytes则为普通灰度处理
			unsigned char B = *((unsigned char *)lpDIBBits + lWidth * 3 * i + j);
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = bMap[B];
		}
	}

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   WindowTrans()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *	 BYTE bLow			- 窗口下界
 *	 BYTE bUp			- 窗口上界
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像进行灰度窗口变换
 *
 ************************************************************************/

void CGrayProc::WindowTrans(HDIB hDIB, BYTE bLow, BYTE bUp)
{
	// 循环变量
	LONG i;
	LONG j;

	// 指向DIB的指针
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 锁定DIB
	lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);

	// 找到DIB图像象素起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
	
	// 判断是否是24-bpp位图
	if (m_clsDIB.DIBBitCount(lpDIB) != 24)
	{
		// 提示用户
		MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
		
		// 解除锁定
		::GlobalUnlock((HGLOBAL) hDIB);
		
		// 返回
		return;
	}
	
	// 更改光标形状
	BeginWaitCursor();
	
	// DIB的宽度
	LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
	
	// DIB的高度
	LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
	
	// 计算图像每行的字节数
	LONG lLineBytes = WIDTHBYTES(lWidth * 24);

	// 对各像素进行灰度转换
	for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lLineBytes; j ++)
		{
			// 读取像素R分量
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断R分量是否超出范围
			if (R < bLow)
			{
				// 直接赋值为0
				R = 0;
			}
			else if (R > bUp)
			{
				// 直接赋值为255
				R = 255;
			}
			
			// 回写处理完的R分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = R;
			j++;

			// 读取像素G分量
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断G分量是否超出范围
			if (G < bLow)
			{
				// 直接赋值为0
				G = 0;
			}
			else if (G > bUp)
			{
				// 直接赋值为255
				G = 255;
			}
			
			// 回写处理完的G分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = G;
			j++;

			// 读取像素B分量
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断B分量是否超出范围
			if (B < bLow)
			{
				// 直接赋值为0
				B = 0;
			}
			else if (B > bUp)
			{
				// 直接赋值为255
				B = 255;
			}
			
			// 回写处理完的B分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = B;
		}
	}

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   PointDZ()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *	 BYTE bLow			- 窗口下界
 *	 BYTE bUp			- 窗口上界
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像进行灰度带阻变换
 *
 ************************************************************************/

void CGrayProc::PointDZ(HDIB hDIB, BYTE bLow, BYTE bUp)
{
	// 循环变量
	LONG i;
	LONG j;

	// 指向DIB的指针
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 锁定DIB
	lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);

	// 找到DIB图像象素起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
	
	// 判断是否是24-bpp位图
	if (m_clsDIB.DIBBitCount(lpDIB) != 24)
	{
		// 提示用户
		MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
		
		// 解除锁定
		::GlobalUnlock((HGLOBAL) hDIB);
		
		// 返回
		return;
	}
	
	// 更改光标形状
	BeginWaitCursor();
	
	// DIB的宽度
	LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
	
	// DIB的高度
	LONG lHeight = m_clsDIB.DIBHeight(lpDIB);

	// 计算图像每行的字节数
	LONG lLineBytes = WIDTHBYTES(lWidth * 24);

	// 对各像素进行灰度转换
	for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lLineBytes; j ++)
		{
			// 读取像素R分量
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断R分量是否超出范围
			if (R < bLow || R > bUp)
			{
				// 直接赋值为255
				R = 255;
			}
			
			// 回写处理完的R分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = R;
			j++;

			// 读取像素G分量
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断G分量是否超出范围
			if (G < bLow || G > bUp)
			{
				// 直接赋值为255
				G = 255;
			}
		
			// 回写处理完的G分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = G;
			j++;

			// 读取像素B分量
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断B分量是否超出范围
			if (B < bLow || B > bUp)
			{
				// 直接赋值为255
				B = 255;
			}
			
			// 回写处理完的B分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = B;
		}
	}

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   PointDT()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *	 BYTE bLow			- 窗口下界
 *	 BYTE bUp			- 窗口上界
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像进行灰度带通变换
 *
 ************************************************************************/

void CGrayProc::PointDT(HDIB hDIB, BYTE bLow, BYTE bUp)
{
	// 循环变量
	LONG i;
	LONG j;

	// 指向DIB的指针
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 锁定DIB
	lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);

	// 找到DIB图像象素起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
	
	// 判断是否是24-bpp位图
	if (m_clsDIB.DIBBitCount(lpDIB) != 24)
	{
		// 提示用户
		MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
		
		// 解除锁定
		::GlobalUnlock((HGLOBAL) hDIB);
		
		// 返回
		return;
	}
	
	// 更改光标形状
	BeginWaitCursor();
	
	// DIB的宽度
	LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
	
	// DIB的高度
	LONG lHeight = m_clsDIB.DIBHeight(lpDIB);

	// 计算图像每行的字节数
	LONG lLineBytes = WIDTHBYTES(lWidth * 24);
	
	// 对各像素进行灰度转换
	for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lLineBytes; j ++)
		{
			// 读取像素R分量
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断R分量是否超出范围
			if (R < bLow || R > bUp)
			{
				// 直接赋值为0
				R = 0;
			}
			
			// 回写处理完的R分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = R;
			j++;

			// 读取像素G分量
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断G分量是否超出范围
			if (G < bLow || G > bUp)
			{
				// 直接赋值为0
				G = 0;
			}
		
			// 回写处理完的G分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = G;
			j++;

			// 读取像素B分量
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断B分量是否超出范围
			if (B < bLow || B > bUp)
			{
				// 直接赋值为0
				B = 0;
			}
			
			// 回写处理完的B分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = B;
		}
	}

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   PointSML()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *	 BYTE bNum			- 规定直方图灰度级数
 *	 int* npNu			- 规定直方图灰度映射关系
 *	 float* fpPu		- 规定直方图各灰度的分布概率
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像进行单映射规则直方图规定化变换
 *
 ************************************************************************/

void CGrayProc::PointSML(HDIB hDIB, BYTE bNum, int *npNu, float *fpPu)
{
	// 循环变量
	LONG i;
	LONG j;

	// 灰度分布密度

⌨️ 快捷键说明

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