简体   繁体   中英

Draw rectangle over SwapChainPanel

I'm receiving a live video from a DJI drone in a SwapChainPanel and I'm using template matching from OpenCV to find an image inside the frames of the video. I want to draw a rectangle when the subgimage is detected, but there are white spaces in both sides of the frames and I don't know how to get the size of those or align the image to the left and top.

在此处输入图像描述

Here is the XAML:

<SwapChainPanel x:Name="swapChainPanel" Grid.Column="8" Grid.ColumnSpan="4" Grid.Row="2" Grid.RowSpan="11">
        <Canvas>
            <Rectangle x:Name="rectFiducial" Visibility="Collapsed" Stroke="Red"></Rectangle>
            <Rectangle Stroke="Blue" Width="400" Height="400"></Rectangle>
        </Canvas>
    </SwapChainPanel>

Here is the code when I try to draw the rectangle with the results of the Template Matching:

SoftwareBitmap inputBitmap = SoftwareBitmap.CreateCopyFromBuffer(CryptographicBuffer.CreateFromByteArray(imageData),
           BitmapPixelFormat.Rgba8,
           imageWidth,
           imageHeight);

            if (inputBitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8
            || inputBitmap.BitmapAlphaMode != BitmapAlphaMode.Premultiplied)
            {
                inputBitmap = SoftwareBitmap.Convert(inputBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
            }

            int x = 0, y = 0, matchMethod = 0;
            double matchResult = 0;
            Stopwatch testWatch = new Stopwatch();
            testWatch.Start();

            await txtMatchMethod.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                int.TryParse(txtMatchMethod.Text, out matchMethod);
            });

            OpenCV.TemplateMatching(inputBitmap, template, matchMethod, out x, out y, out matchResult);

            testWatch.Stop();

            await txtMatchTime.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                txtMatchTime.Text = testWatch.ElapsedMilliseconds.ToString();
                txtMatchResult.Text = matchResult.ToString();

                double swapX = x * swapChainPanel.ActualWidth / imageWidth;
                double swapY = y * swapChainPanel.ActualHeight / imageHeight;
                double swapWidth = template.PixelWidth * swapChainPanel.ActualWidth / imageWidth;
                double swapHeight = template.PixelHeight * swapChainPanel.ActualHeight / imageHeight;

                rectFiducial.SetValue(Canvas.LeftProperty, swapX);
                rectFiducial.SetValue(Canvas.TopProperty, swapY);
                rectFiducial.Width = swapWidth;
                rectFiducial.Height = swapHeight;
                rectFiducial.Visibility = Visibility.Visible;

            });
        }

There is an event where I can get the bytes of the image and I tried to display it in an Image inside a Canvas , but the image didn't stretch to fit the canvas size.

Edit

I realized that I'm calculating the position based on the width and height of the SwapChainPanel , but I have to calculate it with the width and height of the image inside. So I would need to get the data of the resized image that is inside the SwapChainPanel and the padding of the left side.

Well, I couldn't find a solution for the SwapChainPanel , but I found a solution with the image and the canvas. I was trying to make something like this:

<Canvas x:Name="canvas" Grid.Column="8" Grid.ColumnSpan="4" Grid.Row="4" Grid.RowSpan="11">
        <Image x:Name="imgDrone" HorizontalAlignment="Left"/>
        <Rectangle x:Name="rectFiducial" Visibility="Collapsed" Stroke="Red"></Rectangle>
        <Rectangle Stroke="Blue" Width="400" Height="400"></Rectangle>
    </Canvas>

But I couldn't stretch the image, it was displayed with it's real size. So instead of declaring the image inside the Canvas I just took it out and set it's column and row with the same values of the canvas. Like this:

<Image x:Name="imgDrone" HorizontalAlignment="Left" Grid.Column="8" Grid.ColumnSpan="2" Grid.Row="2" Grid.RowSpan="11"/>

    <Canvas x:Name="canvas" Grid.Column="8" Grid.ColumnSpan="4" Grid.Row="4" Grid.RowSpan="11">
        <Rectangle x:Name="rectFiducial" Visibility="Collapsed" Stroke="Red"></Rectangle>
        <Rectangle Stroke="Blue" Width="400" Height="400"></Rectangle>
    </Canvas>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM