From 56abd4e2169ffc36fb943385e1be3e656635fcac Mon Sep 17 00:00:00 2001 From: avosskuehler Date: Mon, 14 Nov 2022 22:23:34 +0100 Subject: [PATCH] NEW: Option to set orientation of right-handed coordinate system to arbitrary angle. BUGFIX: Prevent crash if video properties could not be called with DirectShow. BUGFIX: Correct position in video, if double click on data point row in data window. --- VianaNET/Data/VideoData.cs | 33 +++++++++++++++++-- VianaNET/MainWindow/MainWindow.xaml | 4 +-- .../ManualDataAquisitionWindow.xaml.cs | 18 +++++----- .../DataAcquisition/ModifyDataWindow.xaml.cs | 33 +++++++++---------- .../Modules/Video/Control/VideoCapturer.cs | 9 ++++- .../Video/Dialogs/CoordinateSystemWindow.cs | 30 +++++++++-------- 6 files changed, 82 insertions(+), 45 deletions(-) diff --git a/VianaNET/Data/VideoData.cs b/VianaNET/Data/VideoData.cs index 033b3a7..0fc44a3 100644 --- a/VianaNET/Data/VideoData.cs +++ b/VianaNET/Data/VideoData.cs @@ -483,7 +483,7 @@ public void UpdatePoint(int frameIndex, int objectIndex, Point newLocation) //Point origin = App.Project.CalibrationData.OriginInPixel; Point transformedPoint = newLocation; //transformedPoint.Offset(-origin.X, -origin.Y); - transformedPoint = App.Project.CalibrationData.CoordinateTransform.Transform(transformedPoint); + //transformedPoint = App.Project.CalibrationData.CoordinateTransform.Transform(transformedPoint); sample.Object[objectIndex].PixelX = transformedPoint.X; sample.Object[objectIndex].PixelY = transformedPoint.Y; } @@ -520,7 +520,7 @@ protected virtual void OnPropertyChanged(string propertyName) /// private static Point CalibrateSample(DataSample value) { - if (!App.Project.CalibrationData.IsVideoCalibrated) + if (!App.Project.CalibrationData.IsVideoCalibrated && App.Project.CalibrationData.CoordinateTransform.IsIdentity) { return new Point(value.PixelX, value.PixelY); } @@ -528,12 +528,41 @@ private static Point CalibrateSample(DataSample value) Point origin = App.Project.CalibrationData.OriginInPixel; Point calibratedPoint = new Point(value.PixelX - origin.X, value.PixelY - origin.Y); + calibratedPoint = App.Project.CalibrationData.CoordinateTransform.Transform(calibratedPoint); + calibratedPoint.X = calibratedPoint.X * App.Project.CalibrationData.ScalePixelToUnit; calibratedPoint.Y = calibratedPoint.Y * App.Project.CalibrationData.ScalePixelToUnit; return calibratedPoint; } + ///// + ///// The calibrate sample. + ///// + ///// + ///// The value. + ///// + ///// + ///// The . + ///// + //private static DataSample RevertSampleCalibration(Point value) + //{ + // if (!App.Project.CalibrationData.IsVideoCalibrated && App.Project.CalibrationData.CoordinateTransform.IsIdentity) + // { + // return new Point(value.PixelX, value.PixelY); + // } + + // Point origin = App.Project.CalibrationData.OriginInPixel; + // Point calibratedPoint = new Point(value.PixelX - origin.X, value.PixelY - origin.Y); + + // calibratedPoint = App.Project.CalibrationData.CoordinateTransform.Transform(calibratedPoint); + + // calibratedPoint.X = calibratedPoint.X * App.Project.CalibrationData.ScalePixelToUnit; + // calibratedPoint.Y = calibratedPoint.Y * App.Project.CalibrationData.ScalePixelToUnit; + + // return calibratedPoint; + //} + /// /// Returns the factor to convert sample with milliseconds in the current time unit; /// diff --git a/VianaNET/MainWindow/MainWindow.xaml b/VianaNET/MainWindow/MainWindow.xaml index d9e661a..47039cf 100644 --- a/VianaNET/MainWindow/MainWindow.xaml +++ b/VianaNET/MainWindow/MainWindow.xaml @@ -293,13 +293,13 @@ ToolTipTitle="{lex:Loc VianaNET:Labels:ButtonRotateVideoToolTipTitle}" ToolTipDescription="{lex:Loc VianaNET:Labels:ButtonRotateVideoToolTipDescription}" IsEnabled="{Binding Path=HasVideo, Source={x:Static control:Video.Instance}}"/> - + IsEnabled="{Binding Path=HasVideo, Source={x:Static control:Video.Instance}}"/> Index of the frame. public void MoveToFrame(int frameIndex) { - var newMediaPosition = Video.Instance.VideoPlayerElement.FrameTimeInMS * frameIndex; + var newMediaPosition = Video.Instance.VideoPlayerElement.FrameTimeInMS * (frameIndex - 1); Video.Instance.VideoPlayerElement.MediaPositionInMS = newMediaPosition; this.TimelineSlider.Value = newMediaPosition; Video.Instance.VideoPlayerElement.UpdateFrameIndex(); @@ -317,14 +317,14 @@ private void PlayerMouseDown(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left) { - double scaledX = e.GetPosition(this.VideoImage).X; - double scaledY = e.GetPosition(this.VideoImage).Y; - var factorX = Video.Instance.VideoElement.NaturalVideoWidth / this.VideoImage.ActualWidth; - var factorY = Video.Instance.VideoElement.NaturalVideoHeight / this.VideoImage.ActualHeight; - var originalX = factorX * scaledX; - var originalY = factorY * scaledY; + double posX = e.GetPosition(this.VideoImage).X; + double posY = e.GetPosition(this.VideoImage).Y; + double scaleX = Video.Instance.VideoElement.NaturalVideoWidth / this.VideoImage.ActualWidth; + double scaleY = Video.Instance.VideoElement.NaturalVideoHeight / this.VideoImage.ActualHeight; + double pixelX = scaleX * posX; + double pixelY = scaleY * posY; - App.Project.VideoData.AddPoint(this.IndexOfTrackedObject - 1, new Point(originalX, Video.Instance.VideoElement.NaturalVideoHeight - originalY)); + App.Project.VideoData.AddPoint(this.IndexOfTrackedObject - 1, new Point(pixelX, Video.Instance.VideoElement.NaturalVideoHeight - pixelY)); if (this.IndexOfTrackedObject == App.Project.ProcessingData.NumberOfTrackedObjects) { @@ -404,18 +404,17 @@ private void CursorEllipse_OnMouseLeftButtonUp(object sender, MouseButtonEventAr this.SetVisibilityOfSharpCursor(false); this.Cursor = Cursors.Arrow; - double scaledX = e.GetPosition(this.VideoImage).X; - double scaledY = e.GetPosition(this.VideoImage).Y; - double factorX = Video.Instance.VideoElement.NaturalVideoWidth / this.VideoImage.ActualWidth; - double factorY = Video.Instance.VideoElement.NaturalVideoHeight / this.VideoImage.ActualHeight; - double originalX = factorX * scaledX; - double originalY = factorY * scaledY; + double posX = e.GetPosition(this.VideoImage).X; + double posY = e.GetPosition(this.VideoImage).Y; + double scaleX = Video.Instance.VideoElement.NaturalVideoWidth / this.VideoImage.ActualWidth; + double scaleY = Video.Instance.VideoElement.NaturalVideoHeight / this.VideoImage.ActualHeight; + double pixelX = scaleX * posX; + double pixelY = scaleY * posY; App.Project.VideoData.UpdatePoint( Video.Instance.FrameIndex, this.IndexOfTrackedObject - 1, - new Point(originalX, Video.Instance.VideoElement.NaturalVideoHeight - originalY)); - + new Point(pixelX, Video.Instance.VideoElement.NaturalVideoHeight - pixelY)); } } @@ -524,7 +523,7 @@ private void UpdateDataPointLocation() if (sample.Object != null && sample.Object[i - 1] != null) { Point location = new Point(sample.Object[i - 1].PixelX, Video.Instance.VideoElement.NaturalVideoHeight - sample.Object[i - 1].PixelY); - location = App.Project.CalibrationData.CoordinateTransform.Transform(location); + //location = App.Project.CalibrationData.CoordinateTransform.Transform(location); //Point origin = App.Project.CalibrationData.OriginInPixel; //location.Offset(origin.X, origin.Y); var scaledX = location.X / factorX; diff --git a/VianaNET/Modules/Video/Control/VideoCapturer.cs b/VianaNET/Modules/Video/Control/VideoCapturer.cs index 3998965..1b2f6be 100644 --- a/VianaNET/Modules/Video/Control/VideoCapturer.cs +++ b/VianaNET/Modules/Video/Control/VideoCapturer.cs @@ -160,7 +160,14 @@ public void ShowPropertyPageOfVideoDevice() //{ // DShowUtils.DisplayPropertyPage(IntPtr.Zero, this.VideoDeviceIndex); //} - this.OpenCVObject.Set(VideoCaptureProperties.Settings, 1); + try + { + this.OpenCVObject.Set(VideoCaptureProperties.Settings, 1); + } + catch (System.Exception) + { + InformationDialog.Show("Fehler", "Eigenschaftsseite kann nicht angezeigt werden", false); + } } diff --git a/VianaNET/Modules/Video/Dialogs/CoordinateSystemWindow.cs b/VianaNET/Modules/Video/Dialogs/CoordinateSystemWindow.cs index b8c6670..1e9d800 100644 --- a/VianaNET/Modules/Video/Dialogs/CoordinateSystemWindow.cs +++ b/VianaNET/Modules/Video/Dialogs/CoordinateSystemWindow.cs @@ -23,6 +23,7 @@ namespace VianaNET.Modules.Video.Dialogs { + using SharpDX.Direct3D9; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -148,14 +149,17 @@ protected override void ContainerMouseLeftButtonDown(object sender, MouseButtonE { this.DialogResult = true; Vector vectorDefault = new Vector(1, 0); - Vector vectorXAxis = new Vector(this.directionX.X2 - this.directionX.X1, this.directionX.Y2 - this.directionX.Y1); - Vector vectorYAxis = new Vector(this.directionY.X2 - this.directionY.X1, this.directionY.Y2 - this.directionY.Y1); + Vector vectorXAxis = new Vector(this.directionX.X2 - this.directionX.X1, this.directionX.Y1 - this.directionX.Y2); + Vector vectorYAxis = new Vector(this.directionY.X2 - this.directionY.X1, this.directionY.Y1 - this.directionY.Y2); double angle = Vector.AngleBetween(vectorXAxis, vectorYAxis); - int scaleY = angle < 0 ? 1 : -1; + + // angle = 90 is CCW right handed + // angle = -90 is CW left hand + int scaleY = angle < 0 ? -1 : 1; Matrix matrix = new Matrix(); double angleX = Vector.AngleBetween(vectorDefault, vectorXAxis); matrix.Scale(1, scaleY); - matrix.Rotate(angleX); + matrix.Rotate(-angleX); App.Project.CalibrationData.CoordinateTransform = matrix; this.Close(); @@ -236,7 +240,7 @@ private void CoordinateSystemWindowLoaded(object sender, RoutedEventArgs e) if (this.GetScales(out double scaleX, out double scaleY)) { double originXInScreenPixel = App.Project.CalibrationData.OriginInPixel.X * scaleX; - double originYInScreenPixel = App.Project.CalibrationData.OriginInPixel.Y * scaleY; + double originYInScreenPixel = (Video.Control.Video.Instance.VideoElement.NaturalVideoHeight - App.Project.CalibrationData.OriginInPixel.Y) * scaleY; Canvas.SetLeft(this.originPath, originXInScreenPixel - this.originPath.ActualWidth / 2); Canvas.SetTop(this.originPath, originYInScreenPixel - this.originPath.ActualHeight / 2); this.directionX.X1 = originXInScreenPixel; @@ -312,20 +316,20 @@ private void SetYAxis(Point mouseLocation) if (this.GetScales(out double scaleX, out double scaleY)) { double originXInScreenPixel = App.Project.CalibrationData.OriginInPixel.X * scaleX; - double originYInScreenPixel = App.Project.CalibrationData.OriginInPixel.Y * scaleY; + double originYInScreenPixel = (Video.Control.Video.Instance.VideoElement.NaturalVideoHeight - App.Project.CalibrationData.OriginInPixel.Y) * scaleY; Vector vectorXAxis = new Vector(this.directionX.X2 - this.directionX.X1, this.directionX.Y2 - this.directionX.Y1); Vector vectorMouse = new Vector(mouseLocation.X - originXInScreenPixel, mouseLocation.Y - originYInScreenPixel); double angleMouseXAxis = Vector.AngleBetween(vectorXAxis, vectorMouse); Vector vectorY; - if (angleMouseXAxis >= 0 && angleMouseXAxis <= 180) - { - vectorY = new Vector(-vectorXAxis.Y, vectorXAxis.X); - } - else - { + //if (angleMouseXAxis >= 0 && angleMouseXAxis <= 180) + //{ + // vectorY = new Vector(-vectorXAxis.Y, vectorXAxis.X); + //} + //else + //{ vectorY = new Vector(vectorXAxis.Y, -vectorXAxis.X); - } + //} this.directionY.X2 = originXInScreenPixel + vectorY.X; this.directionY.Y2 = originYInScreenPixel + vectorY.Y;