所以我几乎在终点线上感觉到了。我正在研究工作所需的指纹识别器项目。需要在1月中旬完成所以我需要这个工作:)
我一直在互联网上跳来寻找已经从我的读者那里获取图像的图书馆,我被提到了Griaule。长话短说,经过多次挫折之后,我得出结论,Griaule已经过时了,太复杂了,不应该做的太多,太昂贵,总体来说太难以正常工作。
所以我决定采用另一种方法,我使用Microsoft提供的示例,然后在获得图像后使用另一个库来处理处理。
我现在处于扫描指纹然后制作BMP文件的位置。但文件的宽高比很奇怪。它看起来很高并且挤压在一起,即使(如果存储器服务)扫描仪应该具有更高的分辨率。
控制台写出图像应为256 x 360
,但我必须将该宽度除以3才能使图像正常工作。所以它出现的85x360
看起来并不合适。
所以这是将图像保存为BMP的功能:
bool SaveBMP(BYTE* buffer, int width, int height, long paddedsize, LPCTSTR bmpfile) {
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER info;
memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
memset(&info, 0, sizeof(BITMAPINFOHEADER));
bmfh.bfType = 0x4d42; // Don't question it. Magic Word (B and M). It's necessary. Seriously.
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+paddedsize;
bmfh.bfOffBits = 0x36;
info.biSize = sizeof(BITMAPINFOHEADER);
info.biWidth = width;
info.biHeight = height;
info.biPlanes = 1;
info.biBitCount = 24;
info.biCompression = BI_RGB;
info.biSizeImage = 0;
info.biXPelsPerMeter = 0x0ec4;
info.biYPelsPerMeter = 0x0ec4;
info.biClrUsed = 0;
info.biClrImportant = 0;
HANDLE file = CreateFile(bmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
unsigned long bwritten;
if (WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &bwritten, NULL) == false) {
CloseHandle(file);
return false;
}
if (WriteFile(file, &info, sizeof(BITMAPINFOHEADER), &bwritten, NULL) == false) {
CloseHandle(file);
return false;
}
if (WriteFile(file, buffer, paddedsize, &bwritten, NULL) == false) {
CloseHandle(file);
return false;
}
CloseHandle(file);
return true;
}
用于捕获指纹的代码:
HRESULT CaptureSample()
{
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;
// 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;
}
// 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);
// Art "Messiah" Baker at Microsoft
PWINBIO_BIR_HEADER BirHeader = (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));
PBYTE firstPixel = (PBYTE)((PBYTE)AnsiBdbRecord) + sizeof(WINBIO_BDB_ANSI_381_RECORD);
int width = AnsiBdbRecord->HorizontalLineLength;
int height = AnsiBdbRecord->VerticalLineLength;
wprintf_s(L"\n ID: %d\n", AnsiBdbHeader->ProductId.Owner);
wprintf_s(L"\n Width: %d\n", AnsiBdbRecord->HorizontalLineLength);
wprintf_s(L"\n Height: %d\n", AnsiBdbRecord->VerticalLineLength);
wprintf_s(L"\n Horizontal Img. Res.: %d\n", AnsiBdbHeader->HorizontalImageResolution);
wprintf_s(L"\n Horizontal Scan Img. Res.: %d\n", AnsiBdbHeader->HorizontalScanResolution);
wprintf_s(L"\n Vertical Img. Res.: %d\n", AnsiBdbHeader->VerticalImageResolution);
wprintf_s(L"\n Vertical Scan Img. Res.: %d\n", AnsiBdbHeader->VerticalScanResolution);
wprintf_s(L"\n First Pixel: %d\n", firstPixel);
wprintf_s(L"\n Element Count: %d\n", AnsiBdbHeader->ElementCount);
bool b = SaveBMP(firstPixel, width, height, 0, L"C:\\Users\\smf\\Desktop\\fingerprint.bmp");
wprintf_s(L"\n Success: %d\n", b);
e_Exit:
if (sample != NULL)
{
WinBioFree(sample);
sample = NULL;
}
if (sessionHandle != NULL)
{
WinBioCloseSession(sessionHandle);
sessionHandle = NULL;
}
wprintf_s(L"\n Press any key to exit...");
_getch();
return hr;
}
我不太了解(因为我不熟悉C ++,但精通高级语言)是为了使这个功能起作用,我必须将我传递给函数的任何宽度除以3.如果我不这样做,图像将无效。
这背后的原因是什么,如果可能的话,我如何让图片保留其原始宽度?
答案 0 :(得分:2)
AFAIK,WinBioCaptureSample返回的图像是灰度位图,即每像素使用8位。 SaveBitmap的实现会写入一个24位RGB位图。因此它需要3倍于原始指纹位图的字节数(或 - 正如您已经发现的那样 - 它会将图像缩小3倍)。
因此,为了解决这个问题,你需要在某个时刻将每个字节加倍。在SaveBitmap中或在将数据传递给它之前。