精通visual c++指纹模式识别系统算法及实现

简介: 通过学习,掌握以下几个问题:1、核心算法,并且向GVF衍生;2、核心库封装的方法2016年11月16日06:52:51昨日实现了梯度场和频率场的计算。最大的感觉就是建立基础代码库的重要性。如果使用opencv或者别的代码库,可能它也能实现一些功能,特别对于建立在感官上的效果,差别不大。

通过学习,掌握以下几个问题:
1、核心算法,并且向GVF衍生;
2、核心库封装的方法
2016年11月16日06:52:51
昨日实现了梯度场和频率场的计算。最大的感觉就是建立基础代码库的重要性。
如果使用opencv或者别的代码库,可能它也能实现一些功能,特别对于建立在感官上的效果,差别不大。但是,如果是用于数学计算的,特别是对于我现在还不是很清楚过程,也不是很清楚结果的算法来说,精确的、容易比对的代码更重要。在这种时候,我更愿意采取原始的、按照定义实现的计算方法。
在昨天的频度场计算中,我突破好几天的困扰,直接按照定义修改代码,比如计算频度场
int mainint argcchar** argv )
{
    Mat src = imread2gray("E:\\template\\1.bmp");
    src.convertTo(src,CV_8U);//255的运算
    pyrDown(src,src);
    Mat dst;//结果
    dst.create(src.size(),src.type());   
 
    int IMGH =src.rows;    
    int IMGW =src.cols;  
    int gradSum;
    int grad;
    long  vxvylvxlvy;
 
    unsigned char   *lpSrc = NULL;
    unsigned char   *lpOri = NULL;
    long    anglenum;
    double  fAngle;
    int r = 6;
    int i;int j;
    for (int y = 0;y<IMGH-1;y++)
    {
        for (int x=0;x<IMGW-1;x++)
        {
            lpOri = dst.ptr<uchar>(0) + y*IMGW + x;
            lvx = 0;
            lvy = 0;
            num = 0;
            for(i = -ri <= ri++)    // 为提高速度,步长为
            {
                if(y+i<1 || y+i>=IMGH-1) continue;
                for(j = -rj <= rj++)    // 为提高速度,步长为
                {
                    if(x+j<1 || x+j>=IMGW-1) continue;
                    lpSrc = src.ptr<uchar>(0) + (y+i)*(IMGW) + x+j;
                    //求x方向偏导
                    vx = *(lpSrc + IMGW + 1) - *(lpSrc + IMGW - 1) +
                        *(lpSrc + 1)*2 - *(lpSrc - 1)*2 +
                        *(lpSrc - IMGW + 1) - *(lpSrc - IMGW - 1);
                    //求y方向偏导
                    vy = *(lpSrc + IMGW - 1) - *(lpSrc - IMGW - 1) +
                        *(lpSrc + IMGW)*2 - *(lpSrc - IMGW)*2 +
                        *(lpSrc + IMGW + 1) - *(lpSrc - IMGW + 1);
 
                    lvx += vx * vy * 2;//sin(2sita)
                    lvy += vx*vx - vy*vy;//cos(2sita)
                    num++;
                }
            }
 
            if(num == 0) num = 1;
            // 求弧度
            fAngle = atan2((float)lvy, (float)lvx);
            // 变换到(0 - 2*pi)
            if(fAngle < 0)    fAngle += 2*PI;
 
            // 求纹线角度
            fAngle = (fAngle*EPI*0.5 + 0.5);
            angle = (long)fAngle;
 
            // 因为采用sobel算子,所以角度偏转了度,所以要旋转求得的角度
            angle -= 135;
            // 角度变换到(-180)
            if(angle <= 0)    angle += 180;
 
            angle = 180-angle;
            // 最终纹线角度
            *lpOri = (unsigned char)angle;
            *(lpOri + 1) = (unsigned char)angle;
            *(lpOri + IMGW) = (unsigned char)angle;
            *(lpOri + IMGW + 1) = (unsigned char)angle;
        }
    }
     
    pyrUp(dst,dst);
    imwrite("e:/sandbox/n1dst.bmp",dst);
    return 0;
}
这样从结果的面上来看,已经是非常接近书中给出的效果了。
下一步,专门成立GOGVF项目作为GOCVHelper的一个部分,逐步地改造现有代码库,实现书中的效果。并且向GOGVF的按照定义实现做出努力。
 
2016年11月16日06:52:51 已经逐步移植代码,从梯度一直做到了增强。虽然现在的代码还有一些问题,但是基本不影响使用。并且生成了专门的GOGVF库,用于收集这方面的代码。
虽然这本书很精彩,里面的代码对于我来说都是右开创性的;但是不可否认很多地方,他的代码写的还是比较繁琐、冗余的,给阅读移植带来了不少困难。
使用的情况是这样的
int mainint argcchar** argv )
{
    Mat src = imread2gray("E:\\template\\2.bmp");
    Mat grad = getGrads(src); //梯度场
    Mat org = getOrientMap(src); //方向场
    Mat seg;
    segment(grad,seg); //对梯度场进行阈值,seg为分割结果
    segment_clearEdge(src,org,seg);//反馈到src和org中了,这种方法倒也是方便
    Mat equ = src.clone();
    //cv::equalizeHist(src,equ);
    equalize(src,equ);
    Mat gauss = src.clone();
    GaussSmooth(equ,gauss,0.4);
    Mat smo = src.clone();
    smooth(gauss,smo,1,1);
    orientEnhance(org,smo);
    orientEnhance(org,smo);
    imshow("dst",smo);
    waitKey(0);
    return 0;
}
原始图像
梯度图像,可以看到,在指纹比较密集的地方,梯度很强,而在背景区域,比较干净。
通过梯度场,可以背景前景分离。
方向场。基本上是表示了指纹线段角度的变化。特别观察中间的位置,由255跳跃至0,是因为在中间的部分,指纹几乎是水平的。
  
gaobor增强,现在在细节部分还有一点问题,但是已经基本体现出来特点了。
这是我第一次自己写代码实现gabor的效果,也是深入理解gabor的一次。回头思考,指纹识别其实是很好的算法平台,因为采集到的图片,本身背景前景分割还是比较干净的;在以前,如果处理这样的图片,我可能会选择阈值分割这种直观的方法;在实现了frangi算法之后,很多时候我会拿frangi来实验一下,看看效果。但是这次试用gabor增强,应该说是给我增加了一种新的思路,以后的眼界会更宽阔。。
gaobor增强的核心,是对前面计算出来的梯度场中的“纹线方向进行平滑滤波,纹线 的竖直方向进行锐化滤波
。那么首先就是要计算处正确的梯度场来。在本例中,图片质量比较好,能够通过几乎是定义计算的方法计算出正确稳定的梯度场(但是在其他很多地方,可能不能这样使用?用什么计算出正确的梯度场,作为一个专门的话题)。然后就是通过对梯度进行增强。这里才是实现gaobor的地方。这里贴出的是实现的代码,推导过程分帖说明。关键就是“量化“。
int DDIndex(int angle)
{
    /////////////////////////////////////////////////////////////////////////
    //    angle: [in] 角度 (0 - 180)
    /////////////////////////////////////////////////////////////////////////
    if(angle >= 173 || angle < 8)
    {
        return 0;
    }
    else
    {
        return ((angle-8)/15 + 1);
    }
}
 
void orientEnhance(Mat org,Matdst)
{
    int xy;
    int i;
    int d = 0;
    int sum = 0;
    // 纹线方向上进行平滑滤波的平滑滤波器
    int Hw[7] = {1, 1, 1, 1, 1, 1, 1};
    // 纹线方向的垂直方向上进行锐化滤波的锐化滤波器
    int Vw[7] = {-3, -1, 3, 9, 3, -1, -3};
    int hsum = 0;
    int vsum = 0;
    int temp = 0;
    int IMGW = org.cols;
    int IMGH = org.rows;
 
    BYTE  *lpSrc = NULL;
    BYTE  *lpDir = NULL;
 
    BYTE *g_lpOrient = org.ptr<uchar>(0);
    BYTE *g_lpOrgFinger = dst.ptr<uchar>(0);
    BYTE *g_lpTemp = dst.ptr<uchar>(0);
    //BYTE *g_lpTemp = new BYTE[IMGW * IMGH];
 
    // 纹线方向上进行平滑滤波
    temp = 0;
    for(y = 0; y < IMGHy++)
    {
        for(x = 0; x < IMGWx++)
        {
            lpDir = g_lpOrient + temp + x;
            lpSrc = g_lpOrgFinger + temp + x;
            // 纹线方向的索引
            d = DDIndex(*lpDir);
            sum = 0;
            hsum = 0;
            for(i = 0; i < 7; i++)
            {
                if(y+g_DDSite[d][i][1] < 0 || y+g_DDSite[d][i][1] >= IMGH ||
                    x+g_DDSite[d][i][0] < 0 || x+g_DDSite[d][i][0] >= IMGW)
                {
                    continue;
                }
                sum += Hw[i]*(*(lpSrc + g_DDSite[d][i][1]*IMGW + g_DDSite[d][i][0]));
                hsum += Hw[i];
            }
            if(hsum != 0)
            {
                *(g_lpTemp + temp + x) = (BYTE)(sum/hsum);
            }
            else
            {
                *(g_lpTemp + temp + x) = 255;
            }
        }
        temp += IMGW;
    }
 
    // 纹线方向的垂直方向上进行锐化滤波
    temp = 0;
    for(y = 0; y < IMGHy++)
    {
        for(x = 0; x < IMGWx++)
        {
            lpDir = g_lpOrient + temp + x;
            lpSrc = g_lpTemp + temp + x;
 
            // 纹线方向的垂直方向的索引
            d = (DDIndex(*lpDir)+6) % 12;
 
            sum = 0;
            vsum = 0;
            for(i = 0; i < 7; i++)
            {
                if(y+g_DDSite[d][i][1] < 0 || y+g_DDSite[d][i][1] >= IMGH ||
                    x+g_DDSite[d][i][0] < 0 || x+g_DDSite[d][i][0] >= IMGW)
                {
                    continue;
                }
                sum += Vw[i]*(*(lpSrc + g_DDSite[d][i][1]*IMGW + g_DDSite[d][i][0]));
                vsum += Vw[i];
            }
            if(vsum > 0)
            {
                sum /= vsum;
                if(sum > 255)
                {
                    *(g_lpOrgFinger + temp + x) = 255;
                }
                else if(sum < 0)
                {
                    *(g_lpOrgFinger + temp + x) = 0;
                }
                else
                {
                    *(g_lpOrgFinger + temp + x) = (BYTE)sum;
                }
            }
            else
            {
                *(g_lpOrgFinger + temp + x) = 255;
            }
        }
        temp += IMGW;
    }
 
}
了现在的代码,下一步就可以思考如何对自然环境下的许多图像进行增强了。
 
 
 
 





目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com
目录
相关文章
|
2月前
|
存储 监控 算法
基于 C++ 哈希表算法实现局域网监控电脑屏幕的数据加速机制研究
企业网络安全与办公管理需求日益复杂的学术语境下,局域网监控电脑屏幕作为保障信息安全、规范员工操作的重要手段,已然成为网络安全领域的关键研究对象。其作用类似网络空间中的 “电子眼”,实时捕获每台电脑屏幕上的操作动态。然而,面对海量监控数据,实现高效数据存储与快速检索,已成为提升监控系统性能的核心挑战。本文聚焦于 C++ 语言中的哈希表算法,深入探究其如何成为局域网监控电脑屏幕数据处理的 “加速引擎”,并通过详尽的代码示例,展现其强大功能与应用价值。
71 1
|
3月前
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。
|
4月前
|
运维 监控 算法
解读 C++ 助力的局域网监控电脑网络连接算法
本文探讨了使用C++语言实现局域网监控电脑中网络连接监控的算法。通过将局域网的拓扑结构建模为图(Graph)数据结构,每台电脑作为顶点,网络连接作为边,可高效管理与监控动态变化的网络连接。文章展示了基于深度优先搜索(DFS)的连通性检测算法,用于判断两节点间是否存在路径,助力故障排查与流量优化。C++的高效性能结合图算法,为保障网络秩序与信息安全提供了坚实基础,未来可进一步优化以应对无线网络等新挑战。
|
2月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
86 17
|
2月前
|
存储 监控 算法
基于 C# 的局域网计算机监控系统文件变更实时监测算法设计与实现研究
本文介绍了一种基于C#语言的局域网文件变更监控算法,通过事件驱动与批处理机制结合,实现高效、低负载的文件系统实时监控。核心内容涵盖监控机制选择(如事件触发机制)、数据结构设计(如监控文件列表、事件队列)及批处理优化策略。文章详细解析了C#实现的核心代码,并提出性能优化与可靠性保障措施,包括批量处理、事件过滤和异步处理等技术。最后,探讨了该算法在企业数据安全监控、文件同步备份等场景的应用潜力,以及未来向智能化扩展的方向,如文件内容分析、智能告警机制和分布式监控架构。
59 3
|
1月前
|
机器学习/深度学习 存储 算法
基于 C++ 布隆过滤器算法的局域网上网行为控制:URL 访问过滤的高效实现研究
本文探讨了一种基于布隆过滤器的局域网上网行为控制方法,旨在解决传统黑白名单机制在处理海量URL数据时存储与查询效率低的问题。通过C++实现URL访问过滤功能,实验表明该方法可将内存占用降至传统方案的八分之一,查询速度提升约40%,假阳性率可控。研究为优化企业网络管理提供了新思路,并提出结合机器学习、改进哈希函数及分布式协同等未来优化方向。
35 0
|
1月前
|
算法 5G 定位技术
高低频混合组网系统中基于地理位置信息的信道测量算法matlab仿真
本内容展示了一种基于地理位置信息的信道测量算法,适用于现代蜂窝系统,尤其在毫米波通信中,波束对准成为关键步骤。算法通过信号传播模型和地理信息实现信道状态测量,并优化误差提升准确性。完整程序基于Matlab2022a运行,无水印效果,核心代码配有中文注释及操作视频,适合深入学习与应用开发。
|
1月前
|
机器学习/深度学习 监控 算法
面向办公室屏幕监控系统的改进型四叉树屏幕变化检测算法研究
本文提出一种改进型四叉树数据结构模型,用于优化办公室屏幕监控系统。通过动态阈值调节、变化优先级索引及增量更新策略,显著降低计算复杂度并提升实时响应能力。实验表明,该算法在典型企业环境中将屏幕变化检测效率提升40%以上,同时减少资源消耗。其应用场景涵盖安全审计、工作效能分析及远程协作优化等,未来可结合深度学习实现更智能化的功能。
38 0
|
3月前
|
存储 监控 算法
基于 C++ 哈希表算法的局域网如何监控电脑技术解析
当代数字化办公与生活环境中,局域网的广泛应用极大地提升了信息交互的效率与便捷性。然而,出于网络安全管理、资源合理分配以及合规性要求等多方面的考量,对局域网内计算机进行有效监控成为一项至关重要的任务。实现局域网内计算机监控,涉及多种数据结构与算法的运用。本文聚焦于 C++ 编程语言中的哈希表算法,深入探讨其在局域网计算机监控场景中的应用,并通过详尽的代码示例进行阐释。
81 4
|
4月前
|
存储 算法 安全
企业员工数据泄露防范策略:基于 C++ 语言的布隆过滤器算法剖析[如何防止员工泄密]
企业运营过程中,防范员工泄密是信息安全领域的核心议题。员工泄密可能致使企业核心数据、商业机密等关键资产的流失,进而给企业造成严重损失。为应对这一挑战,借助恰当的数据结构与算法成为强化信息防护的有效路径。本文专注于 C++ 语言中的布隆过滤器算法,深入探究其在防范员工泄密场景中的应用。
76 8