Я пытаюсь извлечь изображения отпечатков пальцев из моих датчиков отпечатков пальцев.
С моим первым датчиком отпечатков пальцев (113×115) он отлично работает.
Датчик тока (114х57) дает мне шумное изображение.
Код был адаптирован к данным датчика (размер, отступ, ширина, высота).
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;
}
Надеюсь, кто-нибудь сможет помочь.
Задача ещё не решена.
Других решений пока нет …