最近,我在做指纹预处理时,得到二值化后的图象,有很多的细化方法,线跟踪法,谢尔曼细化法,还有模板细化算法.但好象都不大好应用,不知道各位大虾有没有什么好的算法,比如对一个m*n像素矩阵,元素值为0,1.采用什么样的方法能细化使一些元素由1变0?
谢谢了!

解决方案 »

  1.   

    http://www-scf.usc.edu/~flv/ipbook/你看看这个,不知道对你有没有帮助
      

  2.   

    BOOL WINAPI ThiningDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
    {

    // 指向源图像的指针
    LPSTR lpSrc;

    // 指向缓存图像的指针
    LPSTR lpDst;

    // 指向缓存DIB图像的指针
    LPSTR lpNewDIBBits;
    HLOCAL hNewDIBBits;
    LONG lLineBytes=WIDTHBYTES(lWidth * 8);
    //脏标记
    BOOL bModified; //循环变量
    long i;
    long j;
    int  n;
    int  m; //四个条件
    BOOL bCondition1;
    BOOL bCondition2;
    BOOL bCondition3;
    BOOL bCondition4;
    bool bNotCondition5; //计数器
    unsigned char nCount;

    //像素值
    unsigned char pixel; //5×5相邻区域像素值
    unsigned char neighbour[5][5]; // 暂时分配内存,以保存新图像
    hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); if (hNewDIBBits == NULL)
    {
    // 分配内存失败
    return FALSE;
    }

    // 锁定内存
    lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化新分配的内存,设定初始值为255
    lpDst = (char *)lpNewDIBBits;
    memset(lpDst, (BYTE)255,lLineBytes * lHeight); bModified=TRUE; while(bModified)
    { bModified = FALSE;
    // 初始化新分配的内存,设定初始值为255
    lpDst = (char *)lpNewDIBBits;
    memset(lpDst, (BYTE)255, lLineBytes* lHeight); for(j = 2; j <lHeight-2; j++)
    {
    for(i = 2;i <lWidth-2; i++)
    { bCondition1 = FALSE;
    bCondition2 = FALSE;
    bCondition3 = FALSE;
    bCondition4 = FALSE;
    bNotCondition5=true; //由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素 // 指向源图像倒数第j行,第i个象素的指针
    lpSrc = (char *)lpDIBBits + lLineBytes * j + i; // 指向目标图像倒数第j行,第i个象素的指针
    lpDst = (char *)lpNewDIBBits + lLineBytes * 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)*lLineBytes + 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;
    if(neighbour[1][2]+neighbour[1][1]+neighbour[2][1]+
    neighbour[3][1]+neighbour[3][2]+neighbour[3][3]+
    neighbour[2][3]+neighbour[1][3]==1)
    bNotCondition5=false;

    //判断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&&bNotCondition5)
    {
    *lpDst = (unsigned char)255;
    bModified = TRUE;
    }
    else
    {
    *lpDst = (unsigned char)0;
    }
    }
    }
    // 复制腐蚀后的图像
    memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
    }
    // 复制腐蚀后的图像
    memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); // 释放内存
    LocalUnlock(hNewDIBBits);
    LocalFree(hNewDIBBits); // 返回
    return TRUE;
    }