Webcam - Camera Preview rotates wrong way
Asked Answered
F

1

10

I would like your help please on a WebCamera problem. I've used a library available from Nuget; WebEye.Controls.Wpf.WebCameraControl (version 1.0.0). The URL is https://www.nuget.org/packages/WebEye.Controls.Wpf.WebCameraControl/

The article and instructions are available at: http://www.codeproject.com/Articles/330177/Yet-another-Web-Camera-control

Due to project constraints, I developed a WPF application for a Linx tablet (Windows 10), rather than as a Universal Windows Application. I used the WebEye library to connect to the webcam on the tablet and take pictures with it. It works fine when I hold the tablet in landscape, but not when I hold the tablet in portrait mode. In portrait mode, the CameraPreview/VideoWindow automatically rotates -90 degrees.

I tried resolve the problem to no avail.

  • Rotate the control surrounding the video window via the Webcamera RenderTransform or LayoutTransform property – The control rotates but the video image does not rotate correctly.
  • Tried to rotate the VideoWindow inside the WebCamera Content property - I got the source code from the GitHub and set the VideoWindow available for access. Recompled the library and used it to rotate the VideoWindow via its RenderTransform property. https://github.com/jacobbo/WebEye/tree/master/WebCameraControl

No matter what I do, the camera preview is always -90 degrees.

The library is simple and it does not have many properties to manipulate the video window.

The webcontrol is in XAML.

<wpf:WebCameraControl x:Name="webCameraControl" 
                              MouseDoubleClick="webCameraControl_MouseDoubleClick" 
                              StylusButtonUp="webCameraControl_StylusButtonUp" 
                              MouseUp="webCameraControl_MouseUp" 
                              TouchUp="webCameraControl_TouchUp" 
                              GotMouseCapture="webCameraControl_GotMouseCapture" 
                              />

This is how I initialised the WebCamera. When the UserControl is loaded, it will then automatically connect to the webcam on the tablet. See startViewing() function.

private WebCameraId _cameraID = null;

private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            startViewing();
        }

private void startViewing()
        {
            List<WebCameraId> cams = (List<WebCameraId>)webCameraControl.GetVideoCaptureDevices();

            if (cams.Count > 0)
            {
                _cameraID = (WebCameraId)cams[0];

                webCameraControl.StartCapture(_cameraID);
            }
        }

I tried to force the control to rotate it correctly when the app detects a change in the Display screen. See DisplaySettingsChanged event.

public ucWebCam()
{
    InitializeComponent();

    Microsoft.Win32.SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
}

private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
    try
    {
        double angle = 0;

        if (SystemParameters.PrimaryScreenWidth > SystemParameters.PrimaryScreenHeight)
        {
            angle = 0;
        }
        else
        {
            angle = -90;
        }

        webCameraControl.StopCapture();

        adjustWebcamAngle(angle);

        webCameraControl.StartCapture(_cameraID);

    }
    catch (Exception ex)
    {

    }
}

private void adjustWebcamAngle(double angle)
{

    try
    {
        // IGNORE portrait boolean flag
        bool portrait = false; 

        if (angle == 90 || angle == 180)
        {
            portrait = true;
        }

        // TRIED TO SET THE ANGLE OF THE CONTROL TO NO AVAIL
        RotateTransform rotTransform = new RotateTransform(angle);
        //rotTransform.Angle = angle;

        ScaleTransform scaleTransform = new ScaleTransform();
        //scaleTransform.ScaleX = (portrait) ? 0 : 1;
        //scaleTransform.ScaleY = (portrait) ? 0 : 1;

        TransformGroup tGroup = new TransformGroup();                
        //tGroup.Children.Add(scaleTransform);
        tGroup.Children.Add(rotTransform);

        // ROTATE CAMERA!
        webCameraControl.RenderTransform = tGroup;

    } catch (Exception ex)
    {

    }
}

So far I only rotated the WebCam control, not the video image.

I looked through the comments in Alexander's article with no joy at: http://www.codeproject.com/Articles/330177/Yet-another-Web-Camera-control

How can I rotate the Camera preview correctly? Can you please advise where I'm going wrong?

I have attached two images to illustrate my problem.

LandScape

Portrait

Fluoroscope answered 27/10, 2016 at 15:14 Comment(1)
Since this library seems to be based on DIrecthShow, I would suggest you to read this answer. In short: there is no easy method to do that. You either have to write you own preview engine, or you have to create your own DirectShow filter that does the trick and to add it into the capture graph.Anisometric
S
7

In case you are not a stranger to C#, I would recommend you use the EMGUCV nuget and create your own preview application. It`s not that hard, and you could use MVVM to bind the frames to your View, making it better than using code behind your control.

PS: This is not an answer, but it is a solution to your problem. I cannot not post comments yet, as I do not have 50 points :(

Have a nice day.

Stores answered 2/11, 2016 at 15:57 Comment(4)
Binding frames is a very bad idea, especially when new frames arrive at high FPS. The WPF binding engine cannot manage that, neither was it created for this kind of tasks.Anisometric
Well if it's a solution to his problem, it is an answer :) +1G
@dymanoid, it depends on what the final goal is. If this is only a preview application its enough to show 30-60 fps. But if this is a high end, observation and processing tool, then you are right. I used that nuget library to create aps that use the camera, and render 30 fps, and its ok. I have no problems.Stores
@LupuSilviu, the binding engine cannot guarantee a stable FPS, because it is driven by a Dispatcher which sorts the tasks according to their priority. I'm glad if your solution works in your particular case, but if you'll try to run a parallel task in your application (which consumes CPU and uses the Dispatcher as well), you'll never get a smooth "video" but it will rather freeze and glitch.Anisometric

© 2022 - 2024 — McMap. All rights reserved.