Skip to content

Instantly share code, notes, and snippets.

@wolterlw
Created September 20, 2019 19:10
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wolterlw/6f1ebc49230506f8e9ce5facc5251d4f to your computer and use it in GitHub Desktop.
Save wolterlw/6f1ebc49230506f8e9ce5facc5251d4f to your computer and use it in GitHub Desktop.
c++ program to get anchors needed for hand detection
/*
parameter JSON
{
"num_layers": 5,
"min_scale": 0.1171875,
"max_scale": 0.75,
"input_size_height": 256,
"input_size_width": 256,
"anchor_offset_x": 0.5,
"anchor_offset_y": 0.5,
"strides": [8,16,32,32,32],
"aspect_ratios": [1.0],
"fixed_anchor_size": true,
"interpolated_scale_aspect_ratio": 1.0,
"reduce_boxes_in_lowest_layer": false
}
*/
#include <vector>
#include <cmath>
#include <iostream>
#include <json.hpp>
#include <fstream>
//see github.com/nlohmann/json
using json=nlohmann::json;
class Anchor{
public:
float x_center = 1;
float y_center = 2;
float h = 3;
float w = 4;
void set_x_center(float val){
x_center = val;
}
void set_y_center(float val){
y_center = val;
}
void set_w(float val){
w = val;
}
void set_h(float val){
h = val;
}
void print(){
std::cout << x_center << "," << y_center << "," <<w << "," << h << std::endl;
}
};
float CalculateScale(float min_scale, float max_scale, int stride_index,
int num_strides) {
return min_scale +
(max_scale - min_scale) * 1.0 * stride_index / (num_strides - 1.0f);
}
std::vector<Anchor> GenerateAnchors(json options){
std::vector<Anchor> anchors;
anchors.reserve(2000);
int layer_id = 0;
while (layer_id < options["strides"].size()) {
std::vector<float> anchor_height;
std::vector<float> anchor_width;
std::vector<float> aspect_ratios;
std::vector<float> scales;
// 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"].size() &&
(int) options["strides"][last_same_stride_layer] ==
(int) options["strides"][layer_id]) {
const float scale =
CalculateScale((float) options["min_scale"], (float) options["max_scale"],
last_same_stride_layer, (int) options["strides"].size());
if (last_same_stride_layer == 0 &&
options["reduce_boxes_in_lowest_layer"]) {
// For first layer, it can be specified to use predefined anchors.
aspect_ratios.push_back(1.0);
aspect_ratios.push_back(2.0);
aspect_ratios.push_back(0.5);
scales.push_back(0.1);
scales.push_back(scale);
scales.push_back(scale);
} else {
for (int aspect_ratio_id = 0;
aspect_ratio_id < options["aspect_ratios"].size();
++aspect_ratio_id) {
aspect_ratios.push_back(options["aspect_ratios"][aspect_ratio_id]);
scales.push_back(scale);
}
if (options["interpolated_scale_aspect_ratio"] > 0.0) {
const float scale_next =
last_same_stride_layer == options["strides"].size() - 1
? 1.0f
: CalculateScale(options["min_scale"], options["max_scale"],
last_same_stride_layer + 1,
options["strides"].size());
scales.push_back(std::sqrt(scale * scale_next));
aspect_ratios.push_back(options["interpolated_scale_aspect_ratio"]);
}
}
last_same_stride_layer++;
}
for (int i = 0; i < aspect_ratios.size(); ++i) {
const float ratio_sqrts = std::sqrt(aspect_ratios[i]);
anchor_height.push_back(scales[i] / ratio_sqrts);
anchor_width.push_back(scales[i] * ratio_sqrts);
}
int feature_map_height = 0;
int feature_map_width = 0;
if (false) { //(options["feature_map_height"].size()) {
feature_map_height = (float)options["feature_map_height"][layer_id];
feature_map_width = (float)options["feature_map_width"][layer_id];
} else {
const int stride = (int)options["strides"][layer_id];
feature_map_height =
std::ceil(1.0f * (float)options["input_size_height"] / stride);
feature_map_width = std::ceil(1.0f * (float)options["input_size_width"] / 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 < anchor_height.size(); ++anchor_id) {
// TODO: Support specifying anchor_offset_x, anchor_offset_y.
const float x_center =
(x + (float)options["anchor_offset_x"]) * 1.0f / feature_map_width;
const float y_center =
(y + (float)options["anchor_offset_y"]) * 1.0f / feature_map_height;
Anchor new_anchor;
new_anchor.set_x_center(x_center);
new_anchor.set_y_center(y_center);
if ((bool)options["fixed_anchor_size"]) {
new_anchor.set_w(1.0f);
new_anchor.set_h(1.0f);
} else {
new_anchor.set_w(anchor_width[anchor_id]);
new_anchor.set_h(anchor_height[anchor_id]);
}
anchors.push_back(new_anchor);
}
}
}
layer_id = last_same_stride_layer;
}
return anchors;
}
int main(int argc, char const *argv[])
{
std::ifstream inp_file("./options.json");
json options;
inp_file >> options;
std::vector<Anchor> res = GenerateAnchors(options);
for (auto value: res)
value.print();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment