Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Controlling LifeCam Cinema on a Raspberry Pi

DZone's Guide to

Controlling LifeCam Cinema on a Raspberry Pi

In this post, we take a look at how an updated Windows 10 IoT Core can now detect and make use of LifeCam Cinema. We'll use a Raspberry Pi to help.

· IoT Zone
Free Resource

Learn how Bluetooth mesh helps you create industrial-grade networks. Download the mesh overview.

After some Windows 10 IoT Core updates, I discovered that it detected a LifeCam Cinema camera connected to it. I had tried it a few months ago, but Windows 10 IoT Core was not able to detect it back then. To find out if and how it works, I wrote a primitive UWP application that shows the picture from camera and saves photos made using the webcam.

Here is the evidence of support for LifeCam Cinema. I found it from the Windows 10 IoT Core Device Portal:

Windows 10 IoT Core. LifeCam Cinema is detected

LifeCam Cinema is shown as two devices, probably because it comes with a microphone.

Displaying Camera Picture

I found some good materials by Jeremy Lindsay that helped me complete my task:

Multi-platform alert: The code given here is for UWP, and it runs on desktop PCs and Windows phones. I’m just targeting my Raspberry Pi here, as I’m trying to build something on it.

Let’s start with a simple XAML page to show the picture from the camera. For this, there is the CaptureElement called PreviewControl.

<Page
    x:Class="UwpCam.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UwpCam"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">     <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <CaptureElement Name="PreviewControl" Stretch="Uniform" />
    </Grid>
</Page>

To make controlling the camera easier, there is the Magellanic.Camera NuGet package added to the project. The full code behind the page is here.

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();           Application.Current.Resuming += Application_Resuming;
        Application.Current.Suspending += Application_Suspending;
    }       protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
        await InitialiseCameraPreview();
    }       private async void Application_Resuming(object sender, object o)
    {
        await InitialiseCameraPreview();
    }       protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        _cameraDevice.Dispose();
    }       private void Application_Suspending(object sender, SuspendingEventArgs e)
    {
        _cameraDevice.Dispose();
    }       private CameraDevice _cameraDevice = new CameraDevice();

    private async Task InitialiseCameraPreview()
    {
        await _cameraDevice.InitialiseCameraAsync(await GetCamera());           var viewFinder = _cameraDevice.ViewFinder;

        PreviewControl.Source = viewFinder;                      await viewFinder.StartPreviewAsync();           
    }       private async Task<DeviceInformation> GetCamera()
    {
        var rearCamera = await _cameraDevice.GetCameraAtPanelLocation(Windows.Devices.Enumeration.Panel.Back);
        var defaultCamera = await _cameraDevice.GetDefaultCamera();           return rearCamera ?? defaultCamera;
    }
}

When I run this application on my Raspberry, then this is what it shows on my screen.

Windows 10 IoT Core: Image from LifeCam Cinema

It has poor resolution for some reason, but at least it works. A quick check shows that there is no support for automated video control features (yet?) but it is possible to manually set many properties like focus, brightness, hue, etc.

Taking Photos With the Webcam

To go one step further with my experiments, I modified the code above to take a photo and saved it to the default user folder. The code is simple and illustrative, but it works.

private async Task InitialiseCameraPreview()
{
    await _cameraDevice.InitialiseCameraAsync(await GetCamera());       var viewFinder = _cameraDevice.ViewFinder;       

    var lowLagCapture = await viewFinder.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));
    var capturedPhoto = await lowLagCapture.CaptureAsync();
    var softwareBitmap = capturedPhoto.Frame.SoftwareBitmap;
    await lowLagCapture.FinishAsync();       var myPictures = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
    var file = await myPictures.SaveFolder.CreateFileAsync("photo.jpg", CreationCollisionOption.GenerateUniqueName);
    SaveSoftwareBitmapToFile(softwareBitmap, file);
    softwareBitmap.Dispose();
}   private async void SaveSoftwareBitmapToFile(SoftwareBitmap softwareBitmap, StorageFile outputFile)
{
    using (IRandomAccessStream stream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);           encoder.SetSoftwareBitmap(softwareBitmap);
        encoder.BitmapTransform.ScaledWidth = 1240;
        encoder.BitmapTransform.ScaledHeight = 960;
        encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees;
        encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Cubic;
        encoder.IsThumbnailGenerated = true;           try
        {
            await encoder.FlushAsync();
        }
        catch (Exception err)
        {
            switch (err.HResult)
            {
                case unchecked((int)0x88982F81): //WINCODEC_ERR_UNSUPPORTEDOPERATION
                                                    // If the encoder does not support writing a thumbnail, then try again
                                                    // but disable thumbnail generation.
                    encoder.IsThumbnailGenerated = false;
                    break;
                default:
                    throw err;
            }
        }           if (encoder.IsThumbnailGenerated == false)
        {
            await encoder.FlushAsync();
        }
    }
}

After running the application few times, there are the following files in the default user pictures folder.

Photos on Raspberry Pi default user pictures folder

For web developers, the code above doesn’t look very familiar. There are a lot of different classes we don’t see every day at work, but it’s actually very simple and logical after going through the UWP documentation.

Wrapping Up

Windows 10 IoT Core is getting better and better about supporting different peripherals. The ability to use a webcam opens a new front for applications that can run on microcomputers. Using the webcam is easy. There are packages available in NuGet to simplify webcam-related tasks, and we can use the same UWP APIs as desktop and mobile applications. Although the Raspberry Pi is not built with photo or video processing in mind, there are still situations where we can benefit from it.

For a deeper look into Bluetooth mesh, check out this technical insight for developers.

Topics:
iot ,raspberry pi ,windows 10 iot core ,image processing ,tutorial

Published at DZone with permission of Gunnar Peipman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}