一、打印输出层
YOLO有多个输出层,打印所有的输出层:
vector <string>outNames=net.getUnconnectedOut;
for (int k= 0;k<outnames.size();k++)
{
printf("output layer name:%s/n",outNames[k].c_str())
}
c_str()函数返回是字符串的一个临时指针
二、推理输出
由于yolo有多个输出层,因此前项推理的时候跟SSD等模型不同,forward的第二个参数需要填入所有层,结果就会有多张输出的图像,即Mat类,代码如下表示:
vector outs; net.forward(outs, outNames);
forward推理的所有输出结果都保存在outs数组中,即outputbob,其性质为Mat类。 补充:SSD等检测模型只有一个输出层,因此前向推理时只需要一行代码即可,即:
net.forward()
三、解析输出
在二中说道输出所有的信息都存放在了outs数组中,因此下面要对它进行解析,显示我们想要的数据,有矩形边框、类别名称、置信度, 我们用如下的数组进行表示和保存。
重点:输出的结构为: 【center_x, center_y, width, heigth,confidence,】
vector<int> classIds;
vector<float> confidences;
vector<Rect> boxes;
利用for循环解析输出(outputblob):
for (size_t i = 0; i < outs.size(); ++i)
{
float* data = (float*)outs[i].data;
for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols)
{
Mat scores = outs[i].row(j).colRange(5, outs[i].cols);
Point classIdPoint;
double confidence;
minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);
minMaxLoc用法参考:opencv学习-模板匹配
根据是否满足置信度输出classIds、confidences、boxes
if (confidence > 0.5)
{
int centerX = (int)(data[0] * frame.cols);
int centerY = (int)(data[1] * frame.rows);
int width = (int)(data[2] * frame.cols);
int height = (int)(data[3] * frame.rows);
int left = centerX - width / 2;
int top = centerY - height / 2;
classIds.push_back(classIdPoint.x);
confidences.push_back((float)confidence);
boxes.push_back(Rect(left, top, width, height));
}
}
}
四、NMS
YOLO有多个输出层,因此一个对象可以在多个层上被检测到,即三中输出的结果是对物体多次边框,所以需要去掉重复的box,这时我们需要用到NMS(非最大抑制)
vector<int> indices;
NMSBoxes(boxes, confidences, 0.5, 0.2, indices);
API-NMSBoxes解读 函数原型:NMSBoxes(bboxes, scores, score_threshold, nms_threshold, eta=None, top_k=None) 各个参数含义:
bboxes:a set of bounding boxes to apply NMS.输入所有的box scores:a set of corresponding confidences. 输入所有的置信度 score_threshold:a threshold used to filter boxes by score. 过滤掉置信度低于该阈值的box nms_threshold:a threshold used in non maximum suppression. indices:the kept indices of bboxes after NMS. 输出进过NMS后的结果,并保存在indices中 以下参数不怎么使用 eta:a coefficient in adaptive threshold formula: nms_thresholdi+1=eta?nms_thresholdi. top_k:if >0, keep at most top_k picked indices.
|