Skip to content

Instantly share code, notes, and snippets.

@xumix
Last active November 30, 2022 09:22
Show Gist options
  • Save xumix/9ed74115e6f03f2f414c802a0393a793 to your computer and use it in GitHub Desktop.
Save xumix/9ed74115e6f03f2f414c802a0393a793 to your computer and use it in GitHub Desktop.
Convert Label Studio annotations from rectangle to polygon
void Main()
{
// label studio exported json
var json = File.ReadAllText(@"C:\project-2-at-2022-11-29-16-57-b274c21b.json");
var jArray = JsonConvert.DeserializeObject<JArray>(json);
foreach (var obj in jArray)
{
foreach (var ann in obj["annotations"])
{
foreach (var res in ann["result"])
{
// no need to convert
if (res["type"].ToString() == "polygonlabels")
{
continue;
}
var value = res["value"];
var (x, y, w, h, rotation) = GetRectCoords(value);
res["type"] = "polygonlabels";
res["from_name"] = "label_polys";
var newValue = new
{
polygonlabels = new[] { value["rectanglelabels"][0] },
points = new[]
{
new[] { x, y },
new[] { x+w, y },
new[] {(x+w), (y+h) },
new[] { x, y+h },
}
};
res["value"] = JToken.FromObject(newValue);
//res.Dump();
}
}
}
File.WriteAllText(@"c:\Ml\poly-convert.json", JsonConvert.SerializeObject(jArray, Newtonsoft.Json.Formatting.Indented));
}
// You can define other methods, fields, classes and namespaces here
// Ported from label-studio-converter/converter.py 'def rotated_rectangle(label)'
private (double label_x, double label_y, double label_w, double label_h, double rotation) GetRectCoords(JToken value)
{
var label_x = (value["x"].Value<double>());
var label_y = (value["y"].Value<double>());
var label_w = (value["width"].Value<double>());
var label_h = (value["height"].Value<double>());
var rotation = value["rotation"].Value<float>();
if (Math.Abs(rotation) > 0)
{
var alpha = Math.Atan(label_h / label_w);
var beta = Math.PI * (rotation / 180); // Label studio defines the angle towards the vertical axis
var radius = Math.Sqrt(Math.Pow((label_w / 2), 2) + Math.Pow((label_h / 2), 2));
//Label studio saves the position of top left corner after rotation
var x_0 = label_x - radius * (Math.Cos(Math.PI - alpha - beta) - Math.Cos(Math.PI - alpha)) + label_w / 2;
var y_0 = label_y + radius * (Math.Sin(Math.PI - alpha - beta) - Math.Sin(Math.PI - alpha)) + label_h / 2;
var theta_1 = alpha + beta;
var theta_2 = Math.PI - alpha + beta;
var theta_3 = Math.PI + alpha + beta;
var theta_4 = 2 * Math.PI - alpha + beta;
var x_coord = new[]
{
x_0 + radius * Math.Cos(theta_1),
x_0 + radius * Math.Cos(theta_2),
x_0 + radius * Math.Cos(theta_3),
x_0 + radius * Math.Cos(theta_4)
};
var y_coord = new[]
{
y_0 + radius * Math.Sin(theta_1),
y_0 + radius * Math.Sin(theta_2),
y_0 + radius * Math.Sin(theta_3),
y_0 + radius * Math.Sin(theta_4)
};
label_x = x_coord.Min();
label_y = y_coord.Min();
label_w = x_coord.Max() - label_x;
label_h = y_coord.Max() - label_y;
}
return (label_x, label_y, label_w, label_h, rotation);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment