赞
踩
交并比(Intersection-over-Union,IoU),目标检测中使用的一个概念,是产生的候选框(candidate bound)与原标记框(ground truth bound)的交叠率,即它们的交集与并集的比值。最理想情况是完全重叠,即比值为1。
计算公式:
C++代码:
struct bbox { int m_left; int m_top; int m_width; int m_height; bbox() {} bbox(int left, int top, int width, int height) { m_left = left; m_top = top; m_width = width; m_height = height; } }; float IOU_compute(const bbox b1, const bbox b2) { w = max(min((b1.m_left + b1.m_width), (b2.m_left + b2.m_width)) - max(b1.m_left, b2.m_left), 0); h = max(min((b1.m_top + b1.m_height), (b2.m_top + b2.m_height)) - max(b1.m_top, b2.m_top), 0); return w*h / (b1.m_width*b1.m_height + b2.m_width*b2.m_height - w*h); }
NMS(non maximum suppression),中文名非极大值抑制,在很多计算机视觉任务中都有广泛应用,如:边缘检测、目标检测等。
在物体检测中NMS(Non-maximum suppression)非极大抑制应用十分广泛,其目的是为了消除多余的框,找到最佳的物体检测的位置。
在RCNN系列算法中,会从一张图片中找出很多个候选框(可能包含物体的矩形边框),然后为每个矩形框为做类别分类概率。
就像上面的图片一样,定位一个车辆,最后算法就找出了一堆的方框,我们需要判别哪些矩形框是没用的。
非极大值抑制:先假设有6个候选框,根据分类器类别分类概率做排序,从小到大分别属于车辆的概率分别为A、B、C、D、E、F。
C++代码:
//升序排列 bool cmpScore(Bbox lsh, Bbox rsh) { if (lsh.score < rsh.score) return true; else return false; } void nms(vector<Bbox> &boundingBox_, const float overlap_threshold, string modelname = "Union"){ if(boundingBox_.empty()){ return; } //对各个候选框根据score的大小进行升序排列 sort(boundingBox_.begin(), boundingBox_.end(), cmpScore); float IOU = 0; float maxX = 0; float maxY = 0; float minX = 0; float minY = 0; vector<int> vPick; int nPick = 0; multimap<float, int> vScores; //存放升序排列后的score和对应的序号 const int num_boxes = boundingBox_.size(); vPick.resize(num_boxes); for (int i = 0; i < num_boxes; ++i){ vScores.insert(pair<float, int>(boundingBox_[i].score, i)); } while(vScores.size() > 0){ int last = vScores.rbegin()->second; //反向迭代器,获得vScores序列的最后那个序列号 vPick[nPick] = last; nPick += 1; for (multimap<float, int>::iterator it = vScores.begin(); it != vScores.end();){ int it_idx = it->second; maxX = max(boundingBox_.at(it_idx).x1, boundingBox_.at(last).x1); maxY = max(boundingBox_.at(it_idx).y1, boundingBox_.at(last).y1); minX = min(boundingBox_.at(it_idx).x2, boundingBox_.at(last).x2); minY = min(boundingBox_.at(it_idx).y2, boundingBox_.at(last).y2); //转换成了两个边界框相交区域的边长 maxX = ((minX-maxX+1)>0)? (minX-maxX+1) : 0; maxY = ((minY-maxY+1)>0)? (minY-maxY+1) : 0; //求交并比IOU IOU = (maxX * maxY)/(boundingBox_.at(it_idx).area + boundingBox_.at(last).area - IOU); if(IOU > overlap_threshold){ it = vScores.erase(it); //删除交并比大于阈值的候选框,erase返回删除元素的下一个元素 }else{ it++; } } } vPick.resize(nPick); vector<Bbox> tmp_; tmp_.resize(nPick); for(int i = 0; i < nPick; i++){ tmp_[i] = boundingBox_[vPick[i]]; } boundingBox_ = tmp_; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。