Adjust webcam brightness (exposure/gain) C#

5.8k views Asked by At

I'm trying to adjust the brightness of my webcam. I need 3 diffrent pictures taken with a diffrent brightness setting. I don't want to make it manual so if want to include the settings in the programm.

Below ist the code I'm using. With the methode GetFrame() a get the next picture from the webcam. I know there is DirectShow (iamvideoprocamp), and I Read the other questions but I still don't know how to integrate it. Can someone give me a hint or an example in c#. Thanks.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;
using DirectShowLib;

namespace Kugel
{
    class Frames
    {
        // property variables
        private int m_Width = 640;
        private int m_Height = 480;
        private int mCapHwnd;

        // global variables to make the video capture go faster
        private IDataObject tempObj;
        private System.Drawing.Image tempImg;


        #region API Declarations

        [DllImport("user32", EntryPoint = "SendMessage")]
        public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

        [DllImport("avicap32.dll", EntryPoint = "capCreateCaptureWindowA")]
        public static extern int capCreateCaptureWindowA(string lpszWindowName, int dwStyle, int X, int Y, int nWidth, int nHeight, int hwndParent, int nID);

        [DllImport("user32", EntryPoint = "OpenClipboard")]
        public static extern int OpenClipboard(int hWnd);

        [DllImport("user32", EntryPoint = "EmptyClipboard")]
        public static extern int EmptyClipboard();

        [DllImport("user32", EntryPoint = "CloseClipboard")]
        public static extern int CloseClipboard();

        #endregion

        #region API Constants

        public const int WM_USER = 1024;

        public const int WM_CAP_CONNECT = 1034;
        public const int WM_CAP_DISCONNECT = 1035;
        public const int WM_CAP_GET_FRAME = 1084;
        public const int WM_CAP_COPY = 1054;

        public const int WM_CAP_START = WM_USER;

        public const int WM_CAP_DLG_VIDEOFORMAT = WM_CAP_START + 41;
        public const int WM_CAP_DLG_VIDEOSOURCE = WM_CAP_START + 42;
        public const int WM_CAP_DLG_VIDEODISPLAY = WM_CAP_START + 43;
        public const int WM_CAP_GET_VIDEOFORMAT = WM_CAP_START + 44;
        public const int WM_CAP_SET_VIDEOFORMAT = WM_CAP_START + 45;
        public const int WM_CAP_DLG_VIDEOCOMPRESSION = WM_CAP_START + 46;
        public const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;

        #endregion

        #region Start and Stop Capture Functions

        /// <summary>
        /// Starts the video capture
        /// </summary>      
        public void Start()
        {
            try
            {
                // for safety, call stop, just in case we are already running
                this.Stop();

                // setup a capture window
                mCapHwnd = capCreateCaptureWindowA("WebCap", 0, 0, 0, m_Width, m_Height, 0, 0);

                // connect to the capture device
                Application.DoEvents();
                SendMessage(mCapHwnd, WM_CAP_CONNECT, 0, 0);
                SendMessage(mCapHwnd, WM_CAP_SET_PREVIEW, 0, 0);
            }

            catch (Exception ex)
            {
              //  MessageBox.Show("An error ocurred while starting the video capture. Check that your webcamera is connected properly and turned on.\r\n\n" + excep.Message);
                this.Stop();
            }
        }

        /// <summary>
        /// Stops the video capture
        /// </summary>
        public void Stop()
        {
            try
            {
                // disconnect from the video source
                Application.DoEvents();
                SendMessage(mCapHwnd, WM_CAP_DISCONNECT, 0, 0);
            }

            catch (Exception ex)
            { // don't raise an error here.
            }

        }

        #endregion

        public void Prefer()
        {
           try
            {
                SendMessage(mCapHwnd, WM_CAP_DLG_VIDEOSOURCE, 0, 0);
            }
           catch (Exception ex)
           {
             //  MessageBox.Show("An error ocurred while capturing the video image. The video capture will now be terminated.\r\n\n" + excep.Message);
           }
        }

        public Image GetFrame()
        {
           try
            {
                // get the next frame;
                SendMessage(mCapHwnd, WM_CAP_GET_FRAME, 0, 0);

                // copy the frame to the clipboard
                SendMessage(mCapHwnd, WM_CAP_COPY, 0, 0);

                // get from the clipboard
                tempObj = Clipboard.GetDataObject();
                tempImg = (System.Drawing.Bitmap)tempObj.GetData(System.Windows.Forms.DataFormats.Bitmap);                   
                return tempImg;
           }
           catch (Exception ex)
           {
             //  MessageBox.Show("An error ocurred while capturing the video image. The video capture will now be terminated.\r\n\n" + excep.Message);
               this.Stop();
           }
           return null;
        }
2

There are 2 answers

0
Roman Ryltsov On

You hardly can integrate DirectShow's IAMVideoProcAmp and the the code snippet you provided because your GetFrame is using completely different API: Video for Windows.

These are two different APIs which possibly share the same video capture device. So, well, there is a chance that you find the same device in DirectShow, then you start building the capture graph, you obtain the interface, the filter will want to accept your brightness changes without starting video capture, then it will want to make them persistent and thus available for the same device via VfW API. With all these assumptions and complexity you might be fine doing adjustments via DirectShow, while capture via VfW. However, it looks way more reasonable to just move to DirectShow completely.

0
Hassan Rahman On

Set the Zoom, Focus and Exposure using the following code snippets.

videoDevice.SetCameraProperty(
            CameraControlProperty.Zoom,
            zoomValue,
            CameraControlFlags.Manual);

        videoDevice.SetCameraProperty(
            CameraControlProperty.Focus,
            focusValue,
            CameraControlFlags.Manual);

        videoDevice.SetCameraProperty(
            CameraControlProperty.Exposure,
            exposureValue,
            CameraControlFlags.Manual);

To access other camera properties like brightness, contrast see IAMVideoProcAmp implementation.

videoDevice.SetVideoProperty(
VideoProcAmpProperty.Brightness,
brightnessValue,
VideoProcAmpFlags.Manual);

videoDevice.SetVideoProperty(
VideoProcAmpProperty.Contrast,
contrastValue,
VideoProcAmpFlags.Manual);

videoDevice.SetVideoProperty(
VideoProcAmpProperty.Saturation,
saturationValue,
VideoProcAmpFlags.Manual);

videoDevice.SetVideoProperty(
VideoProcAmpProperty.Sharpness,
sharpnessValue,
VideoProcAmpFlags.Manual);

videoDevice.SetVideoProperty(
VideoProcAmpProperty.WhiteBalance,
whiteBalanceValue,
VideoProcAmpFlags.Manual);

videoDevice.SetVideoProperty(
VideoProcAmpProperty.BacklightCompensation,
backlightCompensationValue,
VideoProcAmpFlags.Manual);