C++ Windows生物识别框架从指纹传感器提取图像

C++ 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; //------------------------------------------------------------

我正试图从指纹传感器中提取指纹图像

我的第一个指纹传感器(113x115)工作得很好

电流传感器(114x57)给了我一个嘈杂的图像

该代码已根据传感器数据(尺寸、填充、宽度、高度)进行了调整

ImgCompressionAlg=0

像素深度=8

#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