msvc6 数学形态学细化处理的问题 【from 何东健主编《数字图像处理》CMorphPro::ThiningDIB】为何是 “5×5相邻区域像素值”?////////////////////////////////////////////////////////////////////////
//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;
}

解决方案 »

  1.   

    【推荐】格式化 Microsoft Visual C++ 6.0 源程序的Word VBA 源程序/宏。【欢迎篡改】
    Sub M__Replace(FindText, RepaceText)    With Selection.Find
            .ClearFormatting
            .Replacement.ClearFormatting
            .Text = FindText
            .Replacement.Text = RepaceText
            .Forward = True
            .Wrap = wdFindContinue
            .Format = False
            .MatchCase = False
            .MatchWholeWord = False
            .MatchByte = True
            .MatchWildcards = False
            .MatchSoundsLike = False
            .MatchAllWordForms = False
            .Execute Replace:=wdReplaceAll
        End WithEnd SubSub M__FormatC()
        
        'tab
        M__Replace " ", " "
        M__Replace "^t", " "
        
        '+-*/=<>
        
        '()[]{}
        M__Replace "(", " ( "
        M__Replace ")", " ) "
        M__Replace "[", " [ "
        M__Replace "]", " ] "
        M__Replace "{", " { "
        M__Replace "}", " } "
        
        ',.;:
        M__Replace ",", " , "
        M__Replace ";", " ; "
        
        'space
        For lngI = 1 To 10
            M__Replace "  ", " "
        Next
        
        'line
        M__Replace " ^p", "^p"
        M__Replace "^p ", "^p"
        For lngI = 1 To 10
            M__Replace "^p^p", "^p"
        Next
        
        'Alt + F8
        
    End Sub
      

  2.   

    ////////////////////////////////////////////////////////////////////////
    //int CAreaPro::_Thin_LV( )
    //----------------------------------------------------------------------
    //基本功能:细化算法 吕凤军
    // Copy 数字图象处理编程入门 吕凤军 编
    //----------------------------------------------------------------------
    //参数说明:
    //----------------------------------------------------------------------
    //返    回:
    //----------------------------------------------------------------------
    //注    意:taylor
    ////////////////////////////////////////////////////////////////////////
    int CAreaPro::_Thin_LV()
    {
    //变量定义
    int nX, nY;
    unsigned char * pTemp; int nChanged; // 1 改 0 未改
    int nStep; // 步骤
    CString CStrStep;

    // 8连通邻居,低位到高位排列
    // 0 1 2
    // 3 - 4
    // 5 6 7
    int nEeraseID;
    int nEeraseTable [ 256 ] = // 1 删 0 不删
    {
    0, 0, 1, 1, 0, 0, 1, 1,  1, 1, 0, 1, 1, 1, 0, 1, 
    1, 1, 0, 0, 1, 1, 1, 1,  0, 0, 0, 0, 0, 0, 0, 1, 
    0, 0, 1, 1, 0, 0, 1, 1,  1, 1, 0, 1, 1, 1, 0, 1, 
    1, 1, 0, 0, 1, 1, 1, 1,  0, 0, 0, 0, 0, 0, 0, 1, 
    1, 1, 0, 0, 1, 1, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 
    1, 1, 0, 0, 1, 1, 0, 0,  1, 1, 0, 1, 1, 1, 0, 1, 
    0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 1, 1, 0, 0, 1, 1,  1, 1, 0, 1, 1, 1, 0, 1, 
    1, 1, 0, 0, 1, 1, 1, 1,  0, 0, 0, 0, 0, 0, 0, 1, 
    0, 0, 1, 1, 0, 0, 1, 1,  1, 1, 0, 1, 1, 1, 0, 1, 
    1, 1, 0, 0, 1, 1, 1, 1,  0, 0, 0, 0, 0, 0, 0, 0, 
    1, 1, 0, 0, 1, 1, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 
    1, 1, 0, 0, 1, 1, 1, 1,  0, 0, 0, 0, 0, 0, 0, 0, 
    1, 1, 0, 0, 1, 1, 0, 0,  1, 1, 0, 1, 1, 1, 0, 0, 
    1, 1, 0, 0, 1, 1, 1, 0,  1, 1, 0, 0, 1, 0, 0, 0
    }; // 细化算法
    nStep = -1 ;
    do
    {
    nChanged = 0;
    nStep ++ ;
    for ( nY = 1 ; nY < _nYHeight - 1 ; nY++ )
    {
    //数据指针定位到图像数据每行的起始零位置
    pTemp =_p256g + ( ( _nYHeight - 1 - nY ) * _nWidthBytes );
    for ( nX = 1 ; nX < _nXWidth - 1 ; nX++ )
    {
    if ( pTemp[ nX ] == 0 )
    {
    nEeraseID = 
    _Thin_LV_Get1 ( pTemp[ nX + _nWidthBytes - 1 ] ) +
    _Thin_LV_Get1 ( pTemp[ nX + _nWidthBytes ] ) * 2 +
    _Thin_LV_Get1 ( pTemp[ nX + _nWidthBytes + 1 ] ) * 4 +
    _Thin_LV_Get1 ( pTemp[ nX - 1 ] ) * 8 +
    _Thin_LV_Get1 ( pTemp[ nX + 1 ] ) * 16 +
    _Thin_LV_Get1 ( pTemp[ nX - _nWidthBytes - 1 ] ) * 32 +
    _Thin_LV_Get1 ( pTemp[ nX - _nWidthBytes ] ) * 64 +
    _Thin_LV_Get1 ( pTemp[ nX - _nWidthBytes + 1 ] ) * 128 ;
    if ( nEeraseTable[ nEeraseID ] == 1 )
    {
    nChanged = 1;
    pTemp[ nX ] = 255;
    }
    }
    }
    }
    } while ( nChanged == 1 && nStep < 50 ); // 显示步骤
    CStrStep.Format( "%d" , nStep );
    AfxMessageBox( ( LPCTSTR ) CStrStep ); return 1;
    }////////////////////////////////////////////////////////////////////////
    //int CAreaPro::_Thin_LV_Get1(int nP127255)
    //----------------------------------------------------------------------
    //基本功能:细化算法 吕凤军 点变换 127 = 1, 255 = 1, other = 0
    // Copy 数字图象处理编程入门 吕凤军 编
    //----------------------------------------------------------------------
    //参数说明:
    //----------------------------------------------------------------------
    //返    回:
    //----------------------------------------------------------------------
    //注    意:taylor
    ////////////////////////////////////////////////////////////////////////
    int CAreaPro::_Thin_LV_Get1(int nP127255)
    {
    if ( nP127255 == 127 || nP127255 == 255 ) return 1;
    return 0;
    }
      

  3.   

    【篇名】    指纹图像细化算法的研究 CAJ原文下载    PDF原文下载  
    【作者】  王业琳. 宁新宝. 尹义龙.  
    【刊名】    南京大学学报(自然科学版)    2003年04期    编辑部Email  
     《中文核心期刊要目总览》来源期刊   “中国期刊方阵”入选期刊   ASPT来源刊   CJFD收录期刊  
    【机构】  南京大学电子科学与工程系. 山东大学计算机科学与技术学院 南京. 210093 . 济南. 250100.  
    【关键词】    指纹. 图像细化. 单像素宽. 模板.  
    【聚类检索】  同类文献   引用文献   被引用文献    
    【摘要】  对指纹图像的细化算法进行了较深入的研究,分析了两种常用的细化算法——快速细化算法和改进的OPTA算法各自的优缺点,针对这两种算法的不足,分析其产生的原因,并且在第二种算法的基础上,重新构建了细化模板,提出了一种新的细化算法。经过实验证明,该算法能够很好的满足细化的要求,细化完全彻底,细化以后的指纹骨架在纹线中心线,并保持了纹线原有的拓外结构和细节特征,而且光滑无毛刺,运算速度也很快。  
      

  4.   

    thisisll(民工甲):你们院长的源程序升级了吗?
      

  5.   

    哪里有 hscp 图像细化算法 详细说明?
      

  6.   

    谁有:[2] HallRW Fast Parallel Thinning Algorithms: Parallel Speed and Connective Preservation [J] Communication of the ACM, Jan. 1989, 32(1):124-131 [3] Holt CM, etal. An Improved Parallel Thinning Algorithm [J] Communication of the ACM, Feb. 1987, 30(2):156-160
      

  7.   

    细化算法 那个好?Hilditch细化算法Pavlidis细化算法Rosenfeld细化算法