openCV对比图片库找到最匹配图片

emmmm 临危受任 按照需求修改了个平均哈希算法的图片库识别 

平均哈希算法:

实现步骤

  1. 缩小尺寸:将图像缩小到8*8的尺寸,总共64个像素。这一步的作用是去除图像的细节,只保留结构/明暗等基本信息,摒弃不同尺寸/比例带来的图像差异;
  2. 简化色彩:将缩小后的图像,转为64级灰度,即所有像素点总共只有64种颜色;
  3. 计算平均值:计算所有64个像素的灰度平均值;
  4. 比较像素的灰度:将每个像素的灰度,与平均值进行比较,大于或等于平均值记为1,小于平均值记为0;
  5. 计算哈希值:将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图像的指纹。组合的次序并不重要,只要保证所有图像都采用同样次序就行了;
  6. 得到指纹以后,就可以对比不同的图像,看看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;
}

由于感觉图片库图片相似度大,将像素矩阵扩大了

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冬天为什么这么冷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值