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

📄 morphproc.cpp

📁 用C++实现的数字图像处理各个算法源代码 我精心整理的 很难的啊 希望可以给大家带来帮助
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	//图像数据区指针
	unsigned char *pOldBuffer = GetBitsPoint();
	
	//为新图像分配内存
	HGLOBAL hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, 2 * dwSize );

	if( hNewDib == NULL )
	{
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}

	//新图像数据指针
	unsigned char *pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
	
    if (pNewBuffer == NULL || pOldBuffer == NULL)	
	{
		AfxMessageBox("数据绶冲区定位出错!");
		return (FALSE);
	}

	//复制图像数据
	CopyBuffer(pNewBuffer + dwSize, pOldBuffer, (LONG)dwSize);

	//腐蚀
	MoveBuffer(pNewBuffer, pOldBuffer, (LONG)dwSize);
	MakeErosion(nMask, nMaskLen, pOldBuffer, pNewBuffer, nWidthBytes, nWidth, nHeight);

	//用原图减腐蚀后的结果
	XorBuffer(pOldBuffer, pNewBuffer + dwSize, (LONG)dwSize);
	
	//将内存解锁和将不再使用的内存释放
	::GlobalUnlock( m_pDibObject->GetDib() );
	::GlobalUnlock( hNewDib );
	::GlobalFree( hNewDib );
	return( TRUE );
}

////////////////////////////////////////////////////////////////////////
//BOOL MorphGrads()   
//----------------------------------------------------------------------
//基本功能:本函数对CDibObject对象中的图象进行形态学梯度运算。
//----------------------------------------------------------------------
//参数说明:int			 *nMask		击中结构元素数组指针
//			int			 nMaskLen		击中结构元素长度(点数)
//			CDibObject *pDibObject	默认为NULL。
//----------------------------------------------------------------------
//返    回:BOOL
//			成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CMorphPro::MorphGrads(int *nMask, int nMaskLen,
							CDibObject *pDibObject)
{
	//使用传入的CDibObject对象
	if( pDibObject != NULL ) m_pDibObject = pDibObject;
	//无CDibObject对象, 返回FALSE
	if( m_pDibObject == NULL ) return( FALSE );

	//不是8位灰度图像
	int nNumBits = m_pDibObject->GetNumBits(); 
	if( nNumBits != 8 ) return( FALSE );

	//获得图像宽度和高度
	int nWidth = m_pDibObject->GetWidth();
	int nHeight = m_pDibObject->GetHeight();
	int nWidthBytes = m_pDibObject->WidthBytes(8, nWidth);

	//图像数据区大小(字节)
	DWORD dwSize = nWidthBytes * nHeight;
	
	//图像数据区指针
	unsigned char *pOldBuffer = GetBitsPoint();
	
	//为新图像分配内存
	HGLOBAL hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, 2 * dwSize );

	if( hNewDib == NULL )
	{
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}

	//新图像数据指针
	unsigned char *pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
	
    if (pNewBuffer == NULL || pOldBuffer == NULL)	
	{
		AfxMessageBox("数据绶冲区定位出错!");
		return (FALSE);
	}

	//复制图像数据
	CopyBuffer(pNewBuffer + dwSize, pOldBuffer, (LONG)dwSize);

	//膨胀
	MoveBuffer(pNewBuffer, pOldBuffer, (LONG)dwSize);
	MakeDilation(nMask, nMaskLen, pOldBuffer, pNewBuffer, nWidthBytes, nWidth, nHeight);

	//腐蚀
	MoveBuffer(pNewBuffer, pNewBuffer + dwSize, (LONG)dwSize);
	MakeErosion(nMask, nMaskLen, pNewBuffer + dwSize, pNewBuffer, nWidthBytes, 
				nWidth, nHeight);

	//用膨胀后的结果减腐蚀后的结果
	XorBuffer(pOldBuffer, pNewBuffer + dwSize, (LONG)dwSize);
	
	//将内存解锁和将不再使用的内存释放
	::GlobalUnlock( m_pDibObject->GetDib() );
	::GlobalUnlock( hNewDib );
	::GlobalFree( hNewDib );
	return( TRUE );
}

////////////////////////////////////////////////////////////////////////
//BOOL ThiningDIB()   
//----------------------------------------------------------------------
//基本功能:本函数对CDibObject对象中的图象进行细化运算。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject	默认为NULL。
//----------------------------------------------------------------------
//返    回:BOOL
//			成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CMorphPro::ThiningDIB(CDibObject *pDibObject)
{
	//使用传入的CDibObject对象
	if( pDibObject != NULL ) m_pDibObject = pDibObject;
	//无CDibObject对象, 返回FALSE
	if( m_pDibObject == NULL ) return( FALSE );


	//定义变量
	unsigned char *pBuffer, *pBits;
	RGBQUAD *pPalette;
	int nWidthBytes, nNumColors;
	int lWidth,lHeight;
	
	//获得图像指针
	pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes, m_pDibObject->GetNumBits() );
	if( pBuffer == NULL ) return( NULL );

	//获得颜色数
	nNumColors = m_pDibObject->GetNumColors();
	//获得调色板指针
	pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
	//获得位图数据指针
	pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];

	lWidth=m_pDibObject->GetWidth();
	lHeight=m_pDibObject->GetHeight();

	/////////////////////////////////////////////////////////
		// 指向源图像的指针
	LPSTR	lpSrc;
	
	// 指向缓存图像的指针
	LPSTR	lpDst;
	
	// 指向缓存DIB图像的指针
	LPSTR	lpNewDIBBits;
	HLOCAL	hNewDIBBits;

	//脏标记
	BOOL bModified;

	//循环变量
	long i;
	long j;
	int  n;
	int  m;

	//四个条件
	BOOL bCondition1;
	BOOL bCondition2;
	BOOL bCondition3;
	BOOL bCondition4;

	//计数器
	unsigned char nCount;
	
	//像素值
	unsigned char pixel;

	//5×5相邻区域像素值
	unsigned char neighbour[5][5];

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

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

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

	bModified=TRUE;

	while(bModified)
	{

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

		for(j = 2; j <lHeight-2; j++)
		{
			for(i = 2;i <lWidth-2; i++)
			{

				bCondition1 = FALSE;
				bCondition2 = FALSE;
				bCondition3 = FALSE;
				bCondition4 = FALSE;

				//由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素

				// 指向源图像倒数第j行,第i个象素的指针			
				lpSrc = (char *)pBits + lWidth * j + i;

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

				//取得当前指针处的像素值,注意要转换为unsigned char型
				pixel = (unsigned char)*lpSrc;

				//目标图像中含有0和255外的其它灰度值
				if(pixel != 255 && *lpSrc != 0)
					//return FALSE;
					continue;
				//如果源图像中当前点为白色,则跳过
				else if(pixel == 255)
					continue;

				//获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
				for (m = 0;m < 5;m++ )
				{
					for (n = 0;n < 5;n++)
					{
						neighbour[m][n] =(255 - (unsigned char)*(lpSrc + ((4 - m) - 2)*lWidth + n - 2 )) / 255;
					}
				}
				//逐个判断条件。
				//判断2<=NZ(P1)<=6
				nCount =  neighbour[1][1] + neighbour[1][2] + neighbour[1][3] \
						+ neighbour[2][1] + neighbour[2][3] + \
						+ neighbour[3][1] + neighbour[3][2] + neighbour[3][3];
				if ( nCount >= 2 && nCount <=6)
					bCondition1 = TRUE;

				//判断Z0(P1)=1
				nCount = 0;
				if (neighbour[1][2] == 0 && neighbour[1][1] == 1)
					nCount++;
				if (neighbour[1][1] == 0 && neighbour[2][1] == 1)
					nCount++;
				if (neighbour[2][1] == 0 && neighbour[3][1] == 1)
					nCount++;
				if (neighbour[3][1] == 0 && neighbour[3][2] == 1)
					nCount++;
				if (neighbour[3][2] == 0 && neighbour[3][3] == 1)
					nCount++;
				if (neighbour[3][3] == 0 && neighbour[2][3] == 1)
					nCount++;
				if (neighbour[2][3] == 0 && neighbour[1][3] == 1)
					nCount++;
				if (neighbour[1][3] == 0 && neighbour[1][2] == 1)
					nCount++;
				if (nCount == 1)
					bCondition2 = TRUE;

				//判断P2*P4*P8=0 or Z0(p2)!=1
				if (neighbour[1][2]*neighbour[2][1]*neighbour[2][3] == 0)
					bCondition3 = TRUE;
				else
				{
					nCount = 0;
					if (neighbour[0][2] == 0 && neighbour[0][1] == 1)
						nCount++;
					if (neighbour[0][1] == 0 && neighbour[1][1] == 1)
						nCount++;
					if (neighbour[1][1] == 0 && neighbour[2][1] == 1)
						nCount++;
					if (neighbour[2][1] == 0 && neighbour[2][2] == 1)
						nCount++;
					if (neighbour[2][2] == 0 && neighbour[2][3] == 1)
						nCount++;
					if (neighbour[2][3] == 0 && neighbour[1][3] == 1)
						nCount++;
					if (neighbour[1][3] == 0 && neighbour[0][3] == 1)
						nCount++;
					if (neighbour[0][3] == 0 && neighbour[0][2] == 1)
						nCount++;
					if (nCount != 1)
						bCondition3 = TRUE;
				}

				//判断P2*P4*P6=0 or Z0(p4)!=1
				if (neighbour[1][2]*neighbour[2][1]*neighbour[3][2] == 0)
					bCondition4 = TRUE;
				else
				{
					nCount = 0;
					if (neighbour[1][1] == 0 && neighbour[1][0] == 1)
						nCount++;
					if (neighbour[1][0] == 0 && neighbour[2][0] == 1)
						nCount++;
					if (neighbour[2][0] == 0 && neighbour[3][0] == 1)
						nCount++;
					if (neighbour[3][0] == 0 && neighbour[3][1] == 1)
						nCount++;
					if (neighbour[3][1] == 0 && neighbour[3][2] == 1)
						nCount++;
					if (neighbour[3][2] == 0 && neighbour[2][2] == 1)
						nCount++;
					if (neighbour[2][2] == 0 && neighbour[1][2] == 1)
						nCount++;
					if (neighbour[1][2] == 0 && neighbour[1][1] == 1)
						nCount++;
					if (nCount != 1)
						bCondition4 = TRUE;
				}
				if(bCondition1 && bCondition2 && bCondition3 && bCondition4)
				{
					*lpDst = (unsigned char)255;
					bModified = TRUE;
				}
				else
				{
					*lpDst = (unsigned char)0;
				}
			}
		}
			// 复制腐蚀后的图像
			memcpy(pBits, lpNewDIBBits, lWidth * lHeight);


	}
	// 复制腐蚀后的图像
	memcpy(pBits, lpNewDIBBits, lWidth * lHeight);

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

	// 返回
	return TRUE;
}

⌨️ 快捷键说明

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