void CMyDib::Thinning() //细化算法,提取二制黑白图象的的骨架
{
LPBYTE p_data, ptemp,lpSrc,lpDst;
int wide;
int height;
int conf; //系数
int Linebyte;
p_data = GetData();
wide = GetWidth();
height = GetHeight();
LPBITMAPINFO pBitmapInfo = GetInfo();
int num = pBitmapInfo->bmiHeader.biBitCount;
if(num == 24)
::AfxMessageBox("系统提示" , MB_OK);
else
conf = 1;
Linebyte=(((wide*conf*8)+31)/32*4);
//像素值
unsigned char pixel;
ptemp=new BYTE[Linebyte*height];
memset(ptemp,255,Linebyte*height);
//四个条件
BOOL bCondition1;
BOOL bCondition2;
BOOL bCondition3;
BOOL bCondition4;
//计数器
unsigned char nCount;
long i;
long j;
int n;
int m;
//5×5相邻区域像素值
unsigned char neighbour[5][5];
//脏标记
BOOL bModified;
bModified=TRUE;
while(bModified)
{
bModified = FALSE;
// 初始化新分配的内存,设定初始值为255
lpDst=ptemp;
memset(lpDst,255,Linebyte*height);
for(j = 2; j <height-2; j++)
{
for(i = 2;i <Linebyte-2; i++)
{
bCondition1 = FALSE;
bCondition2 = FALSE;
bCondition3 = FALSE;
bCondition4 = FALSE;
//由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = p_data+j*Linebyte+i;
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = ptemp+j*Linebyte+i;
//取得当前指针处的像素值,注意要转换为unsigned char型
pixel = p_data[j*Linebyte+i];
//目标图像中含有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)*Linebyte + n - 2 )) / 255;
}
}
// neighbour[][]
//逐个判断条件。
//判断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(p_data, ptemp, Linebyte* height);
}
// 复制腐蚀后的图像
memcpy(p_data, ptemp, Linebyte* height);
// 返回
return;
}
评论0