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

时间:2017-05-26 12:31:36

标签: c++ windows fingerprint biometrics windows-hello

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

使用我的第一个指纹传感器(113x115),效果很好。

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

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

ImgCompressionAlg = 0;

PixelDepth = 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;
}

Sensor 1

Sensor 2

希望有人能够提供帮助。

0 个答案:

没有答案