I'm trying to use an SDK called VeriFinger, from Neurotechnology, to process a BMP file containing a fingerprint capture (for enhancement), and save it to a new BMP file.
VeriFinger comes with a few tutorials and samples, the main one being called FingersSampleWX.
It looks like this:
Following this application's source code as a guide, I was able to assemble this piece of code which should do what I want, or so I believe:
#include <iostream>
#include <NLicensing.hpp>
#include <NMedia.hpp>
#include <NBiometrics.hpp>
using namespace Neurotec::Biometrics;
using namespace Neurotec::Images;
using namespace Neurotec::Licensing;
int main()
{
if (NLicense::ObtainComponents("/local", "5000", "Biometrics.FingerExtraction"))
std::wcout << L"License OK\n";
else
std::wcout << L"License fail\n";
NFinger finger;
finger.SetFileName("F:\\input\\000001\\MDT1.BMP");
finger.SetPosition(nfpUnknown);
finger.SetImpressionType(nfitNonliveScanPlain);
// testing
auto test1 = finger.GetFileName();
auto test2 = finger.GetImage();
auto test3 = finger.GetProcessedImage();
NImage image(NULL);
if (finger.GetHandle())
{
image = finger.GetProcessedImage();
if (image.GetHandle())
image.Save("F:\\output\\000001\\MDT1_out.bmp");
}
NLicense::ReleaseComponents("Biometrics.FingerExtraction");
}
However, the image won't save. For some reason, the line if (image.GetHandle())
returns false
. That's why I added the testing
section.
Checking the value of test2
and test3
using the debugger tells me:
handle=0x00000000 isDisposed=false
GetProcessedImage()
returns NULL
, which is very weird, because test1
returns the file name of the finger
object correctly. I'm sure missing something... Been struggling with this for a few hours now.
VeriFinger is available as a 30-day trial (700MB). The SDK documentation is located in the Documentation
folder in both CHM and PDF formats.
Thanks.
In order for the image saving to work, one must first:
define an object of type Client::NBiometricClient
call its member function SetFingersReturnProcessedImage()
using the true
as argument
define an object of type NSubject
call its member function SetId()
which takes an argument of type NStringWrapper
- this type has a default constructor for C-style strings (null-terminated char arrays), same as finger.SetFileName()
from the example in the question
call another of its member function, GetFingers()
, and call Add()
on the returned object, using as argument for Add()
the object of type NFinger
which was defined previously (it's called finger
in the question body)
define an object of type NBiometricTask
and initialize it with a call to another member function from the object defined at step 1, which is CreateTask()
and takes two arguments: nboEnroll
(an enum) and NULL
call its member function GetSubjects()
and call Add()
on the returned object, using as argument for Add()
the object defined at step 3
call another member function from the object defined at step 1, this one's PerformTask()
, using as argument the object defined at step 6.
It looks simpler in practice:
// (previous code from question)
NFinger finger;
finger.SetFileName("F:\\input\\000001\\MDT1.BMP");
finger.SetPosition(nfpUnknown);
finger.SetImpressionType(nfitNonliveScanPlain);
// Needed initializations:
Client::NBiometricClient m_biometricClient;
m_biometricClient.SetFingersReturnProcessedImage(true);
NBiometricTask task = m_biometricClient.CreateTask(nboEnroll, NULL);
NSubject subject;
subject.SetId("F:\\input\\000001\\MDT1.BMP"); // I'm just using the filename as argument as its purpose is rather temporary
subject.GetFingers().Add(finger);
task.GetSubjects().Add(subject);
m_biometricClient.PerformTask(task);
// ok, everything should work now
// (...)
Thanks to user3791372 for pointing me in the right direction.