C++ Windows生物识别框架从指纹传感器提取图像
我正试图从指纹传感器中提取指纹图像 我的第一个指纹传感器(113x115)工作得很好 电流传感器(114x57)给了我一个嘈杂的图像 该代码已根据传感器数据(尺寸、填充、宽度、高度)进行了调整 ImgCompressionAlg=0 像素深度=8C++ Windows生物识别框架从指纹传感器提取图像,c++,windows,fingerprint,biometrics,windows-hello,C++,Windows,Fingerprint,Biometrics,Windows Hello,我正试图从指纹传感器中提取指纹图像 我的第一个指纹传感器(113x115)工作得很好 电流传感器(114x57)给了我一个嘈杂的图像 该代码已根据传感器数据(尺寸、填充、宽度、高度)进行了调整 ImgCompressionAlg=0 像素深度=8 #include "stdafx.h" #include "Strsafe.h" using namespace std; //------------------------------------------------------------
#include "stdafx.h"
#include "Strsafe.h"
using namespace std;
//-----------------------------------------------------------------------------
// Forward declarations of local functions for Private Pool Setup.
HRESULT CaptureSample();
bool SaveBMP(BYTE* buffer, int width, int height, int pixelPerVertical, int pixelPerHorizontal, long paddedsize, LPCTSTR bmpfile, BYTE* firstPixel);
//-----------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = S_OK;
hr = CaptureSample();
_tprintf(_T("Capture Sample: hr = 0x%x\n"), hr);
std::cin;
return 0;
}
//-----------------------------------------------------------------------------
HRESULT CaptureSample()
{
restart:
HRESULT hr = S_OK;
WINBIO_SESSION_HANDLE sessionHandle = NULL;
WINBIO_UNIT_ID unitId = 0;
WINBIO_REJECT_DETAIL rejectDetail = 0;
PWINBIO_BIR sample = NULL;
SIZE_T sampleSize = 0;
PWINBIO_UNIT_SCHEMA unitSchema = NULL;
SIZE_T unitCount = 0;
SIZE_T index = 0;
ofstream ofs;
string name;
// Connect to the system pool.
hr = WinBioOpenSession(
WINBIO_TYPE_FINGERPRINT, // Service provider
WINBIO_POOL_SYSTEM, // Pool type
WINBIO_FLAG_RAW, // Access: Capture raw data
NULL, // Array of biometric unit IDs
0, // Count of biometric unit IDs
WINBIO_DB_DEFAULT, // Default database
&sessionHandle // [out] Session handle
);
if (FAILED(hr))
{
wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr);
goto e_Exit;
}
// Enumerate the installed biometric units.
hr = WinBioEnumBiometricUnits(
WINBIO_TYPE_FINGERPRINT, // Type of biometric unit
&unitSchema, // Array of unit schemas
&unitCount); // Count of unit schemas
if (FAILED(hr))
{
wprintf_s(L"\n WinBioEnumBiometricUnits failed. hr = 0x%x\n", hr);
goto e_Exit;
}
// Display information for each installed biometric unit.
wprintf_s(L"\nSensors: \n");
for (index = 0; index < unitCount; ++index)
{
wprintf_s(L"\n[%d]: \tUnit ID: %d\n",
index,
unitSchema[index].UnitId);
wprintf_s(L"\tDevice instance ID: %s\n",
unitSchema[index].DeviceInstanceId);
wprintf_s(L"\tPool type: %d\n",
unitSchema[index].PoolType);
wprintf_s(L"\tBiometric factor: %d\n",
unitSchema[index].BiometricFactor);
wprintf_s(L"\tSensor subtype: %d\n",
unitSchema[index].SensorSubType);
wprintf_s(L"\tSensor capabilities: 0x%08x\n",
unitSchema[index].Capabilities);
wprintf_s(L"\tDescription: %s\n",
unitSchema[index].Description);
wprintf_s(L"\tManufacturer: %s\n",
unitSchema[index].Manufacturer);
wprintf_s(L"\tModel: %s\n",
unitSchema[index].Model);
wprintf_s(L"\tSerial no: %s\n",
unitSchema[index].SerialNumber);
wprintf_s(L"\tFirmware version: [%d.%d]\n",
unitSchema[index].FirmwareVersion.MajorVersion,
unitSchema[index].FirmwareVersion.MinorVersion);
}
wprintf_s(L"\n Pick a Sensor: ");
int i;
std::cin >> i;
unitId = unitSchema[i].UnitId;
// Capture a biometric sample.
wprintf_s(L"\n Calling WinBioCaptureSample - Swipe sensor...\n");
hr = WinBioCaptureSample(
sessionHandle,
WINBIO_NO_PURPOSE_AVAILABLE,
WINBIO_DATA_FLAG_RAW,
&unitId,
&sample,
&sampleSize,
&rejectDetail
);
if (FAILED(hr))
{
if (hr == WINBIO_E_BAD_CAPTURE)
{
wprintf_s(L"\n Bad capture; reason: %d\n", rejectDetail);
}
else
{
wprintf_s(L"\n WinBioCaptureSample failed. hr = 0x%x\n", hr);
}
goto e_Exit;
}
wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId);
wprintf_s(L"\n Captured %d bytes.\n", sampleSize);
PWINBIO_BIR_HEADER BirHeader = (PWINBIO_BIR_HEADER) (((PBYTE)sample) + sample->HeaderBlock.Offset); //header points to the offset of the header block
PWINBIO_BDB_ANSI_381_HEADER AnsiBdbHeader = (PWINBIO_BDB_ANSI_381_HEADER)(((PBYTE)sample) + sample->StandardDataBlock.Offset); //header points to the beginning of the standard data block
PWINBIO_BDB_ANSI_381_RECORD AnsiBdbRecord = (PWINBIO_BDB_ANSI_381_RECORD)(((PBYTE)AnsiBdbHeader) + sizeof(WINBIO_BDB_ANSI_381_HEADER)); //record points to the record of the standard data block
BYTE* firstPixel = (BYTE*)((BYTE*)AnsiBdbRecord) + sizeof(WINBIO_BDB_ANSI_381_RECORD); //points to the data of first pixel
wprintf_s(L"\n ID: %d\n", AnsiBdbHeader->ProductId.Owner);
wprintf_s(L" Horizontal Img. Res.: %d\n", AnsiBdbHeader->HorizontalImageResolution);
wprintf_s(L" Horizontal Scan Img. Res.: %d pixels/centimeter\n", AnsiBdbHeader->HorizontalScanResolution);
wprintf_s(L" Vertical Img. Res.: %d\n", AnsiBdbHeader->VerticalImageResolution);
wprintf_s(L" Vertical Scan Img. Res.: %d pixels/centimeter\n", AnsiBdbHeader->VerticalScanResolution);
wprintf_s(L" Pixel Depth: %d\n", AnsiBdbHeader->PixelDepth); //number of bits in one pixel
wprintf_s(L" Element Count: %d\n", AnsiBdbHeader->ElementCount); //number of images
wprintf_s(L" Width: %d\n", AnsiBdbRecord->HorizontalLineLength);
wprintf_s(L" Height: %d\n", AnsiBdbRecord->VerticalLineLength);
wprintf_s(L" Blocklength: %d\n", AnsiBdbRecord->BlockLength);
wprintf_s(L" Compression Algorithm: %d\n", AnsiBdbHeader->ImageCompressionAlg);
wprintf_s(L" Address of First Pixel in HEX: 0x%x\n", firstPixel);
wprintf_s(L" Address of First Pixel in DEC: %d\n", firstPixel);
//AnsiBdbRecord->BlockLength is size of data + record header
long blocklength = AnsiBdbRecord->BlockLength - sizeof(AnsiBdbRecord); //blocklength is size of raw image data
//long size = sizeof(char) * 4;
bool b = SaveBMP(firstPixel, AnsiBdbRecord->HorizontalLineLength, AnsiBdbRecord->VerticalLineLength, AnsiBdbRecord->VerticalLineLength, AnsiBdbRecord->HorizontalLineLength, blocklength, L"C:\\Users\ChickenDuy\Documents\bio_key_extraction\bio_key_extraction\bio_key_extraction\fingerprint.bmp", firstPixel);
if (b) {
wprintf_s(L"\n SaveBMP succeeded");
}
else {
wprintf_s(L"\n SaveBMP failed");
}
e_Exit:
if (sample != NULL)
{
WinBioFree(sample);
sample = NULL;
}
if (unitSchema != NULL)
{
WinBioFree(unitSchema);
unitSchema = NULL;
}
if (sessionHandle != NULL)
{
WinBioCloseSession(sessionHandle);
sessionHandle = NULL;
}
wprintf_s(L"\n Press 0 to repeat.\n Press 1 to exit\n. ");
std::cin >> i;
if (i == 0) {
goto restart;
}
return hr;
}
bool SaveBMP(BYTE* buffer, int width, int height, int pixelPerVertical, int pixelPerHorizontal, long data_size, LPCTSTR bmpfile, BYTE* firstPixel) {
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER info;
memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
memset(&info, 0, sizeof(BITMAPINFOHEADER));
//long sizeOfColorTable = 4*255*sizeof(char); //size of the color table is 00-FF with a four byte coding RGB0
int padding = 4 - (width % 4); //calculate the padding needed
bmfh.bfType = 19778; // Don't question it. Magic Word (B and M). It's necessary. Seriously.
bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + data_size; //size of the whole bitmap
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); //start position of data after the header
info.biSize = sizeof(BITMAPINFOHEADER); //size of the bitmap info header
info.biWidth = width; //width of the bitmap
info.biHeight = height; //height of the bitmap
info.biPlanes = 1; //dimensions of the image
info.biBitCount = 8; //encoding of raw data -> 8 bits per pixel
info.biCompression = 0; //compression algorithm
info.biSizeImage = (width*sizeof(char) + padding*sizeof(char))*height; //size of image data in bytes including padding
info.biXPelsPerMeter = pixelPerHorizontal;
info.biYPelsPerMeter = pixelPerVertical;
info.biClrUsed = 0;
info.biClrImportant = 0;
ofstream bmp("fingerprint.bmp", ios::binary | ios::trunc | ios::out); //open as output and binary file and delete everything in the current .bmp file
if (bmp.is_open()) {
wprintf_s(L"\n Opening BMP successful\n");
bmp.write((char*)&bmfh, sizeof(BITMAPFILEHEADER)); //write BitmapFileHeader
bmp.write((char*)&info, sizeof(BITMAPINFOHEADER)); //write BitmapInfoHeader
}
else {
wprintf_s(L"\n Opening BMP failed\n");
return false;
}
//char pixelArray[pWidth][pHeight]; //create a pixel array with the size of the image
char pixelArray[1];
BYTE* pixel = new BYTE;
pixel = &(*firstPixel); //new pointer to the first pixel
int* x = 0;
////grey index color array
for (int i = 0; i < 256; i++) {
bmp.write((char*) &i, sizeof(char)); //write red
bmp.write((char*) &i, sizeof(char)); //write green
bmp.write((char*) &i, sizeof(char)); //write blue
bmp.write((char*) &x, sizeof(char)); //write 0
//wprintf(L"\n Saving Color: %x %x %x %x", i, i, i, 0);
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
memset(&pixelArray[0], *pixel, sizeof(char)); //get data from sample and save into array
bmp.write((char*)&pixelArray[0], sizeof(char)); //save pixel to bitmap
pixel = &(*pixel) + sizeof(char); //set pointer to the next byte
//wprintf(L"\n Saving PixelArray[%d][%d] 0x%x", j, i, *pixel);
}
//113 pixels * 3 bytes = 339 bytes -> missing 1 byte (bio_key) because 24bit/3byte pixel depth
//114 pixels * 1 byte = 114 bytes -> missing 2 bytes (small sensor) because 8bit/1byte pixel depth
for (int j = 0; j < padding; j++) {
bmp.write((char*)&x, sizeof(char)); //pad to a multiple of 4 bytes
//wprintf(L"\n Saving PixelArray[%d][%d] 0x%x", 115, i, 0);
}
}
bmp.close();
return true;
}
#包括“stdafx.h”
#包括“Strsafe.h”
使用名称空间std;
//-----------------------------------------------------------------------------
//为专用池设置转发本地函数声明。
HRESULT CaptureSample();
bool SaveBMP(字节*缓冲区、整数宽度、整数高度、整数像素反常、整数像素水平、长填充大小、LPCTSTR bmpfile、字节*第一像素);
//-----------------------------------------------------------------------------
int _tmain(int argc,_TCHAR*argv[]
{
HRESULT hr=S_正常;
hr=CaptureSample();
_tprintf(_T(“捕获样本:hr=0x%x\n”),hr);
性病:cin;
返回0;
}
//-----------------------------------------------------------------------------
HRESULT CaptureSample()
{
重新启动:
HRESULT hr=S_正常;
WINBIO_SESSION_HANDLE sessionHandle=NULL;
WINBIO\u单元ID unitId=0;
WINBIO_拒绝_拒绝细节=0;
PWINBIO_BIR sample=NULL;
大小\u T样本大小=0;
PWINBIO_UNIT_SCHEMA unitSchema=NULL;
大小\u T单位计数=0;
尺寸指数=0;
流的速度;
字符串名;
//连接到系统池。
hr=WinBioOpenSession(
WINBIO_类型_指纹,//服务提供商
WINBIO\u池\u系统,//池类型
WINBIO_FLAG_RAW,//访问:捕获原始数据
NULL,//生物识别单元ID数组
0,//生物识别单元ID的计数
WINBIO_DB_DEFAULT,//默认数据库
&sessionHandle//[out]会话句柄
);
如果(失败(小时))
{
wprintf_s(L“\n WinBioOpenSession失败。hr=0x%x\n”,hr);
转到e_出口;
}
//列举已安装的生物识别装置。
hr=WinbioNumbiometricunits(
WINBIO_类型_指纹,//生物识别装置的类型
&unitSchema,//单元架构数组
&unitCount);//单元架构的计数
如果(失败(小时))
{
wprintf_s(L“\n WinBioEnumBiometricUnits失败。hr=0x%x\n”,hr);
转到e_出口;
}
//显示每个已安装生物识别装置的信息。
wprintf_s(L“\n传感器:\n”);
对于(索引=0;索引<单位计数;++索引)
{
wprintf_s(L“\n[%d]:\t IT ID:%d\n”,
指数
unitSchema[index].UnitId);
wprintf_s(L“\t设备实例ID:%s\n”,
unitSchema[index].DeviceInstanceId);
wprintf\u s(L“\t工具类型:%d\n”,
unitSchema[index].PoolType);
wprintf_s(L“\t生物测量因子:%d\n”,
UNITSHEMA[索引]。生物特征因子);
wprintf_s(L“\t传感器子类型:%d\n”,
unitSchema[index].SensorSubType);
wprintf_s(L“\t传感器功能:0x%08x\n”,
unitSchema[index]。功能);
wprintf_s(L“\t说明:%s\n”,
unitSchema[index].Description);
wprintf\u s(L“\t制造商:%s\n”,
unitSchema[index]。制造商);
wprintf_s(L“\t模型:%s\n”,
unitSchema[index].Model);
wprintf_s(L“\t序列号:%s\n”,
unitSchema[index].SerialNumber);
wprintf_s(L“\t固件版本:[%d.%d]\n”,
unitSchema[index].FirmwareVersion.MajorVersion,
unitSchema[index].FirmwareVersion.MinorVersion);
}
wprintf_s(L“\n选择一个传感器:”);
int i;
标准:cin>>i;
unitId=unitSchema[i].unitId;
//捕获生物特征样本。
wprintf_s(L“\n调用WinBioCaptureSample-滑动传感器…\n”);
hr=WinBioCaptureSample(
会话句柄,
WINBIO_没有可用的目的,
WINBIO_数据_标志_原始,
&尤尼德,
&样本,
&抽样,
&拒绝细节
);
如果(失败(小时))
{
如果(hr==WINBIO\u E\u BAD\u捕获)
{
wprintf_s(L“\n错误捕获;原因:%d\n”,拒绝详细信息);
}
其他的
{
wprintf_s(L“\n WinBioCaptureSample失败。hr=0x%x\n”,hr);
}
转到e_出口;
}
wprintf_s(L“\n刷卡已处理-单元ID:%d\n”,单元ID);
wprintf_s(L“\n捕获了%d个字节。\n”,采样);
PWINBIO_BIR_HEADER BIR HEADER=(PWINBIO_BIR_HEADER)((PBYTE)sample)+sample->HeaderBlock.Offset);//头指向头块的偏移量
PWINBIO_BDB_ANSI_381_HEADER AnsiBdbHeader=(PWINBIO_BDB_ANSI_381_HEADER)((PBYTE)sample)+sample->StandardDataBlock.Offset);//头指向标准数据块的开头
PWINBIO_BDB_ANSI_381_RECORD AnsiBdbRecord=(PWINBIO_BDB_ANSI_381_RECORD)((PBYTE)AnsiBdbHeader)+sizeof(WINBIO_BDB_ANSI_381_HEADER))//记录指向标准数据块的记录
BYTE*firstPixel=(BYTE*)((BYTE*)AnsiBdbRecord)+sizeof(WINBIO_BDB_ANSI_381_RECORD);//指向第一个像素的数据
wprintf_s(L“\n ID:%d\n”,AnsiBdbHeader->ProductId.Owner);
wprintf_s(L“水平图像分辨率:%d\n”,AnsibdHeader->HorizontalImageResolution);
wprintf_s(L“水平扫描图像分辨率:%d像素/厘米”,AnsibdHeader->水平扫描分辨率);
wprintf_s(L“垂直图像分辨率:%d\n”,AnsibdHeader->VerticalImageResolution);
wprintf_s(L“垂直扫描图像分辨率:%d像素/厘米”,AnsibdHeader->VerticalScanResolution);
wprintf_s(L“像素深度:%d\n”,AnsiBdbHeader->PixelDepth);//一个像素中的位数
wprintf_s(L“元素计数:%d\n”,AnsiBdbHeader->ElementCount);//图像数
wprintf_s(L“宽度:%d\n”,AnsiBdbRecord->HorizontalLineLength);
wprintf_s(L“高度:%d\n”,AnsiBdbRecord->VerticalLineLength