📄 grayproc.cpp
字号:
// ************************************************************************
// 文件名: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 + -