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

📄 grayproc.cpp

📁 电子书《数字图像处理学》Visual C++实现 郎锐编写 所附源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// ************************************************************************
//  文件名:GrayProc.cpp
//
//  图像灰度处理函数库:
//
//  ToGray()				- 彩色位图转化为灰度位图
//	PointInvert()			- 对图像进行反色变换
//	GetIntensity()			- 对图像各颜色分量的灰度分布(数目、密度)进行统计
//	PointEqua()				- 对图像进行灰度分布均衡化处理
//  GrayStretch()			- 对图像进行灰度折线变换
//	WindowTrans()			- 对图像进行灰度窗口变换
//	PointDZ()				- 对图像进行灰度带阻变换
//	PointDT()				- 对图像进行灰度带通变换
//	PointSML()				- 对图像进行单映射规则直方图规定化变换
//	PointGML()				- 对图像进行组映射规则直方图规定化变换
//	DynamicCompress()		- 对图像进行灰度动态范围压缩处理 
//	CutWave()				- 对图像进行灰度削波处理 
//
// ************************************************************************

#include "stdafx.h"
#include "DIP_System.h"
#include "GrayProc.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGrayProc

CGrayProc::CGrayProc()
{
}

CGrayProc::~CGrayProc()
{
}


BEGIN_MESSAGE_MAP(CGrayProc, CWnd)
	//{{AFX_MSG_MAP(CGrayProc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


////////////////////////////////////////////////////////////////////////////
//							功能模块开始								  //
////////////////////////////////////////////////////////////////////////////


/*************************************************************************
 *
 * 函数名称:
 *   ToGray()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数将彩色位图转化为灰度图像。
 *
 ************************************************************************/

void CGrayProc::ToGray(HDIB hDIB)
{
	// 循环变量
	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 ++)
		{
			// 获取各颜色分量
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			j++;
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			j++;
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);

			// 计算灰度值
			unsigned char Y = (9798 * R + 19235 * G + 3735 * B) / 32768;
 
			// 回写灰度值
			*((unsigned char *)lpDIBBits + lLineBytes * i + j - 2) = Y;
			*((unsigned char *)lpDIBBits + lLineBytes * i + j - 1) = Y;
			*((unsigned char *)lpDIBBits + lLineBytes * i + j ) = Y;
		}
	}

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

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   PointInvert()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像进行反色变换处理
 *
 ************************************************************************/

void CGrayProc::PointInvert(HDIB hDIB)
{
	// 循环变量
	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 ++)
		{
			// 对像素各颜色分量进行反色处理
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 255 - R;
			j++;
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 255 - G;
			j++;
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 255 - B;
		}
	}

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

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   GetIntensity()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *	 int  *nNs_R		- 红色分量的灰度分布统计
 *   int  *nNs_G		- 绿色分量的灰度分布统计
 *   int  *nNs_B		- 蓝色分量的灰度分布统计
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像RGB分量进行灰度分布的统计
 *
 ************************************************************************/

void CGrayProc::GetIntensity(HDIB hDIB, int *nNs_R, int *nNs_G, int *nNs_B)
{
	// 循环变量
	LONG i;
	LONG j;

	//变量初始化
	memset(nNs_R,0,sizeof(int) * 256);
	memset(nNs_G,0,sizeof(int) * 256);
	memset(nNs_B,0,sizeof(int) * 256);

	// 指向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 ++)
		{
			// 对各像素进行灰度统计
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			nNs_R[R]++;		
			j++;
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			nNs_G[G]++;
			j++;
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			nNs_B[B]++;
		}
	}

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

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   GetIntensity()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *	 float *fPs_R		- 红色分量的灰度分布密度统计
 *   float *fPs_G		- 绿色分量的灰度分布密度统计
 *   float *fPs_B		- 蓝色分量的灰度分布密度统计
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像RGB分量进行灰度分布密度的统计
 *
 ************************************************************************/

void CGrayProc::GetIntensity(HDIB hDIB, float *fPs_R, float *fPs_G, float *fPs_B)
{
	// 循环变量
	LONG i;
	LONG j;

	// 灰度计数
	int nNs_R[256];
	int nNs_G[256];
	int nNs_B[256];

	// 变量初始化
	memset(nNs_R,0,sizeof(nNs_R));
	memset(nNs_G,0,sizeof(nNs_G));
	memset(nNs_B,0,sizeof(nNs_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();
	
	// 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 ++)
		{
			// 对各像素进行灰度统计
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			nNs_R[R]++;		
			j++;
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			nNs_G[G]++;
			j++;
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			nNs_B[B]++;
		}
	}

	// 计算灰度分布密度
	for(i=0;i<256;i++)
	{
		fPs_R[i] = nNs_R[i] / (lHeight * lWidth * 1.0f);
		fPs_G[i] = nNs_G[i] / (lHeight * lWidth * 1.0f);
		fPs_B[i] = nNs_B[i] / (lHeight * lWidth * 1.0f);
	}

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

	// 恢复光标
	EndWaitCursor();
}

	
/*************************************************************************
 *
 * 函数名称:
 *   GetIntensity()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *	 float *fPs_Y		- Y 分量的灰度分布密度统计
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像Y分量进行灰度分布密度的统计
 *
 ************************************************************************/

void CGrayProc::GetIntensity(HDIB hDIB, float *fPs_Y)
{
	// 循环变量
	LONG i;
	LONG j;

	// 灰度计数
	int nNs_Y[256];

	// 变量初始化
	memset(nNs_Y,0,sizeof(nNs_Y));

	// 指向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 ++)
		{
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			j++;
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			j++;
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);

			// 计算灰度值
			unsigned char Y = (9798 * R + 19235 * G + 3735 * B) / 32768;

			// 灰度统计计数
			nNs_Y[Y]++;		
		}
	}

	// 计算灰度分布密度
	for(i=0;i<256;i++)
		fPs_Y[i] = nNs_Y[i] / (lHeight * lWidth * 1.0f);

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

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   GetIntensity()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *	 int *nNs_Y			- Y 分量的灰度分布统计
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像Y分量进行灰度分布统计
 *
 ************************************************************************/

void CGrayProc::GetIntensity(HDIB hDIB, int *nNs_Y)
{
	// 循环变量
	LONG i;
	LONG j;

	// 变量初始化
	memset(nNs_Y, 0, sizeof(nNs_Y));

	// 指向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 ++)
		{
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			j++;
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			j++;
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);

			// 计算灰度值
			unsigned char Y = (9798 * R + 19235 * G + 3735 * B) / 32768;

			// 灰度统计计数
			nNs_Y[Y]++;		
		}
	}

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

	// 恢复光标
	EndWaitCursor();
}

/*************************************************************************
 *
 * 函数名称:
 *   PointEqua()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图像进行灰度分布均衡化处理
 *
 ************************************************************************/

void CGrayProc::PointEqua(HDIB hDIB)
{
	// 循环变量
	LONG i;
	LONG j;

⌨️ 快捷键说明

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