mathmorphology.cpp

来自「visual c++数字图像与图形处理中的光盘内容」· C++ 代码 · 共 1,035 行 · 第 1/2 页

CPP
1,035
字号

	//第四步
	//先进行膨胀, 然后进行腐蚀
	Dilate(pcxDataSrc, w, h, pcxDataDst);
	Erode(pcxDataDst, w, h, pcxDataSrc);
	
	//第五步
	//指向内存目标数据
	pcxDataFore = pcxDataSrc;

	dwBaseIndex = y * dwWidthBytes + 4 * x;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据
		BYTE* pbyDst = lpbyBits32 + dwBaseIndex;
		for(j = 0;j < w;j++)
		{
			short cxBlue = *pcxDataFore++;
			short cxGreen = *pcxDataFore++;
			short cxRed = *pcxDataFore++;
			
			*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
			pbyDst++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	delete[] pcxDataSrc;
	delete[] pcxDataDst;

	return TRUE;
}

//提取边界
BOOL CMathMorphology::PickEdge(LPBYTE lpbyBits32,  int x,  int y,  int nWidth,  int nHeight,  int nScanWidth,  int nScanHeight)
{
	//第一步, 进行参数合法性检测
	ASSERT(lpbyBits32);
	ASSERT(m_pME);
	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	m_dwOperation = IMAGE_MATH_MORPHOLOGY_PICK_DETECT;
	//有效区域的宽度和高度
	int w = min(nWidth, nScanWidth - x);
	int h = min(nHeight, nScanHeight - y);

	//第二步, 分配内存空间, 结果只可能在(-255, +255)之间, 
	//存储蓝色、绿色、红色
	int nSize = w * h;

	//存储源
	short* pcxDataSrc =  new short[(nSize * 3)];
	if (pcxDataSrc == NULL)	return FALSE;

	//存储目标
	short* pcxDataDst = new short[(nSize * 3)];
	if (pcxDataDst == NULL)	return FALSE;

	//第三步, 获取输入图像的数据
	
	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
	
	//开始数据基索引
	DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
	
	//指向内存源数据
	short* pcxDataFore = pcxDataSrc;
	
	int i, j;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据
		BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
		for(j = 0;j < w;j++)
		{
			//blue
			*pcxDataFore++ = *pbySrc++;
			//green
			*pcxDataFore++ = *pbySrc++;
			//red
			*pcxDataFore++ = *pbySrc++;
			pbySrc++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	//第四步
	//先进行腐蚀
	Erode(pcxDataSrc, w, h, pcxDataDst);

	//第五步
	//指向内存目标数据
	pcxDataFore = pcxDataSrc;
	short* pcxDataAfter = pcxDataDst;

	dwBaseIndex = y * dwWidthBytes + 4 * x;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据: 目标
		BYTE* pbyDst = lpbyBits32 + dwBaseIndex;

		for(j = 0;j < w;j++)
		{
			short cxBlue = ((*pcxDataFore++) - (*pcxDataAfter++));
			short cxGreen = ((*pcxDataFore++) - (*pcxDataAfter++));
			short cxRed = ((*pcxDataFore++) - (*pcxDataAfter++));


			//执行归入至[0,255]的运算
			*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
			pbyDst++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	delete[] pcxDataSrc;
	delete[] pcxDataDst;

	return TRUE;

}

//开合成
BOOL CMathMorphology::OpenCompose(LPBYTE lpbyBits32,  int x,  int y,  int nWidth,  int nHeight,  int nScanWidth,  int nScanHeight)
{
	//第一步, 进行参数合法性检测
	ASSERT(lpbyBits32);
	ASSERT(m_pME);
	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	m_dwOperation = IMAGE_MATH_MORPHOLOGY_OPEN_COMPOSE;
	//有效区域的宽度和高度
	int w = min(nWidth, nScanWidth - x);
	int h = min(nHeight, nScanHeight - y);

	//第二步, 分配内存空间, 结果只可能在(-255, +255)之间, 
	//存储蓝色、绿色、红色
	int nSize = w * h;

	//存储源
	short* pcxDataSrc =  new short[(nSize * 3)];
	if (pcxDataSrc == NULL)	return FALSE;

	//存储目标
	short* pcxDataDst = new short[(nSize * 3)];
	if (pcxDataDst == NULL)	return FALSE;


	//第三步, 获取输入图像的数据
	
	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
	
	//开始数据基索引
	DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
	
	//指向内存源数据
	short* pcxDataFore = pcxDataSrc;
	
	int i, j;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据
		BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
		for(j = 0;j < w;j++)
		{
			//blue
			*pcxDataFore++ = *pbySrc++;
			//green
			*pcxDataFore++ = *pbySrc++;
			//red
			*pcxDataFore++ = *pbySrc++;
			pbySrc++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	//保存中间结果
	short* pcxDataTemp = new short[(nSize * 3)];
	if (pcxDataTemp == NULL) return FALSE;


	//第四步
	//先进行膨胀, 然后进行腐蚀, 
	Erode(pcxDataSrc, w, h, pcxDataTemp);
	Dilate(pcxDataTemp, w, h, pcxDataDst);

	//第五步
	//指向内存目标数据
	pcxDataFore = pcxDataSrc;
	short* pcxDataAfter = pcxDataDst;

	dwBaseIndex = y * dwWidthBytes + 4 * x;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据: 目标
		BYTE* pbyDst = lpbyBits32 + dwBaseIndex;

		for(j = 0;j < w;j++)
		{
		
			short cxBlue = ((*pcxDataFore++) + (*pcxDataAfter++));
			short cxGreen = ((*pcxDataFore++) + (*pcxDataAfter++));
			short cxRed = ((*pcxDataFore++) + (*pcxDataAfter++));

			*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
			pbyDst++;
		}
		dwBaseIndex += dwWidthBytes;
	}


	delete[] pcxDataSrc;
	delete[] pcxDataDst;
	delete[] pcxDataTemp;


	return TRUE;
}

//去噪声
BOOL CMathMorphology::Denoise(LPBYTE lpbyBits32,  int x,  int y,  int nWidth,  int nHeight,  int nScanWidth,  int nScanHeight)
{
	//第一步, 进行参数合法性检测
	ASSERT(lpbyBits32);
	ASSERT(m_pME);
	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	m_dwOperation = IMAGE_MATH_MORPHOLOGY_DENOISE;
	//有效区域的宽度和高度
	int w = min(nWidth, nScanWidth - x);
	int h = min(nHeight, nScanHeight - y);

	//第二步, 分配内存空间, 结果只可能在(-255, +255)之间, 
	//存储蓝色、绿色、红色
	int nSize = w * h;

	//存储源
	short* pcxDataSrc =  new short[(nSize * 3)];
	if (pcxDataSrc == NULL)	return FALSE;

	//存储目标
	short* pcxDataDst = new short[(nSize * 3)];
	if (pcxDataDst == NULL)	return FALSE;

	//第三步, 获取输入图像的数据
	
	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
	
	//开始数据基索引
	DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
	
	//指向内存源数据
	short* pcxDataFore = pcxDataSrc;
	
	int i, j;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据
		BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
		for(j = 0;j < w;j++)
		{
			//blue
			*pcxDataFore++ = *pbySrc++;
			//green
			*pcxDataFore++ = *pbySrc++;
			//red
			*pcxDataFore++ = *pbySrc++;
			pbySrc++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	//第四步
	//进行降噪声处理
	//先进行腐蚀, 然后进行膨胀, 膨胀, 腐蚀
	Erode(pcxDataSrc, w, h, pcxDataDst);
	Dilate(pcxDataDst, w, h, pcxDataSrc);
	Dilate(pcxDataSrc, w, h, pcxDataDst);
	Erode(pcxDataDst, w, h, pcxDataSrc);

	//第五步
	//指向内存目标数据
	pcxDataFore = pcxDataSrc;

	dwBaseIndex = y * dwWidthBytes + 4 * x;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据
		BYTE* pbyDst = lpbyBits32 + dwBaseIndex;
		for(j = 0;j < w;j++)
		{
			short cxBlue = *pcxDataFore++;
			short cxGreen = *pcxDataFore++;
			short cxRed = *pcxDataFore++;
			
			*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
			pbyDst++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	delete[] pcxDataSrc;
	delete[] pcxDataDst;

	return TRUE;

}

//形态学梯度
BOOL CMathMorphology::Gradientize(LPBYTE lpbyBits32,  int x,  int y,  int nWidth,  int nHeight,  int nScanWidth,  int nScanHeight)
{
	//第一步, 进行参数合法性检测
	ASSERT(lpbyBits32);
	ASSERT(m_pME);

	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	m_dwOperation = IMAGE_MATH_MORPHOLOGY_GRADIENTIZE;
	//有效区域的宽度和高度
	int w = min(nWidth, nScanWidth - x);
	int h = min(nHeight, nScanHeight - y);

	//第二步, 分配内存空间, 结果只可能在(-255, +255)之间, 
	//存储蓝色、绿色、红色
	int nSize = w * h;

	//存储源
	short* pcxDataSrc =  new short[(nSize * 3)];
	if (pcxDataSrc == NULL)	return FALSE;

	//存储目标
	short* pcxDataDst = new short[(nSize * 3)];
	if (pcxDataDst == NULL)	return FALSE;


	//第三步, 获取输入图像的数据
	
	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
	
	//开始数据基索引
	DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
	
	//指向内存源数据
	short* pcxDataFore = pcxDataSrc;

	int i, j;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据
		BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
		for(j = 0;j < w;j++)
		{
			//blue
			*pcxDataFore++ = *pbySrc++;
			//green
			*pcxDataFore++ = *pbySrc++;
			//red
			*pcxDataFore++ = *pbySrc++;
			pbySrc++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	//保存中间结果
	short* pcxDataTemp = new short[(nSize * 3)];
	if (pcxDataTemp == NULL)	return FALSE;

	//第四步
	//进行形态学梯度
	Dilate(pcxDataSrc, w, h, pcxDataTemp);
	Erode(pcxDataSrc, w, h, pcxDataDst);

	//第五步
	//指向内存目标数据
	pcxDataFore = pcxDataTemp;
	short* pcxDataAfter = pcxDataDst;


	dwBaseIndex = y * dwWidthBytes + 4 * x;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据
		BYTE* pbyDst = lpbyBits32 + dwBaseIndex;
		for(j = 0;j < w;j++)
		{
			short cxBlue = ((*pcxDataFore++) - (*pcxDataAfter++));
			short cxGreen = ((*pcxDataFore++) - (*pcxDataAfter++));
			short cxRed = ((*pcxDataFore++) - (*pcxDataAfter++));
			
			*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
			pbyDst++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	delete[] pcxDataSrc;
	delete[] pcxDataDst;
	delete[] pcxDataTemp;
	return TRUE;
	
}

//高帽变换
BOOL CMathMorphology::TopHat(LPBYTE lpbyBits32,  int x,  int y,  int nWidth,  int nHeight,  int nScanWidth,  int nScanHeight)
{
	//第一步, 进行参数合法性检测
	ASSERT(lpbyBits32);
	ASSERT(m_pME);
	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	m_dwOperation = IMAGE_MATH_MORPHOLOGY_TOP_HAT;
	//有效区域的宽度和高度
	int w = min(nWidth, nScanWidth - x);
	int h = min(nHeight, nScanHeight - y);

	//第二步, 分配内存空间, 结果只可能在(-255, +255)之间, 
	//存储蓝色、绿色、红色
	int nSize = w * h;

	//存储源
	short* pcxDataSrc =  new short[(nSize * 3)];
	if (pcxDataSrc == NULL)	return FALSE;

	//存储目标
	short* pcxDataDst = new short[(nSize * 3)];
	if (pcxDataDst == NULL)	return FALSE;

	//第三步, 获取输入图像的数据
	
	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
	
	//开始数据基索引
	DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
	
	//指向内存源数据
	short* pcxDataFore = pcxDataSrc;
	
	int i, j;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据
		BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
		for(j = 0;j < w;j++)
		{
			//blue
			*pcxDataFore++ = *pbySrc++;
			//green
			*pcxDataFore++ = *pbySrc++;
			//red
			*pcxDataFore++ = *pbySrc++;
			pbySrc++;
		}
		dwBaseIndex += dwWidthBytes;
	}

	//保存中间结果
	short* pcxDataTemp = new short[ (nSize * 3) ];
	if (pcxDataTemp == NULL)	return FALSE;



	//第四步
	//先进行膨胀, 然后进行腐蚀, 
	Erode(pcxDataSrc, w, h, pcxDataTemp);
	Dilate(pcxDataTemp, w, h, pcxDataDst);

	//第五步
	//指向内存目标数据
	pcxDataFore = pcxDataSrc;
	short* pcxDataAfter = pcxDataDst;

	dwBaseIndex = y * dwWidthBytes + 4 * x;
	for(i = 0;i < h;i++)
	{
		//指向一行的开始数据: 目标
		BYTE* pbyDst = lpbyBits32 + dwBaseIndex;

		for(j = 0;j < w;j++)
		{
		
			short cxBlue = ((*pcxDataFore++) - (*pcxDataAfter++));
			short cxGreen = ((*pcxDataFore++) - (*pcxDataAfter++));
			short cxRed = ((*pcxDataFore++) - (*pcxDataAfter++));

			*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
			*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
			pbyDst++;
		}
		dwBaseIndex += dwWidthBytes;
	}


	delete[] pcxDataSrc;
	delete[] pcxDataDst;
	delete[] pcxDataTemp;


	return TRUE;
}

⌨️ 快捷键说明

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