📄 grayprocess.cpp
字号:
/////////////////////////////////////////////////////////////////////////////////
//
// GrayProcess.cpp: implementation of the CGrayProcess class.
//
////////////////////////////////////////////////////////////////////////////////
// 版权所有(2002)
// Copyright(2002)
// 编写者: 向世明
// Author: Xiang Shiming
#include "stdafx.h"
#include "GrayProcess.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CGrayProcess, CImagePointProcess)
CGrayProcess::CGrayProcess()
{
//缺省操作
m_dwOperation = IMAGE_GRAY_COLOR_GRAYED_OUT;
//灰度比例化百分比
m_nPercentage = 100;
//灰度线性变换的四个区间参数
m_byA = 0;
m_byB = 255;
m_byC = 0;
m_byD = 255;
//给定与之匹配的灰度频数
m_pnMatchFreq = NULL;
//原图像的灰度数学期望(expectation)
m_nExpSrc = 128;
//目标图像的灰度数学期望
m_nExpDst = 128;
}
CGrayProcess::~CGrayProcess()
{
}
#ifdef _DEBUG
void CGrayProcess::Dump(CDumpContext& dc) const
{
CImagePointProcess::Dump(dc);
}
void CGrayProcess::AssertValid() const
{
CImagePointProcess::AssertValid();
}
#endif
//设置一个int
void CGrayProcess::SetParam1i(int nPercentage)
{
m_nPercentage = nPercentage;
}
//设置4个BYTE
void CGrayProcess::SetParam4by(BYTE bya, BYTE byb, BYTE byc, BYTE byd)
{
m_byA = bya;
m_byB = byb;
m_byC = byc;
m_byD = byd;
if(m_byA > m_byB)
{
BYTE byTemp = m_byA;
m_byA = m_byB;
m_byB = byTemp;
}
if(m_byC > m_byD)
{
BYTE byTemp = m_byC;
m_byC = m_byD;
m_byD = byTemp;
}
}
//设置目标直方图,
//保证 pnMatch 的长度不小于 256
void CGrayProcess::SetParam1iv(const int* pnMatch)
{
if(m_pnMatchFreq) delete[] m_pnMatchFreq;
else
m_pnMatchFreq = new int[256];
for(int i = 0; i < 256; i++)
m_pnMatchFreq[i] = pnMatch[i];
}
//nExpDst目标期望
//nRatioVarPer方差比值(百分值)
//nRatioVarPer = (int)((varSrc / varDst) * 100);
void CGrayProcess::SetParam2i(int nExpDst, int nRatioVarPer)
{
m_nExpDst = nExpDst;
m_nPercentage = nRatioVarPer;
}
BOOL CGrayProcess::MakeGray(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight)
{
ASSERT(lpbyBits32);
BOOL bSucessfully = TRUE;
switch(m_dwOperation)
{
case IMAGE_GRAY_COLOR_GRAYED_OUT:
case IMAGE_GRAY_PERCENTAGE:
case IMAGE_GRAY_LINEARIZE:
case IMAGE_GRAY_LINEAR_ROUND_OFF:
case IMAGE_GRAY_REVERSE:
{
bSucessfully = MakeLinearGray(lpbyBits32, x, y, nWidth, nHeight, nScanWidth, nScanHeight);
break;
}
case IMAGE_GRAY_HISTOGRAM_BALANCE:
{
bSucessfully = MakeHistogramBalance(lpbyBits32, x, y, nWidth, nHeight, nScanWidth, nScanHeight);
break;
}
case IMAGE_GRAY_HISTOGRAM_MATCH:
{
bSucessfully = MakeHistogramMatch(lpbyBits32, x, y, nWidth, nHeight, nScanWidth, nScanHeight);
break;
}
case IMAGE_GRAY_STATISTIC_MATCH:
{
bSucessfully = MakeStatisticMatch(lpbyBits32, x, y, nWidth, nHeight, nScanWidth, nScanHeight);
break;
}
default : break;
}
return bSucessfully;
}
BOOL CGrayProcess::MakeLinearGray(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight)
{
ASSERT(lpbyBits32);
//第一步, 进行参数合法性检测
if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
//有效区域的宽度和高度
int w = min(nWidth, nScanWidth - x);
int h = min(nHeight, nScanHeight - y);
//行字节数
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
//开始数据基索引
DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
//区间长度
BYTE b_a = m_byB - m_byA; // b - a
BYTE d_c = m_byD - m_byC; // d - c
if(b_a == 0)b_a = 1;
if(d_c == 0)d_c = 1;
//第二步, 灰度修改
for(int i = 0;i < h;i++)
{
BYTE* pbyRsc = lpbyBits32 + dwBaseIndex;
for(int j = 0;j < w;j++)
{
//第一小步, 获取指针
BYTE* pbyBlue = pbyRsc++;
BYTE* pbyGreen = pbyRsc++;
BYTE* pbyRed = pbyRsc++;
pbyRsc++;
//第二小步, 获取值;
BYTE r = *pbyRed;
BYTE g = *pbyGreen;
BYTE b = *pbyBlue;
BYTE gray = (BYTE)(((WORD)r * 30 + (WORD)g * 59 + (WORD)b * 11) / 100);
//第三小步, 处理单个像素值
switch(m_dwOperation)
{
//将彩色转换为灰度图像
case IMAGE_GRAY_COLOR_GRAYED_OUT:
{
*pbyBlue = gray;
*pbyGreen = gray;
*pbyRed = gray;
break;
}
//灰度比例化
case IMAGE_GRAY_PERCENTAGE:
{
int nScale = ((int)gray * m_nPercentage) / 100;
BYTE byResult = (BYTE)BOUND(nScale, 0, 255);
*pbyBlue = byResult;
*pbyGreen = byResult;
*pbyRed = byResult;
break;
}
//灰度线性化:
case IMAGE_GRAY_LINEARIZE:
{
BYTE byResult = gray;
if((gray >= m_byA) && (gray <= m_byB))
byResult = (BYTE)((((WORD)d_c * (WORD)(gray - m_byA)) / (WORD)b_a) + m_byC);
*pbyBlue = byResult;
*pbyGreen = byResult;
*pbyRed = byResult;
break;
}
//灰度线性截断
case IMAGE_GRAY_LINEAR_ROUND_OFF:
{
BYTE byResult = gray;
if(gray <= m_byA)byResult = m_byC;
else if(gray >= m_byB)byResult = m_byD;
else
byResult = (BYTE)((((WORD)d_c * (WORD)(gray - m_byA)) / (WORD)b_a) + m_byC);
*pbyBlue = byResult;
*pbyGreen = byResult;
*pbyRed = byResult;
break;
}
//灰度取反
case IMAGE_GRAY_REVERSE:
{
BYTE byResult = 255 - gray;
*pbyBlue = byResult;
*pbyGreen = byResult;
*pbyRed = byResult;
break;
}
default:break;
}
}
dwBaseIndex += dwWidthBytes;
}
return TRUE;
}
BOOL CGrayProcess::MakeHistogramBalance(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight)
{
ASSERT(lpbyBits32);
//第一步, 进行参数合法性检测
if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
//有效区域的宽度和高度
int w = min(nWidth, nScanWidth - x);
int h = min(nHeight, nScanHeight - y);
if(w * h == 0)return FALSE;
//第二步, 灰度统计
//行字节数
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
//开始数据基索引
DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
//子区域像素个数
DWORD dwPixelSize = w * h;
int i = 0;
int j = 0;
//开辟一个内存区, 记录指定区域的灰度值
//存放被处理的子区域的灰度
BYTE* pbyGraySubArea = new BYTE[dwPixelSize];
if(pbyGraySubArea == NULL) return FALSE;
//定义一个数组, 大小为256, 记录256级灰度出现的频数
DWORD adwFreqSrc[256];
for(i = 0;i < 256;i++)adwFreqSrc[i] = 0;
BYTE* pbyGrayCopy = pbyGraySubArea;
for(i = 0;i < h;i++)
{
BYTE* pbyRsc = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
BYTE b = *pbyRsc++;
BYTE g = *pbyRsc++;
BYTE r = *pbyRsc++;
pbyRsc++;
BYTE gray = (BYTE)(((WORD)r * 30 + (WORD)g * 59 + (WORD)b * 11) / 100);
adwFreqSrc[gray]++;
*pbyGrayCopy++ = gray;
}
dwBaseIndex += dwWidthBytes;
}
//完成频率统计工作
//将频数(Frequencies)进行累加
DWORD adwAccumuSrc[256];
adwAccumuSrc[0] = adwFreqSrc[0];
for(i = 1; i < 256; i++)
adwAccumuSrc[i] = adwAccumuSrc[i - 1] + adwFreqSrc[i];
//最后记录均衡后的灰度, 明显地, 其等级少于256或灰度得到提高
for(i = 0; i < 256; i++)
adwAccumuSrc[i] = ((adwAccumuSrc[i] * 255) / dwPixelSize);
//第三步, 灰度修改
//重新开始
dwBaseIndex = y * dwWidthBytes + 4 * x;
pbyGrayCopy = pbyGraySubArea;
for(i = 0;i < h;i++)
{
BYTE* pbyRsc = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
//原像素的灰度
BYTE byGraySrc = *pbyGrayCopy++;
//原像素的最终灰度
BYTE byGrayDst = (BYTE)adwAccumuSrc[byGraySrc];
*pbyRsc++ = byGrayDst;
*pbyRsc++ = byGrayDst;
*pbyRsc++ = byGrayDst;
pbyRsc++;
}
dwBaseIndex += dwWidthBytes;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -