mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 23:56:30 +00:00
Add annotationResult and put them into json
This commit is contained in:
@@ -1,121 +0,0 @@
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
|
||||
namespace Azaion.Annotator.DTO;
|
||||
|
||||
public class AnnotationInfo
|
||||
{
|
||||
public int ClassNumber { get; set; }
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
|
||||
public AnnotationInfo() { }
|
||||
public AnnotationInfo(int classNumber, double x, double y, double width, double height)
|
||||
{
|
||||
ClassNumber = classNumber;
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public override string ToString() => $"{ClassNumber} {X:F5} {Y:F5} {Width:F5} {Height:F5}".Replace(',', '.');
|
||||
|
||||
public AnnotationInfo ToLabelCoordinates(Size canvasSize, Size videoSize)
|
||||
{
|
||||
var cw = canvasSize.Width;
|
||||
var ch = canvasSize.Height;
|
||||
var canvasAR = cw / ch;
|
||||
var videoAR = videoSize.Width / videoSize.Height;
|
||||
|
||||
var annInfo = new AnnotationInfo { ClassNumber = this.ClassNumber };
|
||||
double left, top;
|
||||
if (videoAR > canvasAR) //100% width
|
||||
{
|
||||
left = X / cw;
|
||||
annInfo.Width = Width / cw;
|
||||
var realHeight = cw / videoAR; //real video height in pixels on canvas
|
||||
var blackStripHeight = (ch - realHeight) / 2.0; //height of black strips at the top and bottom
|
||||
top = (Y - blackStripHeight) / realHeight;
|
||||
annInfo.Height = Height / realHeight;
|
||||
}
|
||||
else //100% height
|
||||
{
|
||||
top = Y / ch;
|
||||
annInfo.Height = Height / ch;
|
||||
var realWidth = ch * videoAR; //real video width in pixels on canvas
|
||||
var blackStripWidth = (cw - realWidth) / 2.0; //height of black strips at the top and bottom
|
||||
left = (X - blackStripWidth) / realWidth;
|
||||
annInfo.Width = Width / realWidth;
|
||||
}
|
||||
|
||||
annInfo.X = left + annInfo.Width / 2.0;
|
||||
annInfo.Y = top + annInfo.Height / 2.0;
|
||||
|
||||
return annInfo;
|
||||
}
|
||||
|
||||
public AnnotationInfo ToCanvasCoordinates(Size canvasSize, Size videoSize)
|
||||
{
|
||||
var cw = canvasSize.Width;
|
||||
var ch = canvasSize.Height;
|
||||
var canvasAR = cw / ch;
|
||||
var videoAR = videoSize.Width / videoSize.Height;
|
||||
|
||||
var annInfo = new AnnotationInfo { ClassNumber = this.ClassNumber };
|
||||
|
||||
double left = X - Width / 2;
|
||||
double top = Y - Height / 2;
|
||||
|
||||
if (videoAR > canvasAR) //100% width
|
||||
{
|
||||
var realHeight = cw / videoAR; //real video height in pixels on canvas
|
||||
var blackStripHeight = (ch - realHeight) / 2.0; //height of black strips at the top and bottom
|
||||
|
||||
annInfo.X = left * cw;
|
||||
annInfo.Y = top * realHeight + blackStripHeight;
|
||||
annInfo.Width = Width * cw;
|
||||
annInfo.Height = Height * realHeight;
|
||||
}
|
||||
else //100% height
|
||||
{
|
||||
var realWidth = ch * videoAR; //real video width in pixels on canvas
|
||||
var blackStripWidth = (cw - realWidth) / 2.0; //height of black strips at the top and bottom
|
||||
|
||||
annInfo.X = left * realWidth + blackStripWidth;
|
||||
annInfo.Y = top * ch;
|
||||
annInfo.Width = Width * realWidth;
|
||||
annInfo.Height = Height * ch;
|
||||
}
|
||||
return annInfo;
|
||||
}
|
||||
|
||||
public static AnnotationInfo? Parse(string? s)
|
||||
{
|
||||
if (s == null || string.IsNullOrEmpty(s))
|
||||
return null;
|
||||
|
||||
var strs = s.Replace(',','.').Split(' ');
|
||||
if (strs.Length != 5)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
var res = new AnnotationInfo
|
||||
{
|
||||
ClassNumber = int.Parse(strs[0], CultureInfo.InvariantCulture),
|
||||
X = double.Parse(strs[1], CultureInfo.InvariantCulture),
|
||||
Y = double.Parse(strs[2], CultureInfo.InvariantCulture),
|
||||
Width = double.Parse(strs[3], CultureInfo.InvariantCulture),
|
||||
Height = double.Parse(strs[4], CultureInfo.InvariantCulture)
|
||||
};
|
||||
return res;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Azaion.Annotator.DTO;
|
||||
|
||||
public class AnnotationResult
|
||||
{
|
||||
[JsonProperty(PropertyName = "f")]
|
||||
public string Image { get; set; } = null!;
|
||||
[JsonProperty(PropertyName = "t")]
|
||||
public TimeSpan Time { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "p")]
|
||||
public double Percentage { get; set; }
|
||||
|
||||
public double Lat { get; set; }
|
||||
public double Lon { get; set; }
|
||||
public List<YoloLabel> Labels { get; set; } = new();
|
||||
|
||||
|
||||
public AnnotationResult() { }
|
||||
public AnnotationResult(TimeSpan time, string timeName, List<YoloLabel> labels)
|
||||
{
|
||||
Labels = labels;
|
||||
Time = time;
|
||||
Image = $"{timeName}.jpg";
|
||||
Percentage = 100;
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,13 @@ namespace Azaion.Annotator.DTO;
|
||||
public class Config
|
||||
{
|
||||
private const string CONFIG_PATH = "config.json";
|
||||
|
||||
private const string DEFAULT_VIDEO_DIR = "video";
|
||||
|
||||
private const string DEFAULT_LABELS_DIR = "labels";
|
||||
private const string DEFAULT_IMAGES_DIR = "images";
|
||||
private const string DEFAULT_RESULTS_DIR = "results";
|
||||
|
||||
private static readonly Size DefaultWindowSize = new(1280, 720);
|
||||
private static readonly Point DefaultWindowLocation = new(100, 100);
|
||||
|
||||
@@ -20,7 +24,8 @@ public class Config
|
||||
public string VideosDirectory { get; set; } = DEFAULT_VIDEO_DIR;
|
||||
public string LabelsDirectory { get; set; } = DEFAULT_LABELS_DIR;
|
||||
public string ImagesDirectory { get; set; } = DEFAULT_IMAGES_DIR;
|
||||
|
||||
public string ResultsDirectory { get; set; } = DEFAULT_RESULTS_DIR;
|
||||
|
||||
public List<AnnotationClass> AnnotationClasses { get; set; } = [];
|
||||
public Size WindowSize { get; set; }
|
||||
public Point WindowLocation { get; set; }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
|
||||
namespace Azaion.Annotator.DTO;
|
||||
@@ -12,6 +13,26 @@ public class FormState
|
||||
public string VideoName => Path.GetFileNameWithoutExtension(CurrentFile).Replace(" ", "");
|
||||
public TimeSpan CurrentVideoLength { get; set; }
|
||||
public int CurrentVolume { get; set; } = 100;
|
||||
|
||||
public List<AnnotationResult> AnnotationResults { get; set; } = [];
|
||||
|
||||
public string GetTimeName(TimeSpan ts) => $"{VideoName}_{ts:hmmssf}";
|
||||
|
||||
public TimeSpan? GetTime(string name)
|
||||
{
|
||||
var timeStr = name.Split("_").LastOrDefault();
|
||||
if (string.IsNullOrEmpty(timeStr))
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
//For some reason, TimeSpan.ParseExact doesn't work on every platform.
|
||||
return new TimeSpan(
|
||||
days: 0,
|
||||
hours: int.Parse(timeStr[0..1]),
|
||||
minutes: int.Parse(timeStr[1..3]),
|
||||
seconds: int.Parse(timeStr[3..5]),
|
||||
milliseconds: int.Parse(timeStr[5..6]) * 100);
|
||||
}
|
||||
catch (Exception e) { return null; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Azaion.Annotator.DTO;
|
||||
|
||||
public abstract class Label
|
||||
{
|
||||
[JsonProperty(PropertyName = "cl")]
|
||||
public int ClassNumber { get; set; }
|
||||
|
||||
public Label(){}
|
||||
public Label(int classNumber) { ClassNumber = classNumber; }
|
||||
}
|
||||
|
||||
public class CanvasLabel : Label
|
||||
{
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
|
||||
public CanvasLabel() { }
|
||||
public CanvasLabel(int classNumber, double x, double y, double width, double height) : base(classNumber)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public CanvasLabel(YoloLabel label, Size canvasSize, Size videoSize)
|
||||
{
|
||||
var cw = canvasSize.Width;
|
||||
var ch = canvasSize.Height;
|
||||
var canvasAr = cw / ch;
|
||||
var videoAr = videoSize.Width / videoSize.Height;
|
||||
|
||||
ClassNumber = label.ClassNumber;
|
||||
|
||||
var left = X - Width / 2;
|
||||
var top = Y - Height / 2;
|
||||
|
||||
if (videoAr > canvasAr) //100% width
|
||||
{
|
||||
var realHeight = cw / videoAr; //real video height in pixels on canvas
|
||||
var blackStripHeight = (ch - realHeight) / 2.0; //height of black strips at the top and bottom
|
||||
|
||||
X = left * cw;
|
||||
Y = top * realHeight + blackStripHeight;
|
||||
Width = label.Width * cw;
|
||||
Height = label.Height * realHeight;
|
||||
}
|
||||
else //100% height
|
||||
{
|
||||
var realWidth = ch * videoAr; //real video width in pixels on canvas
|
||||
var blackStripWidth = (cw - realWidth) / 2.0; //height of black strips at the top and bottom
|
||||
|
||||
X = left * realWidth + blackStripWidth;
|
||||
Y = top * ch;
|
||||
Width = label.Width * realWidth;
|
||||
Height = label.Height * ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class YoloLabel : Label
|
||||
{
|
||||
[JsonProperty(PropertyName = "x")]
|
||||
public double CenterX { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "y")]
|
||||
public double CenterY { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "w")]
|
||||
public double Width { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "h")]
|
||||
public double Height { get; set; }
|
||||
|
||||
public YoloLabel() { }
|
||||
public YoloLabel(int classNumber, double centerX, double centerY, double width, double height) : base(classNumber)
|
||||
{
|
||||
CenterX = centerX;
|
||||
CenterY = centerY;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public YoloLabel(CanvasLabel canvasLabel, Size canvasSize, Size videoSize)
|
||||
{
|
||||
|
||||
var cw = canvasSize.Width;
|
||||
var ch = canvasSize.Height;
|
||||
var canvasAr = cw / ch;
|
||||
var videoAr = videoSize.Width / videoSize.Height;
|
||||
|
||||
ClassNumber = canvasLabel.ClassNumber;
|
||||
|
||||
double left, top;
|
||||
if (videoAr > canvasAr) //100% width
|
||||
{
|
||||
left = canvasLabel.X / cw;
|
||||
Width = canvasLabel.Width / cw;
|
||||
var realHeight = cw / videoAr; //real video height in pixels on canvas
|
||||
var blackStripHeight = (ch - realHeight) / 2.0; //height of black strips at the top and bottom
|
||||
top = (canvasLabel.Y - blackStripHeight) / realHeight;
|
||||
Height = canvasLabel.Height / realHeight;
|
||||
}
|
||||
else //100% height
|
||||
{
|
||||
top = canvasLabel.Y / ch;
|
||||
Height = canvasLabel.Height / ch;
|
||||
var realWidth = ch * videoAr; //real video width in pixels on canvas
|
||||
var blackStripWidth = (cw - realWidth) / 2.0; //height of black strips at the top and bottom
|
||||
left = (canvasLabel.X - blackStripWidth) / realWidth;
|
||||
Width = canvasLabel.Width / realWidth;
|
||||
}
|
||||
|
||||
CenterX = left + canvasLabel.Width / 2.0;
|
||||
CenterY = top + canvasLabel.Height / 2.0;
|
||||
}
|
||||
|
||||
public static YoloLabel? Parse(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
return null;
|
||||
|
||||
var strings = s.Replace(',','.').Split(' ');
|
||||
if (strings.Length != 5)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
var res = new YoloLabel
|
||||
{
|
||||
ClassNumber = int.Parse(strings[0], CultureInfo.InvariantCulture),
|
||||
CenterX = double.Parse(strings[1], CultureInfo.InvariantCulture),
|
||||
CenterY = double.Parse(strings[2], CultureInfo.InvariantCulture),
|
||||
Width = double.Parse(strings[3], CultureInfo.InvariantCulture),
|
||||
Height = double.Parse(strings[4], CultureInfo.InvariantCulture)
|
||||
};
|
||||
return res;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => $"{ClassNumber} {CenterX:F5} {CenterY:F5} {Width:F5} {Height:F5}".Replace(',', '.');
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user