将开源虹膜识别算法OSIRIS4.1移植到Windows
开源虹膜识别算法OSIRIS是在Linux下运行的,为了介绍给众多windows平台下的开发者,这里简述一下如何把它移植到windows。
开发平台Windows XP + Visual Studio 2008 + OpenCV2.3.1。
OsiManager.h
可见,主要是增加了两个接口函数process()和match(),分别用于虹膜计算和虹膜对比;
向SourceImage目录中拷贝如下示例虹膜图像:
并从OSIRIS源码中拷贝如下两个文件:
虹膜识别算法研究QQ群:422376177
开发平台Windows XP + Visual Studio 2008 + OpenCV2.3.1。
1.新建一个对话框工程,将OSIRIS源码中的如下文件拷贝过去并添加到工程:
- OsiCircle.cpp/.h
- OsiEye.cpp/.h
- OsiManager.cpp/.h
- OsiProcessings.cpp/.h
- OsiStringUtils.h
2.在上述源码中,只需要对OsiManager.cpp/.h做少量修改即可使用了:
OsiManager.cpp- #include <fstream>
- #include <iterator>
- #include <stdexcept>
- #include "OsiManager.h"
- #include "OsiStringUtils.h"
- using namespace std ;
- namespace osiris
- {
- OsiManager::OsiManager ( )
- {
- initConfiguration() ;
- loadGaborFilters() ;
- loadApplicationPoints() ;
- }
- OsiManager::~OsiManager ( )
- {
- if ( mpApplicationPoints )
- {
- cvReleaseMat(&mpApplicationPoints) ;
- }
- for ( int f = 0 ; f < mGaborFilters.size() ; f++ )
- {
- cvReleaseMat(&mGaborFilters[f]) ;
- }
- }
- void OsiManager::initConfiguration ( )
- {
- // Options of processing
- mProcessSegmentation = false ;
- mProcessNormalization = false ;
- mProcessEncoding = false ;
- mProcessMatching = false ;
- mUseMask = true ;
- // Inputs
- mListOfImages.clear() ;
- mFilenameListOfImages = "" ;
- mInputDirOriginalImages = "./SourceImage/" ;
- mInputDirMasks = "" ;
- mInputDirParameters = "" ;
- mInputDirNormalizedImages = "" ;
- mInputDirNormalizedMasks = "./NormalizedMasks/" ;
- mInputDirIrisCodes = "./IrisCodes/" ;
- // Outputs
- mOutputDirSegmentedImages = "./SegmentedImages/" ;
- mOutputDirParameters = "./CircleParameters/" ;
- mOutputDirMasks = "./Masks/" ;
- mOutputDirNormalizedImages = "./NormalizedImages/" ;
- mOutputDirNormalizedMasks = "./NormalizedMasks/" ;
- mOutputDirIrisCodes = "./IrisCodes/" ;
- mOutputFileMatchingScores = "" ;
- // Parameters
- mMinPupilDiameter = 50 ;
- mMaxPupilDiameter = 160 ;
- mMinIrisDiameter = 160 ;
- mMaxIrisDiameter = 280 ;
- mWidthOfNormalizedIris = 512 ;
- mHeightOfNormalizedIris = 64 ;
- mFilenameGaborFilters = "./filters.txt" ;
- mFilenameApplicationPoints = "./points.txt" ;
- mGaborFilters.clear() ;
- mpApplicationPoints = 0 ;
- // Suffix for filenames
- mSuffixSegmentedImages = "_segm.bmp" ;
- mSuffixParameters = "_para.txt" ;
- mSuffixMasks = "_mask.bmp" ;
- mSuffixNormalizedImages = "_imno.bmp" ;
- mSuffixNormalizedMasks = "_mano.bmp" ;
- mSuffixIrisCodes = "_code.bmp" ;
- }
- void OsiManager::loadGaborFilters ( )
- {
- //不修改
- }
- void OsiManager::loadApplicationPoints ( )
- {
- //不修改
- }
- int OsiManager::processEye ( const string & rFileName , OsiEye & rEye )
- {
- // Strings handle
- OsiStringUtils osu ;
- // Get eye name
- string short_name = osu.extractFileName(rFileName);
- rEye.loadOriginalImage(mInputDirOriginalImages+rFileName);
- /////////////////////////////////////////////////////////////////
- // SEGMENTATION : process, load
- rEye.segment(mMinIrisDiameter,mMinPupilDiameter,mMaxIrisDiameter,mMaxPupilDiameter) ;
- // Save segmented image
- rEye.saveSegmentedImage(mOutputDirSegmentedImages+short_name+mSuffixSegmentedImages) ;
- /////////////////////////////////////////////////////////////////
- // NORMALIZATION : process, load
- rEye.normalize(mWidthOfNormalizedIris,mHeightOfNormalizedIris) ;
- /////////////////////////////////////////////////////////////////
- // ENCODING : process, load
- rEye.encode(mGaborFilters) ;
- /////////////////////////////////////////////////////////////////
- // SAVE
- // Save parameters
- rEye.saveParameters(mOutputDirParameters+short_name+mSuffixParameters) ;
- // Save mask
- rEye.saveMask(mOutputDirMasks+short_name+mSuffixMasks) ;
- // Save normalized image
- rEye.saveNormalizedImage(mOutputDirNormalizedImages+short_name+mSuffixNormalizedImages) ;
- // Save normalized mask
- rEye.saveNormalizedMask(mOutputDirNormalizedMasks+short_name+mSuffixNormalizedMasks) ;
- // Save iris code
- rEye.saveIrisCode(mOutputDirIrisCodes+short_name+mSuffixIrisCodes) ;
- return 0;
- } // end of function
- int OsiManager::loadEye ( const string & rFileName , OsiEye & rEye )
- {
- OsiStringUtils osu ;
- string short_name = osu.extractFileName(rFileName) ;
- // Load normalized mask
- rEye.loadNormalizedMask(mInputDirNormalizedMasks+short_name+mSuffixNormalizedMasks) ;
- // Load iris code
- rEye.loadIrisCode(mInputDirIrisCodes+short_name+mSuffixIrisCodes) ;
- return 0;
- } // end of function
- void OsiManager::process(string filename)
- {
- try
- {
- OsiEye eye ;
- processEye(filename, eye) ;
- }
- catch ( exception & e )
- {
- cout << e.what() << endl ;
- }
- }
- float OsiManager::match(string filename1, string filename2)
- {
- float val = 0;
- try
- {
- OsiEye eye1, eye2 ;
- loadEye(filename1, eye1) ;
- loadEye(filename2, eye2) ;
- val = eye1.match(eye2, mpApplicationPoints);
- }
- catch ( exception & e )
- {
- cout << e.what() << endl ;
- }
- return val;
- }
- } // end of namespace
OsiManager.h
- #ifndef OSI_MANAGER_H
- #define OSI_MANAGER_H
- #include <iostream>
- #include <vector>
- #include "highgui.h"
- #include "OsiEye.h"
- namespace osiris
- {
- class OsiManager
- {
- public :
- OsiManager ( ) ;
- ~OsiManager ( ) ;
- void process(std::string filename);
- float match(std::string filename1, std::string filename2);
- private :
- //private变量不修改
- // Private methods
- //////////////////
- void initConfiguration ( ) ;
- void loadGaborFilters ( ) ;
- void loadApplicationPoints ( ) ;
- int processEye ( const std::string & rFileName , OsiEye & rEye );
- int loadEye ( const std::string & rFileName , OsiEye & rEye );
- } ; // End of class
- } // End of namespace
- #endif
可见,主要是增加了两个接口函数process()和match(),分别用于虹膜计算和虹膜对比;
3.在对话框程序中新建一个button:
- void CosirismfcDlg::OnBnClickedButton1()
- {
- cvNamedWindow("img", 1);
- cvNamedWindow("segment", 1);
- IplImage* img1 = cvLoadImage( "./SourceImage/S5000R00.jpg", CV_LOAD_IMAGE_GRAYSCALE );
- cvShowImage( "img", img1 );
- theManager.process("S5000R00.jpg");
- IplImage* seg1 = cvLoadImage( "./SegmentedImages/S5000R00_segm.bmp", CV_LOAD_IMAGE_COLOR );
- cvShowImage( "segment", seg1 );
- cvNamedWindow("img2", 1);
- cvNamedWindow("segment2", 1);
- IplImage* img2 = cvLoadImage( "./SourceImage/S5000R01.jpg", CV_LOAD_IMAGE_GRAYSCALE );
- cvShowImage( "img2", img2 );
- theManager.process("S5000R01.jpg");
- IplImage* seg2 = cvLoadImage( "./SegmentedImages/S5000R01_segm.bmp", CV_LOAD_IMAGE_COLOR );
- cvShowImage( "segment2", seg2 );
- if (theManager.match("S5000R00.jpg","S5000R01.jpg") < 0.32)
- MessageBox("S5000R00 and S5000R01 is same person");
- cvNamedWindow("img3", 1);
- cvNamedWindow("segment3", 1);
- IplImage* img3 = cvLoadImage( "./SourceImage/S5001R01.jpg", CV_LOAD_IMAGE_GRAYSCALE );
- cvShowImage( "img3", img3 );
- theManager.process("S5001R01.jpg");
- IplImage* seg3 = cvLoadImage( "./SegmentedImages/S5001R01_segm.bmp", CV_LOAD_IMAGE_COLOR );
- cvShowImage( "segment3", seg3 );
- if (theManager.match("S5000R00.jpg","S5001R01.jpg") > 0.32)
- MessageBox("S5000R00 and S5001R01 is not same person");
- }
该button读取两张来自同一个人的虹膜图像,对比结果应当小于0.32;读取两张不同人的虹膜图像,对比结果应当大于0.32。
虹膜识别都要先进行process步骤,再进行match步骤。
4.把工程属性修改为不使用预编译头,编译;
5.在Release或Debug目录下新建如下几个文件夹:
- CircleParameters
- IrisCodes
- Masks
- NormalizedImages
- NormalizedMasks
- SegmentedImages
- SourceImage
向SourceImage目录中拷贝如下示例虹膜图像:
- S5000R00.bmp
- S5000R01.bmp
- S5000R02.bmp
- S5001R00.bmp
- S5001R01.bmp
- S5001R02.bmp
并从OSIRIS源码中拷贝如下两个文件:
- filters.txt
- points.txt
然后就可运行exe文件了,运行结果:
虹膜识别算法研究QQ群:422376177