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

通过学习,掌握以下几个问题:
1、核心算法,并且向GVF衍生;
2、核心库封装的方法
2016年11月16日06:52:51
昨日实现了梯度场和频率场的计算。最大的感觉就是建立基础代码库的重要性。
如果使用opencv或者别的代码库,可能它也能实现一些功能,特别对于建立在感官上的效果,差别不大。但是,如果是用于数学计算的,特别是对于我现在还不是很清楚过程,也不是很清楚结果的算法来说,精确的、容易比对的代码更重要。在这种时候,我更愿意采取原始的、按照定义实现的计算方法。
在昨天的频度场计算中,我突破好几天的困扰,直接按照定义修改代码,比如计算频度场
int main( int argc, char** 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 main( int argc, char** 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;
    }
 
}
了现在的代码,下一步就可以思考如何对自然环境下的许多图像进行增强了。
 
 
 
 





本资源是以压缩包形式的,里面是一个pdf格式电子书(完整版)。有需要的朋友可以下载。 本书作者: 李昊 傅曦(编著); 本书出版社:人民邮电出版社 内容简介: 《精通VisualC++指纹模式识别系统算法及现实》共5篇。第一篇讲解指纹模式识别系统入门知识,包括指纹模式识别系统演示系统指纹学基础,引导读者快速入门;第二篇讲解指纹模式识别系统算法,包括指纹模式识别预处理和指纹图像特征提取与比对的源代码实现;第三篇讲解如何亲手打造指纹模式识别系统,带领读者制作一个指纹模式识别系统的软硬件系统;第四篇讲解指纹模式识别应用技术基础,包括指纹模式识别技术各类应用的系统构造和源代码实现;第五篇讲解指纹电子产品技术和指纹电子产品的发展创业,包括指纹电子证件系统指纹识别电子产品以及数字指纹技术的创业规划。 《精通VisualC++指纹模式识别系统算法及现实》适合指纹模式识别技术的初学者、指纹识别电子产品工程师以及打算投身指纹模式识别领域的创业者阅读。 推荐理由: 免费公开了VisualC++指纹模式识别系统源代码 带领读者一步一步亲手制作一个指纹识别系统 深度剖析真实的行业应用案例 业界专家强力推荐 部分章节目录: 目录: 第一篇 指纹模式识别系统入门 第1章 指纹模式识别演示轻松入门 3 1.1 体验VisualC++指纹模式识别演示系统 3 1.1.1 VisualC++指纹模式识别演示系统的安装与使用 3 1.1.2 VisualBasic指纹模式识别演示系统的安装与使用 5 1.2 指纹模式识别系统的市场应用前景 8 1.3 指纹模式识别系统的学习方法 10 第2章 轻松接触传统指纹学和数字指纹学 11 2.1 指纹学的历史 11 2.2 传统指纹学 13 2.2.1 指纹卡片 14 2.2.2 指纹分析 16 2.2.3 传统人工指纹比对 16 2.3 数字指纹学概述 18 2.3.1 计算机视觉原理 19 2.3.2 数字指纹学与传统指纹学的关系 21 2.3.3 数字指纹学的方法 23 第3章 轻松自创指纹模式识别演示 26 3.1 动手创建一个VisualC++程序 26 3.1.1 初步了解VisualC++工具环境 26 3.1.2 用VisualC++向导创建程序工程 27 3.2 编程接入VisualC++指纹算法程序代码 30 3.2.1 改造自建VisualC++程序界面 30 3.2.2 编程接入C++指纹算法程序代码实例 34 3.3 使用开发环境自创指纹模式识别演示系统 38 3.3.1 VisualC++指纹模式识别开发环境简介 38 3.3.2 自建VisualC++指纹模式识别演示系统 38 3.3.3 VisualC++指纹模式识别开发环境详细说明 40 3.3.4 指纹图像BMP位图的读取 42 3.3.5 指纹图像的灰度模型 49 3.4 编制可移植VisualC++指纹识别源代码的要点 51 第二篇 指纹模式识别系统算法 第4章 指纹模式识别系统算法总论 55 4.1 指纹模式和指纹模式识别的发展历程 55 4.1.1 指纹的模式对象、模式特征对象、模式类型对象 55 4.1.2 指纹模式和指纹模式识别的发展历程 60 4.1.3 指纹模式的数据结构和数字图像文件表示 62 4.2 指纹模式识别系统算法的组成及流程 62 4.2.1 指纹模式识别系统算法组成概述 62 4.2.2 指纹模式识别系统算法实现流程 64 第5章 指纹模式识别的预处理 68 5.1 指纹数学建模与图像的畸变矫正 68 5.1.1 指纹图像畸变的自然模型 68 5.1.2 指纹图像畸变的物理模型 69 5.1.3 指纹图像畸变矫正的数学模型 70 5.1.4 指纹图像畸变矫正的C++源代码实现 78 5.2 指纹图像场及其计算 82 5.2.1 指纹图像场的自然模型 82 5.2.2 指纹图像场的物理模型 82 5.2.3 指纹图像场的数学模型 84 5.2.4 指纹图像场能计算的源代码实现 85 5.3 指纹图像的分割 88 5.3.1 计算强度场分割指纹图像 89 5.3.2 计算梯度场分割指纹图像 89 5.3.3 指纹图像分割的C++源代码实现 91 5.4 指纹图像的均衡 93 5.4.1 指纹图像灰度失衡的自然模型 93 5.4.2 指纹图像灰度失衡的物理模型 94 5.4.3 指纹图像灰度均衡的数学建模 95 5.4.4 指纹图像灰度均衡的C++源代码实现 97 5.5 指纹图像的收敛 99 5.5.1 指纹图像混沌发散的自然模型 99 5.5.2 指纹图像混沌发散的物理模型 100 5.5.3 指纹图像混沌发散的数学模型 101 5.5.4 指纹图像收敛的C++源代码实现 103 5.6 指纹图像的平滑 106 5.6.1 指纹图像噪声嘈杂的自然模型 107 5.6.2 指纹图像噪声嘈杂的物理模型 107 5.6.3 指纹图像平滑噪声的数学模型 108 5.6.4 指纹图像平滑噪声的C++源代码实现 109 5.7 指纹图像的智能增强 111 5.7.1 指纹图像智能增强的自然模型 111 5.7.2 指纹图像智能增强的物理模型 111 5.7.3 指纹图像智能增强的数学模型 113 5.7.4 指纹图像智能增强的C++源代码实现 114 5.8 指纹图像骨架的提取准备 117 5.8.1 指纹图像二值化模型 118 5.8.2 指纹图像智能二值化C++源代码实现 119 5.8.3 指纹图像去噪声处理C++源代码实现 123 5.9 指纹图像骨架的细化提取 126 5.9.1 指纹图像细化方法 127 5.9.2 指纹图像细化方法C++源代码实现 127 5.9.3 指纹图像细化后处理C++源代码实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值