📄 morphproc.cpp
字号:
//图像数据区指针
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 + -