2

我正在尝试调整网络摄像头的亮度。我需要用不同的亮度设置拍摄 3 张不同的照片。我不想让它手动,所以如果想在程序中包含设置。

下面是我正在使用的代码。使用 GetFrame() 方法从网络摄像头获取下一张图片。我知道有 DirectShow (iamvideoprocamp),我阅读了其他问题,但我仍然不知道如何集成它。有人可以给我一个提示或 c# 中的示例。谢谢。

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;
        }
4

2 回答 2

0

使用以下代码片段设置缩放、焦点和曝光。

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

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

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

要访问其他相机属性,如亮度,请参阅 IAMVideoProcAmp 实现。

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);
于 2014-10-10T21:56:08.377 回答
0

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.

于 2013-12-12T23:23:28.007 回答