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

📄 morph.cpp

📁 其中包括图像压缩的基本编码方法如Huffman编码算术编码JPEG 2000H.261压缩编码标准小波变换编码运动估计算法视频图象采集的VC实现等.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// ************************************************************************
//  文件名:Morph.cpp
//
//   数学形态学函数库:
//
//  VErosion()				- 对图象进行垂直腐蚀
//  HErosion()				- 对图象进行水平腐蚀
//	VDilation()				- 对图象进行垂直膨胀
//	HDilation()				- 对图象进行水平膨胀
//	VHErosion()				- 对图象进行全方向腐蚀
//	VHDilation()			- 对图象进行全方向膨胀
//	OpenOperate()			- 对图象进行开运算处理
//	CloseOperate()			- 对图象进行闭运算处理
//	Thin()					- 对图象进行细化处理
//	Thick()					- 对图象进行粗化处理
//	MAT()					- 对图象进行中轴变换
//
// ************************************************************************

#include "stdafx.h"
#include "dip_system.h"
#include "Morph.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMorph

CMorph::CMorph()
{
}

CMorph::~CMorph()
{
}


BEGIN_MESSAGE_MAP(CMorph, CWnd)
	//{{AFX_MSG_MAP(CMorph)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CMorph message handlers


/*************************************************************************
 *
 * 函数名称:
 *   VErosion()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图象进行垂直方向上的腐蚀
 *
 ************************************************************************/

void CMorph::VErosion(HDIB hDIB)
{
	//循环变量
	LONG i;
	LONG j;
	LONG n;

	// 指向DIB的指针
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 指向源图像的指针
	LPBYTE	lpSrc;
	
	// 指向缓存图像的指针
	LPBYTE	lpDst;

	// 指向缓存DIB图像的指针
	LPBYTE	lpNewDIBBits;
	HLOCAL	hNewDIBBits;

	// 锁定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);

	// 暂时分配内存,以保存新图像
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);

	if (hNewDIBBits == NULL)
	{
		// 分配内存失败
		return;
	}
	
	// 锁定内存
	lpNewDIBBits = (LPBYTE)LocalLock(hNewDIBBits);

	// 初始化新分配的内存,设定初始值为255
	lpDst = (LPBYTE)lpNewDIBBits;
	memset(lpDst, (BYTE)255, lLineBytes * lHeight);

	//使用垂直方向的结构元素进行腐蚀
	for(i = 1; i < lHeight - 1; i++)
	{
		for(j = 0; j < lLineBytes; j += 3)
		{
			//由于使用3×1的结构元素,为防止越界,所以不处理最上边和最下边的两列像素
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + j);

			// 指向目标图像倒数第j行,第i个象素的指针			
			lpDst = (unsigned char *)(lpNewDIBBits + lLineBytes * i + j);

			//目标图像中的当前点先赋成黑色
			*lpDst = 0;
			*(lpDst + 1) = 0;
			*(lpDst + 2) = 0;

			// 如果源图像中(0,-1)、(0,0)、(0,1)三个点之一有白点,
			// 则将目标图像中的(0,0)点赋成白色
			for (n = 0; n < 3; n++)
			{
				if (*(lpSrc + (n - 1) * lLineBytes) > 128)
				{
					*lpDst = 255;
					*(lpDst + 1) = 255;
					*(lpDst + 2) = 255;
					break;
				}
			}				
		}
	}

	// 复制腐蚀后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   HErosion()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图象进行水平方向上的腐蚀
 *
 ************************************************************************/

void CMorph::HErosion(HDIB hDIB)
{
	//循环变量
	LONG i;
	LONG j;
	LONG n;

	// 指向DIB的指针
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 指向源图像的指针
	LPBYTE	lpSrc;
	
	// 指向缓存图像的指针
	LPBYTE	lpDst;

	// 指向缓存DIB图像的指针
	LPBYTE	lpNewDIBBits;
	HLOCAL	hNewDIBBits;

	// 锁定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);

	// 暂时分配内存,以保存新图像
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);

	if (hNewDIBBits == NULL)
	{
		// 分配内存失败
		return;
	}
	
	// 锁定内存
	lpNewDIBBits = (LPBYTE)LocalLock(hNewDIBBits);

	// 初始化新分配的内存,设定初始值为255
	lpDst = (LPBYTE)lpNewDIBBits;
	memset(lpDst, (BYTE)255, lLineBytes * lHeight);

	// 使用水平方向的结构元素进行腐蚀
	for (i = 0; i < lHeight; i++)
	{
		for (j = 3; j < lLineBytes - 3; j += 3)
		{
			// 由于使用1×3的结构元素,为防止越界,所以不处理最左边和最右边的两列像素
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + j);

			// 指向目标图像倒数第j行,第i个象素的指针			
			lpDst = (unsigned char *)(lpNewDIBBits + lLineBytes * i + j);

			// 目标图像中的当前点先赋成黑色
			*lpDst = 0;
			*(lpDst + 1) = 0;
			*(lpDst + 2) = 0;
 
			// 如果源图像中(-1,0)、(0,0)、(1,0)三个点之一有白点,
			// 则将目标图像中的(0,0)点赋成白色
			for (n = 0; n < 3; n++)
			{
				if (*(lpSrc + (n - 1) * 3) > 128)
				{
					*lpDst = 255;
					*(lpDst + 1) = 255;
					*(lpDst + 2) = 255;
					break;
				}
			}				
		}
	}
	// 复制腐蚀后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   VDilation()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图象进行垂直方向上的膨胀
 *
 ************************************************************************/

void CMorph::VDilation(HDIB hDIB)
{
	//循环变量
	LONG i;
	LONG j;
	LONG n;

	// 指向DIB的指针
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 指向源图像的指针
	LPBYTE	lpSrc;
	
	// 指向缓存图像的指针
	LPBYTE	lpDst;

	// 指向缓存DIB图像的指针
	LPBYTE	lpNewDIBBits;
	HLOCAL	hNewDIBBits;

	// 锁定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);

	// 暂时分配内存,以保存新图像
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);

	if (hNewDIBBits == NULL)
	{
		// 分配内存失败
		return;
	}
	
	// 锁定内存
	lpNewDIBBits = (LPBYTE)LocalLock(hNewDIBBits);

	// 初始化新分配的内存,设定初始值为255
	lpDst = (LPBYTE)lpNewDIBBits;
	memset(lpDst, (BYTE)255, lLineBytes * lHeight);

	//使用垂直方向的结构元素进行膨胀
	for(i = 1; i < lHeight - 1; i++)
	{
		for(j = 0; j < lLineBytes; j += 3)
		{
			//由于使用3×1的结构元素,为防止越界,所以不处理最上边和最下边的两列像素
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + j);

			// 指向目标图像倒数第j行,第i个象素的指针			
			lpDst = (unsigned char *)(lpNewDIBBits + lLineBytes * i + j);

			//目标图像中的当前点先赋成白色
			*lpDst = 255;
			*(lpDst + 1) = 255;
			*(lpDst + 2) = 255;

			// 如果源图像中(0,-1)、(0,0)、(0,1)三个点之一有黑点,
			// 则将目标图像中的(0,0)点赋成黑色
			for (n = 0; n < 3; n++)
			{
				if (*(lpSrc + (n - 1) * lLineBytes) < 128)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					break;
				}
			}				
		}
	}

	// 复制腐蚀后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   HDilation()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图象进行水平方向上的膨胀
 *
 ************************************************************************/

void CMorph::HDilation(HDIB hDIB)
{
	//循环变量
	LONG i;
	LONG j;
	LONG n;

	// 指向DIB的指针
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 指向源图像的指针
	LPBYTE	lpSrc;
	
	// 指向缓存图像的指针
	LPBYTE	lpDst;

	// 指向缓存DIB图像的指针
	LPBYTE	lpNewDIBBits;
	HLOCAL	hNewDIBBits;

	// 锁定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);

	// 暂时分配内存,以保存新图像
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);

	if (hNewDIBBits == NULL)
	{
		// 分配内存失败
		return;

⌨️ 快捷键说明

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