图像相似性度量—— 归一化互信息实现

1. 概述

归一化互信息是度量两张图片相似度的一种表达方式,它的值越大代表两张图片的相似性越高。通常用来作为图像配准中的评判准则或是目标函数。它在两幅图像的灰度级数相似的情况下有良好的配准精度,较高的可靠性;但是同时存在计算量大实时性差的不足。:这里的实现是基于Opencv2的。
原理是分别计算图像A,B的信息熵,再计算联合的信息熵。

然后代入公式计算归一化信息熵。这里的联合概率密度P(a,b)具体指的是A图像的灰度级a在图像的相同坐标下在图像B中灰度级为b的像素点的个数与总点数的比值。

2. 实现

//************************************************************************
// 函数名称:    	GetMutualInfo
// 访问权限:    	public 
// 创建日期:		2016/12/09
// 创 建 人:		
// 函数说明:		计算输入图像A和输入图像B的互信息
// 函数参数: 	cv::Mat & img_a	输入图像A
// 函数参数: 	cv::Mat & img_b	输入图像B
// 返 回 值:   	double
//************************************************************************
double CCalcMutualInfo::GetMutualInfo(cv::Mat& img_a, cv::Mat& img_b)
{
	if (!img_a.data || !img_b.data)
	{
		cout << "no input img" << endl;
		return 0.0;
	}
	if (img_a.rows!=img_a.rows || img_a.cols!=img_b.cols)
	{
		cout << "input img's row and cosl not eqaul" << endl;
		return 0.0;
	}

	int rows(img_a.rows);
	int cols(img_b.cols);
	int total_pixel(rows*cols);
	unsigned char* data_a = nullptr;
	unsigned char* data_b = nullptr;
	double value(0.0);						//计算得到的互信息的结果
	double H_a(0.0), H_b(0.0), H_ab(0.0);	//图像A,B或是AB的信息熵
	double* count_array_a = new double[256];
	memset(count_array_a, 0, sizeof(double)*256);
	double* count_array_b = new double[256];
	memset(count_array_b, 0, sizeof(double)* 256);
	double* count_array_ab = new double[256*256];
	memset(count_array_ab, 0, sizeof(double)* 256 * 256);

	//计算H_a, H_b
	for (int i=0; i<rows; i++)
	{
		data_a = img_a.ptr<unsigned char>(i);
		data_b = img_b.ptr<unsigned char>(i);
		for (int j=0; j<cols; j++)
		{
			count_array_a[data_a[j]]++;
			count_array_b[data_b[j]]++;
		}
	}
	for (int i=0; i<255; i++)
	{
		if (0.0 != count_array_a[i])
		{
			double p(count_array_a[i] / (double)total_pixel);
			H_a = H_a + (-1.0*p*(std::log(p) / std::log(2)));
		}
		
		if (0.0 != count_array_b[i])
		{
			double p(count_array_b[i] / (double)total_pixel);
			H_b = H_b + (-1.0*p*(std::log(p) / std::log(2)));
		}
	}

	//计算H_ab
	for (int m = 0; m < 256; m++)	//8位的灰度级
	{
		for (int n = 0; n < 256; n++)
		{
			for (int i = 0; i < rows; i++)
			{
				data_a = img_a.ptr<unsigned char>(i);
				data_b = img_b.ptr<unsigned char>(i);
				for (int j = 0; j < cols; j++)
				{
					//if ((std::abs(m-data_a[j])<20) && (std::abs(n-data_b[j])<20))
					if ((m == data_a[j]) && (n == data_b[j]))	//由联合概率密度的实际物理意义,统计点数
					{
						count_array_ab[m*256 + n]++;
					}
				}
			}
		}
	}
	for (int m = 0; m < 256; m++)
	{
		for (int n = 0; n < 256; n++)
		{
			if (0.0 != count_array_ab[m*256 + n])
			{
				double p(count_array_ab[m*256 + n] / (double)total_pixel);
				H_ab = H_ab + (-1.0*p*(std::log(p) / std::log(2)));
			}
		}
	}
	
	value = (H_a + H_b) / H_ab;	//得出归一化互信息
	delete[] count_array_a;
	delete[] count_array_b;
	delete[] count_array_ab;
	count_array_ab = nullptr;
	count_array_a = nullptr;
	count_array_b = nullptr;
	return value;
}



  • 11
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
图像匹配是指在两幅或多幅图像中找到相应的像素点,以便进行后续的图像处理。而归一化互信息是一种用于比较两个随机变量之间相关性的度量方法。将这两个概念结合起来,可以使用归一化互信息来进行图像匹配。 在MATLAB中,可以使用以下步骤进行归一化互信息图像匹配: 1. 读取需要匹配的两幅图像,将其转换为灰度图像。 2. 对两幅图像进行直方图均衡化,以增强图像对比度。 3. 使用imhist函数计算两幅图像的直方图,并将其归一化。 4. 利用归一化互信息公式计算两幅图像之间的归一化互信息值。 5. 将归一化互信息值最大的位置作为匹配位置,并将其显示在图像上。 以下是一个简单的MATLAB代码示例,用于演示如何使用归一化互信息进行图像匹配: ```matlab % 读取需要匹配的两幅图像 image1 = imread('image1.jpg'); image2 = imread('image2.jpg'); % 将图像转换为灰度图像 gray1 = rgb2gray(image1); gray2 = rgb2gray(image2); % 对灰度图像进行直方图均衡化 eq1 = histeq(gray1); eq2 = histeq(gray2); % 计算两幅图像的直方图,并将其归一化 hist1 = imhist(eq1) / numel(eq1); hist2 = imhist(eq2) / numel(eq2); % 计算归一化互信息值 nmi = mutualinfo(hist1, hist2) / sqrt(entropy(hist1) * entropy(hist2)); % 显示匹配位置 [max_nmi, max_idx] = max(nmi(:)); [match_row, match_col] = ind2sub(size(nmi), max_idx); imshow(image1); hold on; plot(match_col, match_row, 'rx', 'MarkerSize', 20); ``` 需要注意的是,这只是一个简单的示例代码,实际应用中可能需要进行更多的图像预处理和参数调整,以达到更好的匹配效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值