Я недавно столкнулся с теми же проблемами, чтобы решить эту проблему (простой и быстрый алгоритм сравнения двух изображений) раз и навсегда, я добавляю модуль img_hash в opencv_contrib, подробности можно найти в эта ссылка .
Модуль img_hash предоставляет шесть алгоритмов хеширования изображений, довольно простых в использовании.
Пример кода
происхождение Лена
размытие Лена
изменить размер лена
смена лены
#include <opencv2/core.hpp>
#include <opencv2/core/ocl.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/img_hash.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
void compute(cv::Ptr<cv::img_hash::ImgHashBase> algo)
{
auto input = cv::imread("lena.png");
cv::Mat similar_img;
//detect similiar image after blur attack
cv::GaussianBlur(input, similar_img, {7,7}, 2, 2);
cv::imwrite("lena_blur.png", similar_img);
cv::Mat hash_input, hash_similar;
algo->compute(input, hash_input);
algo->compute(similar_img, hash_similar);
std::cout<<"gaussian blur attack : "<<
algo->compare(hash_input, hash_similar)<<std::endl;
//detect similar image after shift attack
similar_img.setTo(0);
input(cv::Rect(0,10, input.cols,input.rows-10)).
copyTo(similar_img(cv::Rect(0,0,input.cols,input.rows-10)));
cv::imwrite("lena_shift.png", similar_img);
algo->compute(similar_img, hash_similar);
std::cout<<"shift attack : "<<
algo->compare(hash_input, hash_similar)<<std::endl;
//detect similar image after resize
cv::resize(input, similar_img, {120, 40});
cv::imwrite("lena_resize.png", similar_img);
algo->compute(similar_img, hash_similar);
std::cout<<"resize attack : "<<
algo->compare(hash_input, hash_similar)<<std::endl;
}
int main()
{
using namespace cv::img_hash;
//disable opencl acceleration may(or may not) boost up speed of img_hash
cv::ocl::setUseOpenCL(false);
//if the value after compare <= 8, that means the images
//very similar to each other
compute(ColorMomentHash::create());
//there are other algorithms you can try out
//every algorithms have their pros and cons
compute(AverageHash::create());
compute(PHash::create());
compute(MarrHildrethHash::create());
compute(RadialVarianceHash::create());
//BlockMeanHash support mode 0 and mode 1, they associate to
//mode 1 and mode 2 of PHash library
compute(BlockMeanHash::create(0));
compute(BlockMeanHash::create(1));
}
В этом случае ColorMomentHash дает нам лучший результат
- Гауссовское размытие: 0,567521
- атака смены: 0,229728
- изменение размера атаки: 0,229358
Плюсы и минусы каждого алгоритма

Производительность img_hash тоже хорошая
Сравнение скорости с библиотекой PHash (100 изображений из ukbench)

Если вы хотите узнать рекомендуемые пороговые значения для этих алгоритмов, проверьте этот пост (http://qtandopencv.blogspot.my/2016/06/introduction-to-image-hash-module-of.html).
Если вам интересно узнать, как я могу измерить производительность модулей img_hash (включая скорость и различные атаки), проверьте эту ссылку (http://qtandopencv.blogspot.my/2016/06/speed-up-image-hashing-of-opencvimghash.html).