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

📄 grayprocess.cpp

📁 visual c++数字图像与图形处理中的光盘内容
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////////
//
// 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 + -