搜索图片及相似度探秘 二

Posted qianbo_insist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搜索图片及相似度探秘 二相关的知识,希望对你有一定的参考价值。

一在这里
搜索图片及相似度探秘 一

在这里插入图片描述

还是继续,准备了五幅图片

两个易烊千玺,两个肖战,一个地球星空
还是像上次那样,准备均值和标准差,但是这次,多了一个图片索引hash计算,这次计算的是整个图片的均值和hash,然后将缩小的图片减去均值,来求大于和小于的概率统计,因为并非真实图片的统计,是8*8 像素的图片统计,所以具有一定的概率性。ok,以下是代码

string compare_func()
{
	string retString = "{\\"ret\\":\\"file is null\\"}";
	Mat image1 = cv::imread("./y1.png", IMREAD_GRAYSCALE);
	Mat image2 = cv::imread("./y2.png", IMREAD_GRAYSCALE);
	Mat image3 = cv::imread("./x1.png", IMREAD_GRAYSCALE);
	Mat image4 = cv::imread("./x2.png", IMREAD_GRAYSCALE);
	Mat image5 = cv::imread("./earth.png", IMREAD_GRAYSCALE);	
	

	if (image1.empty() || image2.empty())
	{
		return retString;
	}
    
	Mat a1, a2,a3,a4,a5;
	cv::resize(image1, a1, cv::Size(8,8));
	cv::resize(image2, a2, cv::Size(8,8));
	cv::resize(image3, a3, cv::Size(8,8));
	cv::resize(image4, a4, cv::Size(8,8));
	cv::resize(image5, a5, cv::Size(8,8));
	Mat mat_mean1, mat_mean2, mat_mean3, mat_mean4, mat_mean5;
	Mat mat_stddev1, mat_stddev2, mat_stddev3, mat_stddev4, mat_stddev5;
	cv::meanStdDev(image1, mat_mean1, mat_stddev1);
	cv::meanStdDev(image2, mat_mean2, mat_stddev2);
	cv::meanStdDev(image3, mat_mean3, mat_stddev3);
	cv::meanStdDev(image4, mat_mean4, mat_stddev4);
	cv::meanStdDev(image5, mat_mean5, mat_stddev5);

	double m1,m2,m3,m4,m5, s1,s2,s3,s4,s5;
	m1 = mat_mean1.at<double>(0, 0);
	s1 = mat_stddev1.at<double>(0, 0);
	cout << "a1" << "灰度均值:" << m1 <<" std: "<<s1 <<endl;

	m2 = mat_mean2.at<double>(0, 0);
	s2 = mat_stddev2.at<double>(0, 0);
	cout << "a2" << "灰度均值:" << m2 << " std: " << s2 << endl;

	m3 = mat_mean3.at<double>(0, 0);
	s3 = mat_stddev3.at<double>(0, 0);
	cout << "a3" << "灰度均值:" << m3 << " std: " << s3 << endl;
	
	m4 = mat_mean4.at<double>(0, 0);
	s4 = mat_stddev4.at<double>(0, 0);
	cout << "a4" << "灰度均值:" << m4 << " std: " << s4 << endl;

	m5 = mat_mean5.at<double>(0, 0);
	s5 = mat_stddev5.at<double>(0, 0);
	cout << "a5" << "灰度均值:" << m5 << " std: " << s5 << endl;

	uint64_t v1 = 0;
	uint64_t v2 = 0;
	uint64_t v3 = 0;
	uint64_t v4 = 0;
	uint64_t v5 = 0;

	int offset = 64;


	for (int i = 0; i < 8; i++)
	{
		uchar* x = a1.ptr<uchar>(i);
		uchar* y = a2.ptr<uchar>(i);
		uchar* z = a3.ptr<uchar>(i);
		uchar* q = a4.ptr<uchar>(i);
		uchar* e = a5.ptr<uchar>(i);
		for (int j = 0; j < 8; j++)
		{
			offset--;
			if (x[j] > m1)
				v1 |= (uint64)1 << offset;
			if (y[j] > m2)
				v2 |= (uint64)1 << offset;
			if (z[j] > m3)
				v3 |= (uint64)1 << offset;
			if (q[j] > m4)
				v4 |= (uint64)1 << offset;
			if (e[j] > m5)
				v5 |= (uint64)1 << offset;
		}
	}

	int ret1 = compare_hash(v1, v2);
	int ret2 = compare_hash(v1, v3);
	int ret3 = compare_hash(v1, v4);
	int ret4 = compare_hash(v1, v5);
	cout << v1 << " " << v2<< " " << v3 <<" "<< v4 <<" "<<v5<<endl;
	cout << ret1 << " " << ret2 <<" "<< ret3<<" "<<ret4<< endl;
	imshow("1", image1);
	imshow("2", image2);
	imshow("3", image3);
	imshow("4", image4);
	imshow("5", image5);
	cv::waitKey(0);
}

比较hansh函数,每幅图是一个hash,当两幅图像的位值,也就是是0还是1,无论是0还是1,只要相等我们就将相似度加1.

int compare_hash(uint64_t target, uint64_t compare)
{
	int ret = 0;
	for (int i = 0;i < 64; i++)
	{
		uint64_t a = (target >> i) << (63 - i);
		uint64_t b = (compare >> i) << (63 - i);
		if (a == b)
			ret++;
	}
	//1100110100001001
	return ret;
}

结果:
结果
很可惜,根本就查不到相似之处,而且1和2 都是易烊千玺,3和4 都是肖战,但是均值和标准差并没有什么规律,hash值比较并没有比较出什么规律,说明方法都是失效的,ok,如何找到规律,才是我们要做的,这将在下一节继续努力,敬请期待。

以上是关于搜索图片及相似度探秘 二的主要内容,如果未能解决你的问题,请参考以下文章

百度图像搜索探秘

怎么对比两张图片的相似度

图像视频相似度算法

算法竞赛入门码蹄集进阶塔335题(MT3330-3335)

Elasticsearch:图片相似度搜索的 5 个技术组成部分

Elasticsearch:图片相似度搜索的 5 个技术组成部分