开源虹膜识别算法OSIRIS是在Linux下运行的,为了介绍给众多windows平台下的开发者,这里简述一下如何把它移植到windows。
开发平台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);</code></pre><pre><code class="language-cpp"> 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群里下载:
虹膜识别算法研究QQ群:422376177
扫码加入: