static std::vector<String> getOutputsNames(const Net& net) { std::vector<String> names; std::vector<int> outLayers = net.getUnconnectedOutLayers(); std::vector<String> layersNames = net.getLayerNames(); names.resize(outLayers.size()); for (size_t i = 0; i < outLayers.size(); ++i) names[i] = layersNames[outLayers[i] - 1]; return names; }
void postprocess(Mat& frame, const std::vector<Mat>& outs, Net& net) { static std::vector<int> outLayers = net.getUnconnectedOutLayers(); static std::string outLayerType = net.getLayer(outLayers[0])->type; if (net.getLayer(0)->outputNameToIndex("im_info") != -1) // Faster-RCNN or R-FCN { // Network produces output blob with a shape 1x1xNx7 where N is a number of // detections and an every detection is a vector of values // [batchId, classId, confidence, left, top, right, bottom] CV_Assert(outs.size() == 1); float* data = (float*)outs[0].data; for (size_t i = 0; i < outs[0].total(); i += 7) { float confidence = data[i + 2]; if (confidence > confThreshold) { int left = (int)data[i + 3]; int top = (int)data[i + 4]; int right = (int)data[i + 5]; int bottom = (int)data[i + 6]; int classId = (int)(data[i + 1]) - 1; // Skip 0th background class id. drawPred(classId, confidence, left, top, right, bottom, frame); } } } else if (outLayerType == "DetectionOutput") { // Network produces output blob with a shape 1x1xNx7 where N is a number of // detections and an every detection is a vector of values // [batchId, classId, confidence, left, top, right, bottom] CV_Assert(outs.size() == 1); float* data = (float*)outs[0].data; for (size_t i = 0; i < outs[0].total(); i += 7) { float confidence = data[i + 2]; if (confidence > confThreshold) { int left = (int)(data[i + 3] * frame.cols); int top = (int)(data[i + 4] * frame.rows); int right = (int)(data[i + 5] * frame.cols); int bottom = (int)(data[i + 6] * frame.rows); int classId = (int)(data[i + 1]) - 1; // Skip 0th background class id. drawPred(classId, confidence, left, top, right, bottom, frame); } } } else if (outLayerType == "Region") { std::vector<int> classIds; std::vector<float> confidences; std::vector<Rect> boxes; for (size_t i = 0; i < outs.size(); ++i) { // Network produces output blob with a shape NxC where N is a number of // detected objects and C is a number of classes + 4 where the first 4 // numbers are [center_x, center_y, width, height] 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); if (confidence > confThreshold) { 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)); } } } std::vector<int> indices; NMSBoxes(boxes, confidences, confThreshold, 0.4f, indices); for (size_t i = 0; i < indices.size(); ++i) { int idx = indices[i]; Rect box = boxes[idx]; drawPred(classIds[idx], confidences[idx], box.x, box.y, box.x + box.width, box.y + box.height, frame); } } else CV_Error(Error::StsNotImplemented, "Unknown output layer type: " + outLayerType); }
void postprocess(Mat& frame, const Mat& out, Net& net) { static std::vector<int> outLayers = net.getUnconnectedOutLayers(); static std::string outLayerType = net.getLayer(outLayers[0])->type; float* data = (float*)out.data; if (net.getLayer(0)->outputNameToIndex("im_info") != -1) // Faster-RCNN or R-FCN { // Network produces output blob with a shape 1x1xNx7 where N is a number of // detections and an every detection is a vector of values // [batchId, classId, confidence, left, top, right, bottom] for (size_t i = 0; i < out.total(); i += 7) { float confidence = data[i + 2]; if (confidence > confThreshold) { int left = (int)data[i + 3]; int top = (int)data[i + 4]; int right = (int)data[i + 5]; int bottom = (int)data[i + 6]; int classId = (int)(data[i + 1]) - 1; // Skip 0th background class id. drawPred(classId, confidence, left, top, right, bottom, frame); } } } else if (outLayerType == "DetectionOutput") { // Network produces output blob with a shape 1x1xNx7 where N is a number of // detections and an every detection is a vector of values // [batchId, classId, confidence, left, top, right, bottom] for (size_t i = 0; i < out.total(); i += 7) { float confidence = data[i + 2]; if (confidence > confThreshold) { int left = (int)(data[i + 3] * frame.cols); int top = (int)(data[i + 4] * frame.rows); int right = (int)(data[i + 5] * frame.cols); int bottom = (int)(data[i + 6] * frame.rows); int classId = (int)(data[i + 1]) - 1; // Skip 0th background class id. drawPred(classId, confidence, left, top, right, bottom, frame); } } } else if (outLayerType == "Region") { // Network produces output blob with a shape NxC where N is a number of // detected objects and C is a number of classes + 4 where the first 4 // numbers are [center_x, center_y, width, height] for (int i = 0; i < out.rows; ++i, data += out.cols) { Mat confidences = out.row(i).colRange(5, out.cols); Point classIdPoint; double confidence; minMaxLoc(confidences, 0, &confidence, 0, &classIdPoint); if (confidence > confThreshold) { int classId = classIdPoint.x; 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; drawPred(classId, (float)confidence, left, top, left + width, top + height, frame); } } } else CV_Error(Error::StsNotImplemented, "Unknown output layer type: " + outLayerType); }