mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 11:26:31 +00:00
clamp detections to media borders - create, move, resize
fix inference start fix config fix resize rectangles show
This commit is contained in:
@@ -7,7 +7,6 @@ using System.Windows.Media.Imaging;
|
|||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
using Azaion.Common.Database;
|
using Azaion.Common.Database;
|
||||||
using Azaion.Common.DTO;
|
using Azaion.Common.DTO;
|
||||||
using Azaion.Common.Events;
|
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Color = System.Windows.Media.Color;
|
using Color = System.Windows.Media.Color;
|
||||||
using Image = System.Windows.Controls.Image;
|
using Image = System.Windows.Controls.Image;
|
||||||
@@ -40,6 +39,7 @@ public class CanvasEditor : Canvas
|
|||||||
private readonly TimeSpan _viewThreshold = TimeSpan.FromMilliseconds(400);
|
private readonly TimeSpan _viewThreshold = TimeSpan.FromMilliseconds(400);
|
||||||
|
|
||||||
public Image BackgroundImage { get; set; } = new() { Stretch = Stretch.Uniform };
|
public Image BackgroundImage { get; set; } = new() { Stretch = Stretch.Uniform };
|
||||||
|
private RectangleF? _clampedRect;
|
||||||
|
|
||||||
public static readonly DependencyProperty GetTimeFuncProp =
|
public static readonly DependencyProperty GetTimeFuncProp =
|
||||||
DependencyProperty.Register(
|
DependencyProperty.Register(
|
||||||
@@ -129,6 +129,7 @@ public class CanvasEditor : Canvas
|
|||||||
{
|
{
|
||||||
SetZoom();
|
SetZoom();
|
||||||
BackgroundImage.Source = source;
|
BackgroundImage.Source = source;
|
||||||
|
UpdateClampedRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetZoom(Matrix? matrix = null)
|
private void SetZoom(Matrix? matrix = null)
|
||||||
@@ -190,7 +191,7 @@ public class CanvasEditor : Canvas
|
|||||||
|
|
||||||
private void CanvasMouseMove(object sender, MouseEventArgs e)
|
private void CanvasMouseMove(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
var pos = e.GetPosition(this);
|
var pos = GetClampedPosition(e);
|
||||||
_horizontalLine.Y1 = _horizontalLine.Y2 = pos.Y;
|
_horizontalLine.Y1 = _horizontalLine.Y2 = pos.Y;
|
||||||
_verticalLine.X1 = _verticalLine.X2 = pos.X;
|
_verticalLine.X1 = _verticalLine.X2 = pos.X;
|
||||||
SetLeft(_classNameHint, pos.X + 10);
|
SetLeft(_classNameHint, pos.X + 10);
|
||||||
@@ -199,24 +200,36 @@ public class CanvasEditor : Canvas
|
|||||||
switch (SelectionState)
|
switch (SelectionState)
|
||||||
{
|
{
|
||||||
case SelectionState.NewAnnCreating:
|
case SelectionState.NewAnnCreating:
|
||||||
NewAnnotationCreatingMove(sender, e);
|
NewAnnotationCreatingMove(pos);
|
||||||
break;
|
break;
|
||||||
case SelectionState.AnnResizing:
|
case SelectionState.AnnResizing:
|
||||||
AnnotationResizeMove(sender, e);
|
AnnotationResizeMove(pos);
|
||||||
break;
|
break;
|
||||||
case SelectionState.AnnMoving:
|
case SelectionState.AnnMoving:
|
||||||
AnnotationPositionMove(sender, e);
|
AnnotationPositionMove(pos);
|
||||||
|
e.Handled = true;
|
||||||
break;
|
break;
|
||||||
case SelectionState.PanZoomMoving:
|
case SelectionState.PanZoomMoving:
|
||||||
PanZoomMove(sender, e);
|
PanZoomMove(pos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PanZoomMove(object sender, MouseEventArgs e)
|
private Point GetClampedPosition(MouseEventArgs e)
|
||||||
{
|
{
|
||||||
var currentPoint = e.GetPosition(this);
|
var pos = e.GetPosition(this);
|
||||||
var delta = currentPoint - _panStartPoint;
|
return !_clampedRect.HasValue
|
||||||
|
? pos
|
||||||
|
: new Point
|
||||||
|
(
|
||||||
|
Math.Clamp(pos.X, _clampedRect.Value.X, _clampedRect.Value.Right),
|
||||||
|
Math.Clamp(pos.Y, _clampedRect.Value.Y, _clampedRect.Value.Bottom)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PanZoomMove(Point point)
|
||||||
|
{
|
||||||
|
var delta = point - _panStartPoint;
|
||||||
|
|
||||||
var matrix = _matrixTransform.Matrix;
|
var matrix = _matrixTransform.Matrix;
|
||||||
matrix.Translate(delta.X, delta.Y);
|
matrix.Translate(delta.X, delta.Y);
|
||||||
@@ -229,7 +242,7 @@ public class CanvasEditor : Canvas
|
|||||||
(sender as UIElement)?.ReleaseMouseCapture();
|
(sender as UIElement)?.ReleaseMouseCapture();
|
||||||
if (SelectionState == SelectionState.NewAnnCreating)
|
if (SelectionState == SelectionState.NewAnnCreating)
|
||||||
{
|
{
|
||||||
var endPos = e.GetPosition(this);
|
var endPos = GetClampedPosition(e);
|
||||||
_newAnnotationRect.Width = 0;
|
_newAnnotationRect.Width = 0;
|
||||||
_newAnnotationRect.Height = 0;
|
_newAnnotationRect.Height = 0;
|
||||||
var width = Math.Abs(endPos.X - _newAnnotationStartPos.X);
|
var width = Math.Abs(endPos.X - _newAnnotationStartPos.X);
|
||||||
@@ -262,14 +275,14 @@ public class CanvasEditor : Canvas
|
|||||||
var origin = lb.TranslatePoint(new Point(0, 0), this);
|
var origin = lb.TranslatePoint(new Point(0, 0), this);
|
||||||
lb.Children[0].Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
|
lb.Children[0].Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
|
||||||
var size = lb.Children[0].DesiredSize;
|
var size = lb.Children[0].DesiredSize;
|
||||||
var lbRect = new RectangleF((float)origin.X, (float)origin.Y, (float)size.Width, (float)size.Height);
|
var controlLabel = new RectangleF((float)origin.X, (float)origin.Y, (float)size.Width, (float)size.Height);
|
||||||
|
|
||||||
foreach (var c in CurrentDetections)
|
foreach (var c in CurrentDetections)
|
||||||
{
|
{
|
||||||
if (c == detectionControl)
|
if (c == detectionControl)
|
||||||
continue;
|
continue;
|
||||||
var detRect = new RectangleF((float)GetLeft(c), (float)GetTop(c), (float)c.Width, (float)c.Height);
|
var detRect = new RectangleF((float)GetLeft(c), (float)GetTop(c), (float)c.Width, (float)c.Height);
|
||||||
detRect.Intersect(lbRect);
|
detRect.Intersect(controlLabel);
|
||||||
|
|
||||||
|
|
||||||
// var intersect = detections[i].ToRectangle();
|
// var intersect = detections[i].ToRectangle();
|
||||||
@@ -287,6 +300,42 @@ public class CanvasEditor : Canvas
|
|||||||
_verticalLine.Y2 = e.NewSize.Height;
|
_verticalLine.Y2 = e.NewSize.Height;
|
||||||
BackgroundImage.Width = e.NewSize.Width;
|
BackgroundImage.Width = e.NewSize.Width;
|
||||||
BackgroundImage.Height = e.NewSize.Height;
|
BackgroundImage.Height = e.NewSize.Height;
|
||||||
|
UpdateClampedRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateClampedRect()
|
||||||
|
{
|
||||||
|
if (BackgroundImage.Source is not BitmapSource imageSource)
|
||||||
|
{
|
||||||
|
_clampedRect = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var imgWidth = imageSource.PixelWidth;
|
||||||
|
var imgHeight = imageSource.PixelHeight;
|
||||||
|
var canvasWidth = ActualWidth;
|
||||||
|
var canvasHeight = ActualHeight;
|
||||||
|
|
||||||
|
var imgRatio = imgWidth / (double)imgHeight;
|
||||||
|
var canvasRatio = canvasWidth / canvasHeight;
|
||||||
|
|
||||||
|
double renderedWidth;
|
||||||
|
double renderedHeight;
|
||||||
|
|
||||||
|
if (imgRatio > canvasRatio)
|
||||||
|
{
|
||||||
|
renderedWidth = canvasWidth;
|
||||||
|
renderedHeight = canvasWidth / imgRatio;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
renderedHeight = canvasHeight;
|
||||||
|
renderedWidth = canvasHeight * imgRatio;
|
||||||
|
}
|
||||||
|
var xOffset = (canvasWidth - renderedWidth) / 2;
|
||||||
|
var yOffset = (canvasHeight - renderedHeight) / 2;
|
||||||
|
|
||||||
|
_clampedRect = new RectangleF((float)xOffset, (float)yOffset, (float)renderedWidth, (float)renderedHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Annotation Resizing & Moving
|
#region Annotation Resizing & Moving
|
||||||
@@ -300,17 +349,15 @@ public class CanvasEditor : Canvas
|
|||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AnnotationResizeMove(object sender, MouseEventArgs e)
|
private void AnnotationResizeMove(Point point)
|
||||||
{
|
{
|
||||||
if (SelectionState != SelectionState.AnnResizing)
|
if (SelectionState != SelectionState.AnnResizing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var currentPos = e.GetPosition(this);
|
|
||||||
|
|
||||||
var x = GetLeft(_curAnn);
|
var x = GetLeft(_curAnn);
|
||||||
var y = GetTop(_curAnn);
|
var y = GetTop(_curAnn);
|
||||||
var offsetX = currentPos.X - _lastPos.X;
|
var offsetX = point.X - _lastPos.X;
|
||||||
var offsetY = currentPos.Y - _lastPos.Y;
|
var offsetY = point.Y - _lastPos.Y;
|
||||||
switch (_curRec.HorizontalAlignment, _curRec.VerticalAlignment)
|
switch (_curRec.HorizontalAlignment, _curRec.VerticalAlignment)
|
||||||
{
|
{
|
||||||
case (HorizontalAlignment.Left, VerticalAlignment.Top):
|
case (HorizontalAlignment.Left, VerticalAlignment.Top):
|
||||||
@@ -350,7 +397,7 @@ public class CanvasEditor : Canvas
|
|||||||
_curAnn.Height = Math.Max(MIN_SIZE, _curAnn.Height + offsetY);
|
_curAnn.Height = Math.Max(MIN_SIZE, _curAnn.Height + offsetY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_lastPos = currentPos;
|
_lastPos = point;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AnnotationPositionStart(object sender, MouseEventArgs e)
|
private void AnnotationPositionStart(object sender, MouseEventArgs e)
|
||||||
@@ -367,19 +414,26 @@ public class CanvasEditor : Canvas
|
|||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AnnotationPositionMove(object sender, MouseEventArgs e)
|
private void AnnotationPositionMove(Point point)
|
||||||
{
|
{
|
||||||
if (SelectionState != SelectionState.AnnMoving)
|
if (SelectionState != SelectionState.AnnMoving)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var currentPos = e.GetPosition(this);
|
var offsetX = point.X - _lastPos.X;
|
||||||
var offsetX = currentPos.X - _lastPos.X;
|
var offsetY = point.Y - _lastPos.Y;
|
||||||
var offsetY = currentPos.Y - _lastPos.Y;
|
|
||||||
|
|
||||||
SetLeft(_curAnn, GetLeft(_curAnn) + offsetX);
|
var nextLeft = GetLeft(_curAnn) + offsetX;
|
||||||
SetTop(_curAnn, GetTop(_curAnn) + offsetY);
|
var nextTop = GetTop(_curAnn) + offsetY;
|
||||||
_lastPos = currentPos;
|
|
||||||
e.Handled = true;
|
if (_clampedRect.HasValue)
|
||||||
|
{
|
||||||
|
nextLeft = Math.Clamp(nextLeft, _clampedRect.Value.X, _clampedRect.Value.Right - _curAnn.Width);
|
||||||
|
nextTop = Math.Clamp(nextTop, _clampedRect.Value.Y, _clampedRect.Value.Bottom - _curAnn.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLeft(_curAnn, nextLeft);
|
||||||
|
SetTop(_curAnn, nextTop);
|
||||||
|
_lastPos = point;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -391,26 +445,29 @@ public class CanvasEditor : Canvas
|
|||||||
_newAnnotationStartPos = e.GetPosition(this);
|
_newAnnotationStartPos = e.GetPosition(this);
|
||||||
SetLeft(_newAnnotationRect, _newAnnotationStartPos.X);
|
SetLeft(_newAnnotationRect, _newAnnotationStartPos.X);
|
||||||
SetTop(_newAnnotationRect, _newAnnotationStartPos.Y);
|
SetTop(_newAnnotationRect, _newAnnotationStartPos.Y);
|
||||||
_newAnnotationRect.MouseMove += NewAnnotationCreatingMove;
|
_newAnnotationRect.MouseMove += (sender, e) =>
|
||||||
|
{
|
||||||
|
var currentPos = e.GetPosition(this);
|
||||||
|
NewAnnotationCreatingMove(currentPos);
|
||||||
|
};
|
||||||
|
|
||||||
SelectionState = SelectionState.NewAnnCreating;
|
SelectionState = SelectionState.NewAnnCreating;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NewAnnotationCreatingMove(object sender, MouseEventArgs e)
|
private void NewAnnotationCreatingMove(Point point)
|
||||||
{
|
{
|
||||||
if (SelectionState != SelectionState.NewAnnCreating)
|
if (SelectionState != SelectionState.NewAnnCreating)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var currentPos = e.GetPosition(this);
|
var diff = point - _newAnnotationStartPos;
|
||||||
var diff = currentPos - _newAnnotationStartPos;
|
|
||||||
|
|
||||||
_newAnnotationRect.Height = Math.Abs(diff.Y);
|
_newAnnotationRect.Height = Math.Abs(diff.Y);
|
||||||
_newAnnotationRect.Width = Math.Abs(diff.X);
|
_newAnnotationRect.Width = Math.Abs(diff.X);
|
||||||
|
|
||||||
if (diff.X < 0)
|
if (diff.X < 0)
|
||||||
SetLeft(_newAnnotationRect, currentPos.X);
|
SetLeft(_newAnnotationRect, point.X);
|
||||||
if (diff.Y < 0)
|
if (diff.Y < 0)
|
||||||
SetTop(_newAnnotationRect, currentPos.Y);
|
SetTop(_newAnnotationRect, point.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateDetections(Annotation annotation, List<DetectionClass> detectionClasses, Size mediaSize)
|
public void CreateDetections(Annotation annotation, List<DetectionClass> detectionClasses, Size mediaSize)
|
||||||
@@ -432,7 +489,9 @@ public class CanvasEditor : Canvas
|
|||||||
canvasLabel = new CanvasLabel(yoloLabel, RenderSize, mediaSize, canvasLabel.Confidence);
|
canvasLabel = new CanvasLabel(yoloLabel, RenderSize, mediaSize, canvasLabel.Confidence);
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateDetectionControl(detectionClass, annotation.Time, canvasLabel);
|
var control = CreateDetectionControl(detectionClass, annotation.Time, canvasLabel);
|
||||||
|
control.UpdateLayout();
|
||||||
|
CheckLabelBoundaries(control);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,8 +541,6 @@ public class CanvasEditor : Canvas
|
|||||||
RemoveAnnotations(expiredAnns);
|
RemoveAnnotations(expiredAnns);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetBackground() => Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
|
|
||||||
|
|
||||||
public void ZoomTo(Point point)
|
public void ZoomTo(Point point)
|
||||||
{
|
{
|
||||||
SetZoom();
|
SetZoom();
|
||||||
|
|||||||
@@ -127,9 +127,9 @@ public class DetectionControl : Border
|
|||||||
VerticalAlignment = VerticalAlignment.Stretch,
|
VerticalAlignment = VerticalAlignment.Stretch,
|
||||||
Children = { _selectionFrame }
|
Children = { _selectionFrame }
|
||||||
};
|
};
|
||||||
|
_grid.Children.Add(DetectionLabelContainer);
|
||||||
foreach (var rect in _resizedRectangles)
|
foreach (var rect in _resizedRectangles)
|
||||||
_grid.Children.Add(rect);
|
_grid.Children.Add(rect);
|
||||||
_grid.Children.Add(DetectionLabelContainer);
|
|
||||||
|
|
||||||
Child = _grid;
|
Child = _grid;
|
||||||
Cursor = Cursors.SizeAll;
|
Cursor = Cursors.SizeAll;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class InferenceClient : IInferenceClient
|
|||||||
Arguments = $"-p {_inferenceClientConfig.ZeroMqPort} -lp {_loaderClientConfig.ZeroMqPort} -a {_inferenceClientConfig.ApiUrl}",
|
Arguments = $"-p {_inferenceClientConfig.ZeroMqPort} -lp {_loaderClientConfig.ZeroMqPort} -a {_inferenceClientConfig.ApiUrl}",
|
||||||
CreateNoWindow = true
|
CreateNoWindow = true
|
||||||
};
|
};
|
||||||
//process.Start();
|
process.Start();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,10 +17,10 @@
|
|||||||
"DirectoriesConfig": {
|
"DirectoriesConfig": {
|
||||||
"ApiResourcesDirectory": "stage",
|
"ApiResourcesDirectory": "stage",
|
||||||
"VideosDirectory": "E:\\Azaion6",
|
"VideosDirectory": "E:\\Azaion6",
|
||||||
"LabelsDirectory": "E:\\labels_test",
|
"LabelsDirectory": "E:\\labels",
|
||||||
"ImagesDirectory": "E:\\images_test",
|
"ImagesDirectory": "E:\\images",
|
||||||
"ResultsDirectory": "E:\\results_test",
|
"ResultsDirectory": "E:\\results",
|
||||||
"ThumbnailsDirectory": "E:\\thumbnails_test",
|
"ThumbnailsDirectory": "E:\\thumbnails",
|
||||||
"GpsSatDirectory": "satellitesDir",
|
"GpsSatDirectory": "satellitesDir",
|
||||||
"GpsRouteDirectory": "routeDir"
|
"GpsRouteDirectory": "routeDir"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user