public Result GetResults(float scoreThreshold = 0.5f, float iouThreshold = 0.3f) { results.Clear(); int keypointsCount = KeypointsCount; for (int i = 0; i < anchors.Length; i++) { float score = MathTF.Sigmoid(output1[i]); if (score < scoreThreshold) { continue; } SsdAnchor anchor = anchors[i]; float sx = output0[i, 0]; float sy = output0[i, 1]; float w = output0[i, 2]; float h = output0[i, 3]; float cx = sx + anchor.x * width; float cy = sy + anchor.y * height; cx /= (float)width; cy /= (float)height; w /= (float)width; h /= (float)height; var keypoints = new Vector2[keypointsCount]; for (int j = 0; j < keypointsCount; j++) { float lx = output0[i, 4 + (2 * j) + 0]; float ly = output0[i, 4 + (2 * j) + 1]; lx += anchor.x * width; ly += anchor.y * height; lx /= (float)width; ly /= (float)height; keypoints[j] = new Vector2(lx, ly); } results.Add(new Result() { score = score, rect = new Rect(cx - w * 0.5f, cy - h * 0.5f, w, h), keypoints = keypoints, }); } // No result if (results.Count == 0) { return(Result.Negative); } return(results.First()); // return NonMaxSuppression(results, iouThreshold).First(); }
public List <Result> GetResults(float scoreThreshold = 0.7f, float iouThreshold = 0.3f) { results.Clear(); for (int i = 0; i < anchors.Length; i++) { float score = MathTF.Sigmoid(output0[i]); if (score < scoreThreshold) { continue; } SsdAnchor anchor = anchors[i]; float sx = output1[i, 0]; float sy = output1[i, 1]; float w = output1[i, 2]; float h = output1[i, 3]; float cx = sx + anchor.x * width; float cy = sy + anchor.y * height; cx /= (float)width; cy /= (float)height; w /= (float)width; h /= (float)height; var keypoints = new Vector2[7]; for (int j = 0; j < 7; j++) { float lx = output1[i, 4 + (2 * j) + 0]; float ly = output1[i, 4 + (2 * j) + 1]; lx += anchor.x * width; ly += anchor.y * height; lx /= (float)width; ly /= (float)height; keypoints[j] = new Vector2(lx, ly); } results.Add(new Result() { score = score, rect = new Rect(cx - w * 0.5f, cy - h * 0.5f, w, h), keypoints = keypoints, }); //Debug.Log(ToString(keypoints)); } return(NonMaxSuppression(results, iouThreshold)); }
public static SsdAnchor[] Generate(Options options) { var anchors = new List <SsdAnchor>(); int layer_id = 0; while (layer_id < options.strides.Length) { var anchor_height = new List <float>(); var anchor_width = new List <float>(); var aspect_ratios = new List <float>(); var scales = new List <float>(); // For same strides, we merge the anchors in the same order. int last_same_stride_layer = layer_id; while (last_same_stride_layer < (int)options.strides.Length && options.strides[last_same_stride_layer] == options.strides[layer_id]) { float scale = CalculateScale(options.minScale, options.maxScale, last_same_stride_layer, options.strides.Length); if (last_same_stride_layer == 0 && options.reduceBoxesInLowestLayer) { // For first layer, it can be specified to use predefined anchors. aspect_ratios.Add(1.0f); aspect_ratios.Add(2.0f); aspect_ratios.Add(0.5f); scales.Add(0.1f); scales.Add(scale); scales.Add(scale); } else { for (int aspect_ratio_id = 0; aspect_ratio_id < (int)options.aspectRatios.Length; ++aspect_ratio_id) { aspect_ratios.Add(options.aspectRatios[aspect_ratio_id]); scales.Add(scale); } if (options.interpolatedScaleAspectRatio > 0.0) { float scale_next = last_same_stride_layer == (int)options.strides.Length - 1 ? 1.0f : CalculateScale(options.minScale, options.maxScale, last_same_stride_layer + 1, options.strides.Length); scales.Add(Mathf.Sqrt(scale * scale_next)); aspect_ratios.Add(options.interpolatedScaleAspectRatio); } } last_same_stride_layer++; } for (int i = 0; i < (int)aspect_ratios.Count; ++i) { float ratio_sqrts = Mathf.Sqrt(aspect_ratios[i]); anchor_height.Add(scales[i] / ratio_sqrts); anchor_width.Add(scales[i] * ratio_sqrts); } int feature_map_height = 0; int feature_map_width = 0; if (options.featureMapHeight.Length > 0) { feature_map_height = options.featureMapHeight[layer_id]; feature_map_width = options.featureMapWidth[layer_id]; } else { int stride = options.strides[layer_id]; feature_map_height = Mathf.CeilToInt(1.0f * options.inputSizeHeight / stride); feature_map_width = Mathf.CeilToInt(1.0f * options.inputSizeWidth / stride); } for (int y = 0; y < feature_map_height; ++y) { for (int x = 0; x < feature_map_width; ++x) { for (int anchor_id = 0; anchor_id < (int)anchor_height.Count; ++anchor_id) { // TODO: Support specifying anchor_offset_x, anchor_offset_y. float x_center = (x + options.anchorOffsetX) * 1.0f / feature_map_width; float y_center = (y + options.anchorOffsetY) * 1.0f / feature_map_height; var new_anchor = new SsdAnchor(); new_anchor.x = x_center; new_anchor.y = y_center; if (options.fixedAnchorSize) { new_anchor.width = 1.0f; new_anchor.height = 1.0f; } else { new_anchor.width = anchor_width[anchor_id]; new_anchor.height = anchor_height[anchor_id]; } anchors.Add(new_anchor); } } } layer_id = last_same_stride_layer; } return(anchors.ToArray()); }