零均值归一化积相关算法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。