Сравнение двух изображений через хэш C++
У нас есть два одинаковых изображений, переведённых в градацию серого. Нам нужно сравнить эти изображения, и если они одинаковы, то мы делаем что-то.
Перерыл более нескольких сотен сайтов, но решения устарели, либо же не удаётся реализовать.
Тем временем есть готовые функции для расчёта хэша в OpenCv, но, в документации файл есть, а на деле его нет (я имею ввиду img_hash), что делает данный способ решения проблемы невозможным.
Ответы (1 шт):
С OpenCV не подскажу, но может такой способ подойдёт тоже.
Общая идея: помещаем файл аккурат в память и от этого массива байт считаем контрольную сумму:
#include <Windows.h>
#include <atlbase.h>
constexpr auto szFilePath = LR"(C:\Folder\img1.png)"
...
ATL::CHandle hFile;
hFile.m_h = ::CreateFile(
szFilePath,
GENERIC_READ,
FILE_SHARE_READ,
nullptr,
OPEN_EXISTING,
0,
nullptr
);
if (hFile == INVALID_HANDLE_VALUE) // Ошибка
ATL::CHandle hFileMapping;
hFileMapping.m_h = ::CreateFileMapping(
hFile,
nullptr,
PAGE_READONLY,
0,
0,
nullptr
);
if (!hFileMapping) // ошибка (тут именно на ноль проверка)
const BYTE* pData = (const BYTE*)::MapViewOfFile(
hFileMapping,
FILE_MAP_READ,
0, 0, 0
);
if (!pData) // ошибка
//
// В массиве данных pData лежат данные png
// файла в бинарном виде
//
// По завершении работы надо файл размапить
::UnmapViewOfFile(pData);
Далее надо узнать размер файла. Это вот так делается:
LARGE_INTEGER liFileSize = { 0 };
BOOL bResult = ::GetFileSizeEx(hFile, &liFileSize);
if (!bResult) // ошибка
LONGLONG dwFileSize = liFileSize.QuadPart; // Это и есть размер файла
Ну а дальше, зная размер массива данных и указатель на него, можно легко посчитать хэш от этого массива. Например, с помощью RtlComputeCrc32 из NtDll.dll.