emmmm 临危受任 按照需求修改了个平均哈希算法的图片库识别
平均哈希算法:
实现步骤
- 缩小尺寸:将图像缩小到8*8的尺寸,总共64个像素。这一步的作用是去除图像的细节,只保留结构/明暗等基本信息,摒弃不同尺寸/比例带来的图像差异;
- 简化色彩:将缩小后的图像,转为64级灰度,即所有像素点总共只有64种颜色;
- 计算平均值:计算所有64个像素的灰度平均值;
- 比较像素的灰度:将每个像素的灰度,与平均值进行比较,大于或等于平均值记为1,小于平均值记为0;
- 计算哈希值:将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图像的指纹。组合的次序并不重要,只要保证所有图像都采用同样次序就行了;
- 得到指纹以后,就可以对比不同的图像,看看64位中有多少位是不一样的。在理论上,这等同于”汉明距离”(Hamming distance,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数)。如果不相同的数据位数不超过5,就说明两张图像很相似;如果大于10,就说明这是两张不同的图像。
修改后:
#include "stdafx.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdlib.h>
#include <string>
#pragma comment(lib,"opencv_world341d.lib")
//#pragma comment(lib,"opencv_highgui341d.lib")
//#pragma comment(lib,"opencv_imgproc341d.lib")
#define MAX_IMAGE_SIZE 2
using namespace std;
struct MARK_MATCH {
int mark = 0;
string address = "C:/Users/thero/Desktop/temp/";
}mark[MAX_IMAGE_SIZE];
int cmp(const void *a, const void *b) {
return ((MARK_MATCH *)a)->mark - ((MARK_MATCH *)b)->mark;
}
void judge_mark(int index);
string strSrcImageName1 = "C:/Users/thero/Desktop/temp/1Copy.png";
string strSrcImageName = "C:/Users/thero/Desktop/temp/";
string strSrcImageName2 ;
string temp_img_address;
int iAvg1 = 0, iAvg2 = 0, i = 0, j = 0, tmp = 0, tmp1 = 0, index = 0, iDiffNum = 0;
int arr1[6400], arr2[6400];
int _tmain(int argc, _TCHAR* argv[])
{
while (index < MAX_IMAGE_SIZE) {
judge_mark(index);
index++;
}
qsort(mark, MAX_IMAGE_SIZE, sizeof(MARK_MATCH), cmp);
cout << mark[0].address;
getchar();
return 0;
}
void judge_mark(int index) {
temp_img_address = to_string(index) + ".png";
strSrcImageName2 = strSrcImageName + temp_img_address;
cv::Mat matSrc, matSrc1, matSrc2;
cv::Mat matDst1, matDst2;
matSrc1 = cv::imread(strSrcImageName1, CV_LOAD_IMAGE_COLOR);
matSrc2 = cv::imread(strSrcImageName2, CV_LOAD_IMAGE_COLOR);
cv::resize(matSrc1, matDst1, cv::Size(80, 80), 0, 0, cv::INTER_CUBIC);
cv::resize(matSrc2, matDst2, cv::Size(80, 80), 0, 0, cv::INTER_CUBIC);
cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY);
cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY);
for (i = 0; i < 80; i++)
{
uchar* data1 = matDst1.ptr<uchar>(i);
uchar* data2 = matDst2.ptr<uchar>(i);
tmp = i * 80;
for (j = 0; j < 80; j++)
{
tmp1 = tmp + j;
arr1[tmp1] = data1[j] / 40 * 40;
arr2[tmp1] = data2[j] / 40 * 40;
iAvg1 += arr1[tmp1];
iAvg2 += arr2[tmp1];
}
}
iAvg1 /= 6400;
iAvg2 /= 6400;
for (i = 0; i < 6400; i++)
{
arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;
arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0;
}
iDiffNum = 0;
for (i = 0; i < 6400; i++)
if (arr1[i] != arr2[i])
++iDiffNum;
mark[index].mark = iDiffNum;
mark[index].address = strSrcImageName2;
}
由于感觉图片库图片相似度大,将像素矩阵扩大了