图片相似度计算 2---(phash--c++实现)

在上一篇博客里介绍了图片相似计算中的最简单的一个ahash, 其是基于内容检索最简单的一种,这篇介绍它的增强版感知哈希算法(phash—perceptual hash)。主要也是用缩略图搜索原图并能达到较好点的效果。
其实现一共包含以下几个步骤:

  1. 图像缩放–将图像缩放到32*32大小,这一步的作用是取出各种图片尺寸和图片比例的差异,只保留结构、明暗等信息。
  2. 灰度化–将32*32大小的图像进行灰度化
  3. 离散余弦变换(DCT)–对32*32大小图像进行DCT
  4. 计算均值–用3232大小图片前面88的像素值中大于均值的则用1表示,小于的用0表示,这样就得到一个二进制码作为该图像的phash值(保留左上角的8*8,这些代表的图片的最低频率)
  5. 计算两幅图像的ahash值的汉明距离,距离越小,表明两幅图像越相似;距离越大,表明两幅图像越不相似。
代码实现
#include <opencv2\opencv.hpp>  
#include <opencv2\core\core.hpp>  
#include <opencv2\highgui\highgui.hpp>  
#include <opencv2\imgproc\imgproc.hpp>  
#include <opencv2\objdetect\objdetect.hpp>  
#include <opencv2\imgproc\types_c.h>   
#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;
using namespace cv;
string pHashValue(Mat &srcImg);//pHash方法计算图片哈希值
int hanmingDist(string &str1, string &str2);//计算哈希值字符串的汉明距离

int main()
{
	Mat orgImg = imread("图片1路径");
	Mat img = imread("图片2路径");

	imshow("OrgImg", orgImg);
	imshow("Img", img);

	string str1 = pHashValue(orgImg);
	string str2 = pHashValue(img);

	int distance = hanmingDist(str1, str2);
	cout << "两张图片的汉明距离:" << distance << endl;

	if (distance < 5) //若汉明距离小于5,则两张图片相似
    {
		cout << "两张图片相似" << endl;
	}
	else
	{
		cout << "两张图片不相似" << endl;
	}

	waitKey(0);
	return 0;
}

string pHashValue(Mat &srcImg)//pHash方法计算图片哈希值
{
	Mat img, dstImg;
	string rst(64, '\0');

	double dIndex[64];
	double mean = 0.0;
	int  k = 0;

	if (srcImg.channels() == 3)//若为彩色图像则转换为灰度图像
	{
		cvtColor(srcImg, srcImg, CV_BGR2GRAY);
		img = Mat_<double>(srcImg);
	}
	else
	{

		img = Mat_<double>(srcImg);

	}

	//缩放尺寸
	resize(img, img, Size(32, 32));
	//离散余弦变换 DCT
	dct(img, dstImg);

	//获取dct系数均值
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			dIndex[k] = dstImg.at<double>(i, j);
			//计算每个像素的均值
			mean += dstImg.at<double>(i, j) / 64;
			++k;
		}
	}

	//计算hash
	for (int i = 0; i < 64; ++i)
	{
		if (dIndex[i] >= mean)
		{
			rst[i] = '1';
		}
		else {
			rst[i] = '0';
		}
	}

	return rst;

}
int hanmingDist(string &str1, string &str2)//计算哈希值字符串的汉明距离
{
	if ((str1.size() != 64) || (str2.size() != 64))
	{
		return -1;
	}

	int distValue = 0;
	for (int i = 0; i < 64; i++)
	{
		if (str1[i] != str2[i])
		{
			distValue++;
		}
	}

	return distValue;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值