📄 morph.cpp
字号:
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 判断条件二是否成立:
nCount = 0;
if (S[1][2] == 0 && S[1][1] == 1)
nCount++;
if (S[1][1] == 0 && S[2][1] == 1)
nCount++;
if (S[2][1] == 0 && S[3][1] == 1)
nCount++;
if (S[3][1] == 0 && S[3][2] == 1)
nCount++;
if (S[3][2] == 0 && S[3][3] == 1)
nCount++;
if (S[3][3] == 0 && S[2][3] == 1)
nCount++;
if (S[2][3] == 0 && S[1][3] == 1)
nCount++;
if (S[1][3] == 0 && S[1][2] == 1)
nCount++;
if (nCount != 1)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 判断条件三是否成立;
if (S[1][2] * S[2][1] * S[2][3] != 0)
{
nCount = 0;
if (S[0][2] == 0 && S[0][1] == 1)
nCount++;
if (S[0][1] == 0 && S[1][1] == 1)
nCount++;
if (S[1][1] == 0 && S[2][1] == 1)
nCount++;
if (S[2][1] == 0 && S[2][2] == 1)
nCount++;
if (S[2][2] == 0 && S[2][3] == 1)
nCount++;
if (S[2][3] == 0 && S[1][3] == 1)
nCount++;
if (S[1][3] == 0 && S[0][3] == 1)
nCount++;
if (S[0][3] == 0 && S[0][2] == 1)
nCount++;
if (nCount == 1)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
}
// 判断条件四是否成立:
if (S[1][2] * S[2][1] * S[3][2] != 0)
{
nCount = 0;
if (S[1][1] == 0 && S[1][0] == 1)
nCount++;
if (S[1][0] == 0 && S[2][0] == 1)
nCount++;
if (S[2][0] == 0 && S[3][0] == 1)
nCount++;
if (S[3][0] == 0 && S[3][1] == 1)
nCount++;
if (S[3][1] == 0 && S[3][2] == 1)
nCount++;
if (S[3][2] == 0 && S[2][2] == 1)
nCount++;
if (S[2][2] == 0 && S[1][2] == 1)
nCount++;
if (S[1][2] == 0 && S[1][1] == 1)
nCount++;
if (nCount == 1)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
}
// 如果条件均满足则删除该点
*lpDst = 255;
*(lpDst + 1) = 255;
*(lpDst + 2) = 255;
bJump = TRUE;
}
}
// 复制腐蚀后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
}
// 复制腐蚀后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 恢复光标
EndWaitCursor();
}
/*************************************************************************
*
* 函数名称:
* Thick()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数对图象进行粗化处理
*
************************************************************************/
void CMorph::Thick(HDIB hDIB)
{
// 循环变量
LONG i;
LONG j;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定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);
// 对各像素进行灰度转换
for (i = 0; i < lHeight; i ++)
{
for (j = 0; j < lLineBytes; j ++)
{
// 对像素各颜色分量进行二值化求补处理
unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
if (R > 127)
*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 0;
else
*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 255;
j++;
unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
if (G > 127)
*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 0;
else
*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 255;
j++;
unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
if (B >127)
*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 0;
else
*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 0;
}
}
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 在求补后再对图象进行细化
Thin(hDIB);
// 恢复光标
EndWaitCursor();
}
/*************************************************************************
*
* 函数名称:
* MAT()
*
* 参数:
* HDIB hDIB - 待处理的DIB
*
* 返回值:
* void - 无返回值
*
* 说明:
* 该函数对图象进行中轴变换
*
************************************************************************/
void CMorph::MAT(HDIB hDIB)
{
// 循环变量
LONG i;
LONG j;
LONG m;
LONG n;
// 5×5相邻区域像素值
unsigned char S[5][5];
// 计数器
unsigned char nCount;
// 循环跳出标志
BOOL bJump;
// 指向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);
while (bJump)
{
bJump = FALSE;
// 初始化新分配的内存,设定初始值为255
lpDst = (LPBYTE)lpNewDIBBits;
memset(lpDst, (BYTE)255, lLineBytes * lHeight);
// 由于使用5×5的结构元素,为防越界,不处理外围的2行、2列像素
for (i = 2; i < lHeight - 2; i++)
{
for (j = 2 * 3; j < lLineBytes - 2 * 3; j += 3)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (LPBYTE)(lpDIBBits + lLineBytes * i + j);
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = (LPBYTE)(lpNewDIBBits + lLineBytes * i + j);
// 如果源图像中当前点为白色,则跳过
if (*lpSrc > 127)
continue;
// 获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
for (m = 0; m < 5; m++)
{
for (n = 0; n < 5; n++)
{
if (*(lpSrc + (2 - m) * lLineBytes + (n - 2) * 3) > 127)
S[m][n] = 0;
else
S[m][n] = 1;
}
}
// 判断条件1-1是否成立:
nCount = S[1][1] + S[1][2] + S[1][3] + S[2][1]
+ S[2][3] + S[3][1] + S[3][2] + S[3][3];
if (nCount < 2 || nCount >6)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 判断条件1-2是否成立:
nCount = 0;
if (S[1][2] == 0 && S[1][1] == 1)
nCount++;
if (S[1][1] == 0 && S[2][1] == 1)
nCount++;
if (S[2][1] == 0 && S[3][1] == 1)
nCount++;
if (S[3][1] == 0 && S[3][2] == 1)
nCount++;
if (S[3][2] == 0 && S[3][3] == 1)
nCount++;
if (S[3][3] == 0 && S[2][3] == 1)
nCount++;
if (S[2][3] == 0 && S[1][3] == 1)
nCount++;
if (S[1][3] == 0 && S[1][2] == 1)
nCount++;
if (nCount != 1)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 判断条件1-3是否成立;
if (S[1][2] * S[2][1] * S[3][2] != 0)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 判断条件1-4是否成立:
if (S[2][1] * S[3][2] * S[2][3] != 0)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 如果条件均满足则删除该点
*lpDst = 255;
*(lpDst + 1) = 255;
*(lpDst + 2) = 255;
}
}
// 由于使用5×5的结构元素,为防越界,不处理外围的2行、2列像素
for (i = 2; i < lHeight - 2; i++)
{
for (j = 2 * 3; j < lLineBytes - 2 * 3; j += 3)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (LPBYTE)(lpDIBBits + lLineBytes * i + j);
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = (LPBYTE)(lpNewDIBBits + lLineBytes * i + j);
// 如果源图像中当前点为白色,则跳过
if (*lpSrc > 127)
continue;
// 获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
for (m = 0; m < 5; m++)
{
for (n = 0; n < 5; n++)
{
if (*(lpSrc + (2 - m) * lLineBytes + (n - 2) * 3) > 127)
S[m][n] = 0;
else
S[m][n] = 1;
}
}
// 判断条件2-1是否成立:
nCount = S[1][1] + S[1][2] + S[1][3] + S[2][1]
+ S[2][3] + S[3][1] + S[3][2] + S[3][3];
if (nCount < 2 || nCount >6)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 判断条件2-2是否成立:
nCount = 0;
if (S[1][2] == 0 && S[1][1] == 1)
nCount++;
if (S[1][1] == 0 && S[2][1] == 1)
nCount++;
if (S[2][1] == 0 && S[3][1] == 1)
nCount++;
if (S[3][1] == 0 && S[3][2] == 1)
nCount++;
if (S[3][2] == 0 && S[3][3] == 1)
nCount++;
if (S[3][3] == 0 && S[2][3] == 1)
nCount++;
if (S[2][3] == 0 && S[1][3] == 1)
nCount++;
if (S[1][3] == 0 && S[1][2] == 1)
nCount++;
if (nCount != 1)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 判断条件2-3是否成立;
if (S[1][2] * S[2][1] * S[2][3] != 0)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 判断条件2-4是否成立:
if (S[1][2] * S[3][2] * S[2][3] != 0)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
continue;
}
// 如果条件均满足则删除该点
*lpDst = 255;
*(lpDst + 1) = 255;
*(lpDst + 2) = 255;
bJump = TRUE;
}
}
// 复制腐蚀后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
}
// 复制腐蚀后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 恢复光标
EndWaitCursor();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -