匹配代价函数之ZNCC

      零均值归一化积相关算法ZNCC,利用两个待匹配像素点邻域窗口内的像素,通过零均值归一化相似性度量公式来计算两个待匹配像素之间的相似程度,公式如下

代码如下:

inline bool XYCheck(const cv::Mat& img, const cv::Point2i& p)
{
	return p.x >= 0 && p.x < img.cols&& p.y >= 0 && p.y < img.rows;
}

inline bool XYCheck(const cv::Mat& img, int c, int r)
{
	return c >= 0 && c < img.cols&& r >= 0 && r < img.rows;
}

double ZNCC(const cv::Mat& img1, int c1, int r1,
	const cv::Mat& img2, int c2, int r2, int size)
{
	if (img1.type() != CV_8UC1 || !XYCheck(img1,c1,r1)
		|| img2.type() != CV_8UC1 || !XYCheck(img2, c2,r2) || size <= 0)
	{
		return FLT_MAX;
	}

	std::vector<uchar> vals1, vals2;
	for (int i = -size; i <= size; i++)
	{
		for (int j = -size; j <= size; j++)
		{
			if (XYCheck(img1, c1 + j, r1 + i)
				&& XYCheck(img2, c2 + j, r2 + i))
			{
				vals1.push_back(img1.ptr<uchar>(r1 + i)[c1 + j]);
				vals2.push_back(img2.ptr<uchar>(r2 + i)[c2 + j]);
			}
		}
	}
	if (vals1.empty()) return FLT_MAX;
	double avg1 = cv::mean(vals1).val[0];
	double avg2 = cv::mean(vals2).val[0];

	double val12 = 0, val11 = 0, val22 = 0;//这些是自相关和互相关
	for (int i = 0; i < vals1.size(); ++i)
	{
		val12 += (vals1[i] - avg1) * (vals2[i] - avg2);
		val11 += pow(vals1[i] - avg1, 2);
		val22 += pow(vals2[i] - avg2, 2);
	}

	return val12==0?FLT_MAX:fabs(sqrt(val11 * val22) / val12);
}

double ZNCC(const cv::Mat& img1, const cv::Point2i& p1,
	const cv::Mat& img2, const cv::Point2i& p2, int size)
{
	return ZNCC(img1, p1.x, p1.y, img2, p2.x, p2.y, size);
}

本人水平有限,如有错误,还望不吝指正,代码有一定删减,没有重新编译,如有错误,请自行调试,有问题请邮箱联系1299771369@qq.com。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值