自适应非极大值抑制算法

自适应非极大值抑制算法

自适应非极大值抑制算法是论文Multi-Image Matching using Multi-Scale Oriented Patches提出的一种算法。基本思想是评估所有候选点的极大区域,并进行排序。

具体来说,就是先选取很多的评分较高的候选点,组成集合S。对S中的每个点 x i x_i xi,寻找它的响应能作为区域最大值的区域半径 r i r_i ri,即

r i = m i n ∣ ∣ x i − x j ∣ ∣ , s . t . r e s p o n s e ( x i ) < r e s p o n s e ( x j ) , x j ∈ S r_i =min||x_i-x_j||,s.t.response(x_i)<response(x_j),x_j \in S ri=minxixj,s.t.response(xi)<response(xj),xjS

将找到的 r i r_i ri降序排列。选取前n个元素对应的点,即为自适应非极大值滤波后得到的关键点。

算法效果如图:

过滤前

自适应非极大值抑制算法_第1张图片

过滤后

自适应非极大值抑制算法_第2张图片

评价

不同于传统非极大值抑制算法,ANMS算法不用选取阈值。然而带来的问题是它需要计算所有候选点之间的距离,所以会带来很大的时间复杂度。

实现代码如下


double computeR(Point2i x1, Point2i x2)
{
	return norm(x1 - x2);
}
template < typename T>
vector< size_t>  sort_indexes(const vector< T>  & v) {

	// initialize original index locations
	vector< size_t>  idx(v.size());
	for (size_t i = 0; i != idx.size(); ++i) idx[i] = i;

	// sort indexes based on comparing values in v
	sort(idx.begin(), idx.end(),
		[&v](size_t i1, size_t i2) {return v[i1] >  v[i2]; });

	return idx;
}

vector ANMS(const std::vector& kpts,int num = 500)
{
	int sz = kpts.size();
	double maxmum = 0;
	vector roblocalmax(kpts.size());
	vector raduis(kpts.size(), INFINITY);
	for (size_t i = 0; i < sz; i++)
	{
		auto rp = kpts[i].response;
		if (rp > maxmum)
			maxmum = rp;
		roblocalmax[i] = rp*0.9;
	}
	auto max_response = maxmum*0.9;
	for (size_t i = 0; i < sz; i++)
	{
		double rep = kpts[i].response;
		Point2i p = kpts[i].pt;
		auto& rd = raduis[i];
		if (rep>max_response)
		{
			rd = INFINITY;
		}
		else 
		{
			for (size_t j = 0; j < sz; j++)
			{
				if (roblocalmax[j] > rep)
				{
					auto d = computeR(kpts[j].pt, p);
					if (rd > d)
						rd = d;
				}
			}
		}
	}
	auto sorted = sort_indexes(raduis);
	vector rpts;
	
	for (size_t i = 0; i < num; i++)
	{
		rpts.push_back(kpts[sorted[i]]);
	}
	return std::move(rpts);
}

你可能感兴趣的:(算法,计算机视觉,算法)