c++版的NMS(非极大抑制)实现

本文深入解析了NMS(非极大抑制)算法,一种用于深度学习目标检测中筛选高置信度检测框的方法。通过详细步骤说明及C++代码实现,展示了如何通过计算IoU去除冗余框,保留最优检测结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NMS(非极大抑制)是深度学习目标检测中常用的小算法,用来过滤掉同一个物体上的那些置信度较低的bbboxes,最后只剩下该目标检测框集中最大置信度的那个。

算法原理

   说它是小算法的原因是其原理很简单。

  1)先对输入检测框按置信度由高到低排序

2)挑选第一个检测框(即最高置信度,记为A)和其它检测框(记为B)进行iou计算

3)如果iou大于nmsThreshold, 那就将B清除掉

4)跳转到2)从剩余得框集里面找置信度最大得框和其它框分别计算iou

5)直到所有框都过滤完。

代码实现

网上得代码主要以python或matlab为主,我这里是c++实现得,接口参数和opencv里面得NMSBoxes(...)完全一样。代码里面有相应注释,而且经过测试,能正常工作得。

typedef struct {
	Rect box;
	float confidence;
	int index;
}BBOX;

static float get_iou_value(Rect rect1, Rect rect2)
{
	int xx1, yy1, xx2, yy2;

	xx1 = max(rect1.x, rect2.x);
	yy1 = max(rect1.y, rect2.y);
	xx2 = min(rect1.x + rect1.width - 1, rect2.x + rect2.width - 1);
	yy2 = min(rect1.y + rect1.height - 1, rect2.y + rect2.height - 1);

	int insection_width, insection_height;
	insection_width = max(0, xx2 - xx1 + 1);
	insection_height = max(0, yy2 - yy1 + 1);

	float insection_area, union_area, iou;
	insection_area = float(insection_width) * insection_height;
	union_area = float(rect1.width*rect1.height + rect2.width*rect2.height - insection_area);
	iou = insection_area / union_area;
	return iou;
}

//input:  boxes: 原始检测框集合;
//input:  confidences:原始检测框对应的置信度值集合
//input:  confThreshold 和 nmsThreshold 分别是 检测框置信度阈值以及做nms时的阈值
//output:  indices  经过上面两个阈值过滤后剩下的检测框的index
void nms_boxes(vector<Rect> &boxes, vector<float> &confidences, float confThreshold, float nmsThreshold, vector<int> &indices)
{	
	BBOX bbox;
	vector<BBOX> bboxes;
	int i, j;
	for (i = 0; i < boxes.size(); i++)
	{
		bbox.box = boxes[i];
		bbox.confidence = confidences[i];
		bbox.index = i;
		bboxes.push_back(bbox);
	}
	sort(bboxes.begin(), bboxes.end(), comp);

	int updated_size = bboxes.size();
	for (i = 0; i < updated_size; i++)
	{
		if (bboxes[i].confidence < confThreshold)
			continue;
		indices.push_back(bboxes[i].index);
		for (j = i + 1; j < updated_size; j++)
		{
			float iou = get_iou_value(bboxes[i].box, bboxes[j].box);
			if (iou > nmsThreshold)
			{
				bboxes.erase(bboxes.begin() + j);
				updated_size = bboxes.size();
			}
		}
	}

小结

   做的比较匆忙,没太考虑效率。如果有更好得方法或有欠考虑周到得地方,恳请指正。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ltshan139

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值