形态学细化指纹图像

您所在的位置:网站首页 指纹形态 形态学细化指纹图像

形态学细化指纹图像

2024-07-14 12:22| 来源: 网络整理| 查看: 265

        基于指纹细化有一种算法叫OPTA(one-pass thinning algorithm),基于该算法有些缺点,如毛刺较多。所以有一种基于形态学的细化算法。

       一个好的细化算法应该遵守如下一些要求:收敛性、连通性、拓扑性、保持性、细化性、中轴性和快速性。

收敛性:迭代必须是收敛的;

连通性:不破坏纹线的连接性;

拓扑性:保持原图像的基本结构特性;

保持性:保护指纹的细节特征;

细化性:骨架纹线的宽度为1个像素,即单像素宽;(单像素的定义:端点,连接点,分叉点在其8领域的前景点个数分别为1,2,3,其实我觉得这个定义是不对的。)

中轴性:骨架尽可能地接近条纹中心线;

快速性:算法简单,速度快。

  

        宏观的总结一句话:形态学细化就是在不是端点的边界处的点才能删除,删除后如果不改变拓扑结构和连通性就可以删除

        

简单列举了8邻域的几种情况

(1)不可以删除,不是边界点。

(2)不可以删除,不是边界点。

(3)可以删除,是边界点,左边界的点且删除后不改变拓扑性和连通性。

(4)不可以删除,删除后改变了连通性。

(5)可以删除,是边界点,是左边界和下边界的点且删除后不改变拓扑行和连通性。

(6)不可以删除,是端点

     那我们就一次从上下左右4个方向依次对图像进行细化,直到每个方向都细化完成后那么整幅指纹就细化完成了。

 

void Thinning() { IplImage* pMark = cvCreateImage(cvGetSize(m_pSkelImage), IPL_DEPTH_8U, 1); cvSetZero(pMark); for(int i = 0; i < 4; i++) no_more[i] = 0; int thin_dir = UP; while(!(no_more[0] && no_more[1] && no_more[2] && no_more[3])) { if(!no_more[thin_dir]) thin(m_pSkelImage, thin_dir, pMark); thin_dir = next_thin_dir(thin_dir); } cvReleaseImage(&pMark); } // The one-pixel wide border has been set as zero. void thin(IplImage* img, int thin_dir, IplImage* pMark) { int y, x; switch(thin_dir) { case DOWN : for(y = 1 ; y < m_iHeight - 1; y ++) for(x = 1; x < m_iWidth - 1; x ++) if(IMG(img,y,x) == 1) if(IMG(img,y-1,x) == 0) check_neighbors_8simple_down(img,pMark,y,x); break; case UP : for(y = 1 ; y < m_iHeight - 1; y ++) for(x = 1; x < m_iWidth - 1; x ++) if(IMG(img,y,x) == 1) if(IMG(img,y+1,x) == 0) check_neighbors_8simple_up(img,pMark,y,x); break; case LEFT : for(y = 1 ; y < m_iHeight - 1; y ++) for(x = 1; x < m_iWidth - 1; x ++) if(IMG(img,y,x) == 1) if(IMG(img,y,x+1) == 0) check_neighbors_8simple_left(img,pMark,y,x); break; case RIGHT : for(y = 1 ; y < m_iHeight - 1; y ++) for(x = 1; x < m_iWidth - 1; x ++) if(IMG(img,y,x) == 1) if(IMG(img,y,x-1) == 0) check_neighbors_8simple_right(img,pMark,y,x); break; } bool bChange = false; for(y = 1; y < m_iHeight - 1; y ++) { for(x = 1; x < m_iWidth - 1; x ++) { if(IMG(pMark,y,x) == 1) { IMG(img,y,x) = 0; IMG(pMark,y,x) = 0; bChange = true; } } } if(!bChange) no_more[thin_dir] = 1; } int next_thin_dir(int thin_dir) { int next_dir; switch(thin_dir) { case UP : next_dir=LEFT; break; case RIGHT : next_dir=DOWN; break; case DOWN : next_dir=UP; break; case LEFT : next_dir=RIGHT; break; } return next_dir; } void check_neighbors_8simple_down(IplImage* img, IplImage* pMark, int y, int x) { int neighbors = IMG(img,y-1,x-1) + IMG(img,y-1,x+1) + IMG(img,y,x+1) + IMG(img,y+1,x+1) + IMG(img,y+1,x) + IMG(img,y+1,x-1) + IMG(img,y,x-1); if(neighbors == 1) return; if( IMG(img,y,x+1) == 0 && IMG(img,y-1,x+1) == 1 ) return; if( IMG(img,y,x-1) == 0 && IMG(img,y-1,x-1) == 1 ) return; if( IMG(img,y+1,x) == 0 ) if( IMG(img,y,x+1) == 1 || IMG(img,y+1,x+1) == 1 ) if(IMG(img,y,x-1) ==1 || IMG(img,y+1,x-1) == 1 ) return; IMG(pMark,y,x) = 1; } void check_neighbors_8simple_up(IplImage* img, IplImage* pMark, int y, int x) { int neighbors = IMG(img,y-1,x-1) + IMG(img,y-1,x+1) + IMG(img,y,x+1) + IMG(img,y+1,x+1) + IMG(img,y-1,x) + IMG(img,y+1,x-1) + IMG(img,y,x-1); if(neighbors == 1) return; if( IMG(img,y,x+1) == 0 && IMG(img,y+1,x+1) == 1 ) return; if( IMG(img,y,x-1) == 0 && IMG(img,y+1,x-1) == 1 ) return; if( IMG(img,y-1,x) == 0 ) if( IMG(img,y,x+1) == 1 || IMG(img,y-1,x+1) == 1 ) if(IMG(img,y,x-1) || IMG(img,y-1,x-1) == 1 ) return; IMG(pMark,y,x) = 1; } void check_neighbors_8simple_left(IplImage* img, IplImage* pMark, int y, int x) { int neighbors = IMG(img,y-1,x-1) + IMG(img,y-1,x+1) + IMG(img,y-1,x) + IMG(img,y+1,x+1) + IMG(img,y+1,x) + IMG(img,y+1,x-1) + IMG(img,y,x-1); if(neighbors == 1) return; if( IMG(img,y-1,x) == 0 && IMG(img,y-1,x+1) == 1 ) return; if( IMG(img,y+1,x) == 0 && IMG(img,y+1,x+1) == 1 ) return; if( IMG(img,y,x-1) == 0 ) if( IMG(img,y-1,x-1) == 1 || IMG(img,y-1,x) == 1 ) if(IMG(img,y+1,x-1) ==1 || IMG(img,y+1,x) == 1 ) return; IMG(pMark,y,x) = 1; } void check_neighbors_8simple_right(IplImage* img, IplImage* pMark, int y, int x) { int neighbors = IMG(img,y-1,x-1) + IMG(img,y-1,x+1) + IMG(img,y-1,x) + IMG(img,y+1,x+1) + IMG(img,y+1,x) + IMG(img,y+1,x-1) + IMG(img,y,x+1); if(neighbors == 1) return; if( IMG(img,y-1,x) == 0 && IMG(img,y-1,x-1) == 1 ) return; if( IMG(img,y+1,x) == 0 && IMG(img,y+1,x-1) == 1 ) return; if( IMG(img,y,x+1) == 0 ) if( IMG(img,y-1,x) == 1 || IMG(img,y-1,x+1) == 1 ) if(IMG(img,y+1,x) ==1 || IMG(img,y+1,x+1) == 1 ) return; IMG(pMark,y,x) = 1; }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3