将开源虹膜识别算法OSIRIS4.1移植到Windows

开源虹膜识别算法OSIRIS是在Linux下运行的,为了介绍给众多windows平台下的开发者,这里简述一下如何把它移植到windows。

开发平台Windows XP + Visual Studio 2008 + OpenCV2.3.1

1.新建一个对话框工程,将OSIRIS源码中的如下文件拷贝过去并添加到工程:

  1. OsiCircle.cpp/.h  
  2. OsiEye.cpp/.h  
  3. OsiManager.cpp/.h  
  4. OsiProcessings.cpp/.h  
  5. OsiStringUtils.h  

2.在上述源码中,只需要对OsiManager.cpp/.h做少量修改即可使用了:

OsiManager.cpp

  1. #include <fstream>  
  2. #include <iterator>  
  3. #include <stdexcept>  
  4. #include "OsiManager.h"  
  5. #include "OsiStringUtils.h"  
  6.   
  7. using namespace std ;  
  8.   
  9. namespace osiris  
  10. {  
  11.     OsiManager::OsiManager ( )  
  12.     {  
  13.         initConfiguration() ;     
  14.   
  15.     loadGaborFilters() ;  
  16.     loadApplicationPoints() ;  
  17.     }  
  18.   
  19.     OsiManager::~OsiManager ( )  
  20.     {  
  21.         if ( mpApplicationPoints )  
  22.         {  
  23.             cvReleaseMat(&mpApplicationPoints) ;  
  24.         }  
  25.           
  26.         for ( int f = 0 ; f < mGaborFilters.size() ; f++ )  
  27.         {  
  28.             cvReleaseMat(&mGaborFilters[f]) ;  
  29.         }  
  30.     }  
  31.   
  32.     void OsiManager::initConfiguration ( )  
  33.     {  
  34.         // Options of processing  
  35.         mProcessSegmentation = false ;  
  36.         mProcessNormalization = false ;  
  37.         mProcessEncoding = false ;  
  38.         mProcessMatching = false ;  
  39.         mUseMask = true ;  
  40.   
  41.         // Inputs  
  42.         mListOfImages.clear() ;  
  43.         mFilenameListOfImages = "" ;  
  44.         mInputDirOriginalImages = "./SourceImage/" ;  
  45.         mInputDirMasks = "" ;  
  46.         mInputDirParameters = "" ;  
  47.         mInputDirNormalizedImages = "" ;  
  48.         mInputDirNormalizedMasks = "./NormalizedMasks/" ;  
  49.         mInputDirIrisCodes = "./IrisCodes/" ;  
  50.   
  51.         // Outputs  
  52.         mOutputDirSegmentedImages = "./SegmentedImages/" ;  
  53.         mOutputDirParameters = "./CircleParameters/" ;  
  54.         mOutputDirMasks = "./Masks/" ;  
  55.         mOutputDirNormalizedImages = "./NormalizedImages/" ;  
  56.         mOutputDirNormalizedMasks = "./NormalizedMasks/" ;  
  57.         mOutputDirIrisCodes = "./IrisCodes/" ;  
  58.         mOutputFileMatchingScores = "" ;  
  59.   
  60.         // Parameters  
  61.         mMinPupilDiameter = 50 ;  
  62.         mMaxPupilDiameter = 160 ;  
  63.         mMinIrisDiameter = 160 ;  
  64.         mMaxIrisDiameter = 280 ;  
  65.         mWidthOfNormalizedIris = 512 ;  
  66.         mHeightOfNormalizedIris = 64 ;  
  67.         mFilenameGaborFilters = "./filters.txt" ;  
  68.         mFilenameApplicationPoints = "./points.txt" ;  
  69.         mGaborFilters.clear() ;  
  70.         mpApplicationPoints = 0 ;  
  71.   
  72.         // Suffix for filenames  
  73.         mSuffixSegmentedImages = "_segm.bmp" ;  
  74.         mSuffixParameters = "_para.txt" ;  
  75.         mSuffixMasks = "_mask.bmp" ;  
  76.         mSuffixNormalizedImages = "_imno.bmp" ;  
  77.         mSuffixNormalizedMasks = "_mano.bmp" ;  
  78.         mSuffixIrisCodes = "_code.bmp" ;  
  79.     }  
  80.   
  81.     void OsiManager::loadGaborFilters ( )  
  82.     {  
  83.     //不修改  
  84.     }  
  85.   
  86.     void OsiManager::loadApplicationPoints ( )  
  87.     {  
  88.     //不修改  
  89.     }  
  90.   
  91.     int OsiManager::processEye ( const string & rFileName , OsiEye & rEye )  
  92.     {  
  93.         // Strings handle  
  94.         OsiStringUtils osu ;  
  95.         // Get eye name  
  96.         string short_name = osu.extractFileName(rFileName);  
  97.         rEye.loadOriginalImage(mInputDirOriginalImages+rFileName);   
  98.       
  99.         /////////////////////////////////////////////////////////////////  
  100.         // SEGMENTATION : process, load  
  101.          rEye.segment(mMinIrisDiameter,mMinPupilDiameter,mMaxIrisDiameter,mMaxPupilDiameter) ;  
  102.         // Save segmented image  
  103.         rEye.saveSegmentedImage(mOutputDirSegmentedImages+short_name+mSuffixSegmentedImages) ;  
  104.   
  105.         /////////////////////////////////////////////////////////////////  
  106.         // NORMALIZATION : process, load  
  107.         rEye.normalize(mWidthOfNormalizedIris,mHeightOfNormalizedIris) ;  
  108.   
  109.         /////////////////////////////////////////////////////////////////  
  110.         // ENCODING : process, load  
  111.         rEye.encode(mGaborFilters) ;  
  112.   
  113.         /////////////////////////////////////////////////////////////////  
  114.         // SAVE  
  115.         // Save parameters  
  116.         rEye.saveParameters(mOutputDirParameters+short_name+mSuffixParameters) ;  
  117.         // Save mask  
  118.         rEye.saveMask(mOutputDirMasks+short_name+mSuffixMasks) ;  
  119.         // Save normalized image  
  120.         rEye.saveNormalizedImage(mOutputDirNormalizedImages+short_name+mSuffixNormalizedImages) ;  
  121.         // Save normalized mask  
  122.         rEye.saveNormalizedMask(mOutputDirNormalizedMasks+short_name+mSuffixNormalizedMasks) ;  
  123.         // Save iris code  
  124.         rEye.saveIrisCode(mOutputDirIrisCodes+short_name+mSuffixIrisCodes) ;    
  125.   
  126.         return 0;  
  127.     } // end of function  
  128.   
  129.     int OsiManager::loadEye ( const string & rFileName , OsiEye & rEye )  
  130.     {  
  131.         OsiStringUtils osu ;  
  132.         string short_name = osu.extractFileName(rFileName) ;  
  133.   
  134.         // Load normalized mask  
  135.         rEye.loadNormalizedMask(mInputDirNormalizedMasks+short_name+mSuffixNormalizedMasks) ;  
  136.   
  137.         // Load iris code  
  138.         rEye.loadIrisCode(mInputDirIrisCodes+short_name+mSuffixIrisCodes) ;  
  139.   
  140.         return 0;  
  141.     } // end of function  
  142.   
  143.     void OsiManager::process(string filename)  
  144.     {  
  145.         try  
  146.         {  
  147.             OsiEye eye ;  
  148.             processEye(filename, eye) ;    
  149.         }  
  150.         catch ( exception & e )  
  151.         {  
  152.             cout << e.what() << endl ;                  
  153.         }  
  154.     }  
  155.   
  156.     float OsiManager::match(string filename1, string filename2)  
  157.     {  
  158.         float val = 0;  
  159.   
  160.         try  
  161.         {  
  162.             OsiEye eye1, eye2 ;  
  163.             loadEye(filename1, eye1) ;    
  164.             loadEye(filename2, eye2) ;   
  165.             val = eye1.match(eye2, mpApplicationPoints);  
  166.         }  
  167.         catch ( exception & e )  
  168.         {  
  169.             cout << e.what() << endl ;                  
  170.         }  
  171.   
  172.         return val;  
  173.     }  
  174.   
  175. // end of namespace  

OsiManager.h
  1. #ifndef OSI_MANAGER_H  
  2. #define OSI_MANAGER_H  
  3.   
  4. #include <iostream>  
  5. #include <vector>  
  6. #include "highgui.h"  
  7. #include "OsiEye.h"  
  8.   
  9. namespace osiris  
  10. {  
  11.     class OsiManager  
  12.     {  
  13.     public :  
  14.         OsiManager ( ) ;  
  15.         ~OsiManager ( ) ;  
  16.   
  17.     void process(std::string filename);  
  18.     float match(std::string filename1, std::string filename2);  
  1.     private :  
  2.         //private变量不修改  
  3.   
  4.         // Private methods  
  5.         //////////////////  
  6.         void initConfiguration ( ) ;  
  7.         void loadGaborFilters ( ) ;  
  8.         void loadApplicationPoints ( ) ;  
  9.   
  10.     int processEye ( const std::string & rFileName , OsiEye & rEye );  
  11.     int loadEye ( const std::string & rFileName , OsiEye & rEye );  
  12.     } ; // End of class  
  13. // End of namespace  
  14. #endif  

可见,主要是增加了两个接口函数process()和match(),分别用于虹膜计算和虹膜对比;

3.在对话框程序中新建一个button:

  1. void CosirismfcDlg::OnBnClickedButton1()  
  2. {  
  3.     cvNamedWindow("img", 1);  
  4.     cvNamedWindow("segment", 1);  
  5.   
  6.     IplImage* img1 = cvLoadImage( "./SourceImage/S5000R00.jpg", CV_LOAD_IMAGE_GRAYSCALE );  
  7.     cvShowImage( "img", img1 );  
  8.     theManager.process("S5000R00.jpg");  
  9.     IplImage* seg1 = cvLoadImage( "./SegmentedImages/S5000R00_segm.bmp", CV_LOAD_IMAGE_COLOR );  
  10.     cvShowImage( "segment", seg1 );  
  11.   
  12.     cvNamedWindow("img2", 1);  
  13.     cvNamedWindow("segment2", 1);  
  14.     IplImage* img2 = cvLoadImage( "./SourceImage/S5000R01.jpg", CV_LOAD_IMAGE_GRAYSCALE );  
  15.     cvShowImage( "img2", img2 );  
  16.     theManager.process("S5000R01.jpg");  
  17.     IplImage* seg2 = cvLoadImage( "./SegmentedImages/S5000R01_segm.bmp", CV_LOAD_IMAGE_COLOR );  
  18.     cvShowImage( "segment2", seg2 );  
  19.   
  20.     if (theManager.match("S5000R00.jpg","S5000R01.jpg") < 0.32)  
  21.         MessageBox("S5000R00 and S5000R01 is same person");  
  22.   
  23.     cvNamedWindow("img3", 1);  
  24.     cvNamedWindow("segment3", 1);  
  25.     IplImage* img3 = cvLoadImage( "./SourceImage/S5001R01.jpg", CV_LOAD_IMAGE_GRAYSCALE );  
  26.     cvShowImage( "img3", img3 );  
  27.     theManager.process("S5001R01.jpg");  
  28.     IplImage* seg3 = cvLoadImage( "./SegmentedImages/S5001R01_segm.bmp", CV_LOAD_IMAGE_COLOR );  
  29.     cvShowImage( "segment3", seg3 );  
  30.   
  31.     if (theManager.match("S5000R00.jpg","S5001R01.jpg") > 0.32)  
  32.         MessageBox("S5000R00 and S5001R01 is not same person");  
  33. }  

该button读取两张来自同一个人的虹膜图像,对比结果应当小于0.32;读取两张不同人的虹膜图像,对比结果应当大于0.32。

虹膜识别都要先进行process步骤,再进行match步骤。


4.把工程属性修改为不使用预编译头,编译;


5.在Release或Debug目录下新建如下几个文件夹:

  1. CircleParameters  
  2. IrisCodes  
  3. Masks  
  4. NormalizedImages  
  5. NormalizedMasks  
  6. SegmentedImages  
  7. SourceImage  

向SourceImage目录中拷贝如下示例虹膜图像:
  1. S5000R00.bmp  
  2. S5000R01.bmp  
  3. S5000R02.bmp  
  4. S5001R00.bmp  
  5. S5001R01.bmp  
  6. S5001R02.bmp  

并从OSIRIS源码中拷贝如下两个文件:
  1. filters.txt  
  2. points.txt  

然后就可运行exe文件了,运行结果:

将开源虹膜识别算法OSIRIS4.1移植到Windows



本文完整工程可在qq群里下载:
虹膜识别算法研究QQ群:422376177