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

📄 grayprocess.cpp

📁 vc++6.0编译的一个程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	//定义一个数组, 大小为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;
	}

	delete[] pbyGraySubArea;
	return TRUE;
}

//直方图规定化, 应用步骤:
//第一, 给定灰度出现的频数, 采用成员函数设定灰度频数, 灰度级必须为256级
//第二, 进行灰度直方图规定化
BOOL CGrayProcess::MakeHistogramMatch(LPBYTE lpbyBits32,  int x,  int y,  int nWidth,  int nHeight,  int nScanWidth,  int nScanHeight)
{
	ASSERT(lpbyBits32);
	//第一步, 进行参数合法性检测
	if(m_pnMatchFreq == NULL) return FALSE;
	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;
	}
	
	//完成频率统计工作

	//将频数进行累加
	DWORD adwAccumSrc[256];
	adwAccumSrc[0] = adwFreqSrc[0];
	for(i = 1; i < 256; i++)
		adwAccumSrc[i] = adwAccumSrc[i - 1] + adwFreqSrc[i];
	
	//最后记录均衡后的灰度, 明显地, 其等级少于256或灰度得到提高
	for(i = 0; i < 256; i++)
		adwAccumSrc[i] = ((adwAccumSrc[i] * 255) / dwPixelSize);
	
	//第三步, 建立映射.

	//首先, 累积规定的频数, 从而获得规定的直方图
	DWORD adwAccumDst[256];
	adwAccumDst[0] = (DWORD)m_pnMatchFreq[0];
	for(i = 1; i < 256; i++)
		adwAccumDst[i] = adwAccumDst[i - 1] + (DWORD)m_pnMatchFreq[i];
	if(adwAccumDst[255] == 0)adwAccumDst[255] = 1;
	for(i = 0; i < 255; i++)
		adwAccumDst[i] = ((adwAccumDst[i] * 255) / adwAccumDst[255]);
	adwAccumDst[255] = 255;

	//建立映射:----一个逆过程
	adwAccumSrc[0] = SearchBinary((int*)adwAccumDst, adwAccumSrc[0], 0, 255);
	
	//优化的快速查找方法
	for(i = 1;i < 256;i++)
		adwAccumSrc[i] = SearchBinary((int*)adwAccumDst, adwAccumSrc[i], adwAccumSrc[i - 1], 255);
		
	//第四步, 灰度修改
	//重新开始
	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)adwAccumSrc[byGraySrc];

			*pbyRsc++ = byGrayDst;
			*pbyRsc++ = byGrayDst;
			*pbyRsc++ = byGrayDst;
			pbyRsc++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	delete[] pbyGraySubArea;

	return TRUE;
}

//邻近二分查找, 返回最近索引
//nValue----待查找的值
//nStart----开始序号
//nEnd-----结束序号
int CGrayProcess::SearchBinary(const int* pnArray,  int nValue, int nStart, int nEnd)
{
	ASSERT(pnArray);

	int nLength = nEnd - nStart + 1;
	if(nLength == 1)return nStart;
	else if(nLength == 2)
	{
		if(nValue <= pnArray[nStart]) return nStart;
		else if(nValue >= pnArray[nStart + 1])return (nStart + 1);
		else
		{
			if((nValue - pnArray[nStart]) < (pnArray[nStart + 1] - nValue)) 
				return nStart;
			else 
				return (nStart + 1);
		}
	}
	//nLength >= 3
	else	
	{
		//区间右端点
		int nRight = nEnd;
		//区间左端点
		int nLeft = nStart;		

	
		//小于等于左端点的值
		if(nValue <= pnArray[nLeft]) return nLeft;
		//大于等于右端点的值
		if(nValue >= pnArray[nRight]) return nRight;
		
		nRight--;
		nLeft++;

		//区间中点
		int nMiddle = (nRight + nLeft) / 2;

		//是否发现适度的区间
		BOOL bFound = FALSE;
		
		//返回值
		int nReturn = -1;

		//待查找之数一定在[nLeft - 1, nRight + 1]区间内
		while(!bFound && (nRight >= nLeft))
		{
			//equal to the middle
			if(nValue == pnArray[nMiddle])
			{
				bFound = TRUE;
				nReturn = nMiddle;
			}
			else if(nValue < pnArray[nMiddle])
			{
				//找到了
				if(nValue >= pnArray[nMiddle - 1])
				{
					bFound = TRUE;
					//比较
					if((nValue - pnArray[nMiddle - 1]) < (pnArray[nMiddle] - nValue))
						nReturn = nMiddle - 1;
					else
						nReturn = nMiddle;
				}
				//没有找到, 不在该区间
				else
					nRight = nMiddle - 1;
			}

			//nValue > pnArray[middle]
			else
			{
				//找到了
				if(nValue < pnArray[nMiddle + 1])
				{
					bFound = TRUE;
					//比较
					if((nValue - pnArray[nMiddle]) < (pnArray[nMiddle + 1] - nValue))
						nReturn = nMiddle;
					else
						nReturn = (nMiddle + 1);
				}
				
				//没有找到, 不在该区间
				else
					nLeft = nMiddle + 1;
			}//nValue >= pnArray[middle]
			nMiddle = (nRight + nLeft) / 2;
		
		}//end -- while
		
		return nReturn;
	}// end -- else -- nLength >= 3
}

//按Wallis and Jong-Sen Lee的方法计算数学期望
int CGrayProcess::GetGrayExpectation(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;

	//数学期望累积
	int nGrayExpSum = 0;
	for(int i = 0;i < h;i++)
	{
		BYTE* pbyRsc = lpbyBits32 + dwBaseIndex;

		for(int 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);
			
			nGrayExpSum += gray;
		}
		dwBaseIndex += dwWidthBytes;
	}
	m_nExpSrc = (nGrayExpSum / (w * h));
	return m_nExpSrc;
}

//进行统计匹配
BOOL CGrayProcess::MakeStatisticMatch(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;

	//记录灰度数学期望(平均值, 按Wallis and Jong-Sen Lee的方法)
	int nExpGray = 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);
			*pbyGrayCopy++ = gray;
			nExpGray += gray;
		}
		dwBaseIndex += dwWidthBytes;
	}
	
	//最后数学期望:
	nExpGray /= 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++;
			
			//原像素的最终灰度
			 int nGrayDst = (m_nPercentage * ((int)byGraySrc - nExpGray)) / 100 + m_nExpDst;
			 BYTE byGrayDst = (BYTE)(BOUND(nGrayDst, 0, 255));

			*pbyRsc++ = byGrayDst;
			*pbyRsc++ = byGrayDst;
			*pbyRsc++ = byGrayDst;
			pbyRsc++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	delete[] pbyGraySubArea;
	return TRUE;
}


⌨️ 快捷键说明

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