'C# Aforge - image is not consistent, some images are very bright most of them not

I'm trying to get a consistent image with Aforge but sometimes the image is very bright, most of the time it is good. If you look at the pictures you can see a very clear difference between the two. The picture should be like the second image so that I can perform my image processing on it but due the fact that it so bright sometimes it will mess it up. In the pictures you'll see the camera is exposed to outside light but in our test setup it isn't and even there it is a problem. I'm using a logitech c900 webcam.

enter image description here

enter image description here

I have no clue why they are different or how to solve it. I tried a couple of things like setting a brightness, giving it more time to set the filters but... The code looks as the following:

using AForge.Imaging.Filters;
using AForge.Video;
using AForge.Video.DirectShow;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;

namespace X
{
    public class LiveCamera
    {
        #region Properties
        private static readonly double _maxiumumDurationToTakePicture = 30;
        public static bool RequestPicture { get; private set; } = false;
        public static bool PictureTaken { get; private set; } = false;
        public static bool IsCameraStarted { get; private set; } = false;

        public static VideoCaptureDevice VideoSource { get; private set; }
        public static Bitmap Picture { get; private set; }
        public static CameraConfig CamConfig { get; private set; }
        #endregion

        public static void StartCameraService(CameraConfig camConfig = null)
        {
            LogUtil.Logger.Information($"StartCameraService - starting the camera service");
            try
            {
                CamConfig = CheckCameraConfig(camConfig);
                LogUtil.Logger.Information($"StartCameraService - config loaded: {camConfig}");
                var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
                var moniker = Camera.GetCameraMonikerString(videoDevices, CamConfig.CameraName);
                VideoSource = new VideoCaptureDevice(moniker);
                VideoSource.ProvideSnapshots = true;
                VideoSource.VideoResolution = Camera.GetResolution(VideoSource, CamConfig);
                Camera.SetCameraOptions(VideoSource, CamConfig);

                VideoSource.NewFrame += new NewFrameEventHandler(Video_NewFrame);
                
                Thread.Sleep(5000);
                VideoSource.Start();
                Thread.Sleep(200);
                IsCameraStarted = true;
            }
            catch (Exception ex)
            {
                LogUtil.Logger.Error($"StartCameraService - camera service didn't start well: {ex}");
            }
        }

        private static void Video_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {
            if (RequestPicture)
            {
                Picture = (Bitmap)eventArgs.Frame.Clone();
                if (!(Picture is null))
                {
                    PictureTaken = true;
                }
            }
        }

        public static string GetCameraOutput(string name = "", string path = "")
        {
            if (IsCameraStarted == false)
            {
                return "";
            }

            RequestPicture = true;
            name = CheckName(name);
            path = CheckPath(path);

            LogUtil.Logger.Information($"GetCameraOutput - Taking the picture from the camera service");
            try
            {
                var endTime = DateTime.Now.AddSeconds(_maxiumumDurationToTakePicture);
                while (!PictureTaken)
                {
                    if (DateTime.Now > endTime)
                    {
                        break;
                    }
                }

                SetPictureFilters(CamConfig);
                var absPath = path + name;
                absPath = VerifySavedImage(absPath);
                LogUtil.Logger.Information($"GetCameraOutput - Taking the picture path: {absPath}");
                Thread.Sleep(100);
                Reset();
                return absPath;
            }
            catch (Exception ex)
            {
                LogUtil.Logger.Error($"GetCameraOutput - could not get camera capture: {ex}");
            }
            Reset();
            return "";
        }

        public static void CloseCameraService()
        {
            LogUtil.Logger.Information($"CloseCameraService - Closing the camera service");
            if (IsCameraStarted is false)
            {
                return;
            }

            try
            {
                VideoSource.SignalToStop();
                VideoSource.NewFrame -= new NewFrameEventHandler(Video_NewFrame);
                IsCameraStarted = false;
                Reset();
                Thread.Sleep(1000);
            }
            catch (Exception ex)
            {
                LogUtil.Logger.Error($"CloseCameraService - could not close the camera: {ex}");
            }
        }

        #region Internal
        private static string VerifySavedImage(string path)
        {
            if(Picture is null)
            {
                LogUtil.Logger.Information("The image was null, not able to save the picture.");
            }
            if (!File.Exists(path))
            {
                Picture.Save(path + ".png", ImageFormat.Jpeg);
                return path + ".png";
            }
            else
            {
                var rand = new Random();
                var number = rand.Next(0, 100);
                path = $"{path}_{number}.png";
                Picture.Save(path + ".png", ImageFormat.Jpeg); // ...
                return path;
            }
        }

        private static void Reset()
        {
            RequestPicture = false;
            PictureTaken = false;
            Picture = null;
        }

        private static string CheckName(string name)
        {
            if (name.Equals(""))
            {
                name = Config.Default.DefaultImageName + Guid.NewGuid().ToString();
            }
            return name;
        }

        private static string CheckPath(string path)
        {
            if (path.Equals(""))
            {
                path = Config.Default.DefaultImagePath;
            }
            ResourceFolder.CreateFolderPath(path);
            return path;
        }

        private static CameraConfig CheckCameraConfig(CameraConfig config)
        {
            if (config is null)
            {
                config = ConfigReader.GetConfig("MVPConfig.json").CameraConfig;
            }
            return config;
        }
        #endregion

        #region Picture filters
        private static void SetPictureFilters(CameraConfig config)
        {
            SetBrightnessCorrectionFilter(config.Brightness);
        }

        private static void SetBrightnessCorrectionFilter(int? brightnessFactor)
        {
            if (brightnessFactor is null)
            {
                return;
            }
            var br = new BrightnessCorrection(brightnessFactor.Value);
            Thread.Sleep(50);
            br.ApplyInPlace(Picture);
        }
        #endregion
    }
}

I use the above as follows

LiveCamera.StartCameraService();
var capture = LiveCamera.GetCameraOutput();
LiveCamera.CloseCameraService();

I'm using C# dotnet framework 4 and aforge 2.2.5 and I looked if someone had this problem but couldn't find anything on this forum or the internet. Any help would be very nice! Thanks in advance.



Solution 1:[1]

When I checked the values of the focus and the exposure when taking pictures I noticed that the exposure wasn't set to the value it was supposed to. I solved this by implementing a check if the values were not set that it should set them again. This seems to do the trick.

Why the values are not set from the first time I have no idea. Especially because I gave the camera enough time and so on.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John