2013-12-10 270 views
2

我正在嘗試調整攝像頭的亮度。我需要以不同的亮度設置拍攝3張不同的照片。我不想讓它手動,所以如果想要包括在程序中的設置。調整攝像頭亮度(曝光/增益)C#

下面是我正在使用的代碼。用方法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; 
     } 

回答

0

你幾乎可以集成的DirectShow的IAMVideoProcAmp和代碼片段您提供的,因爲你的GetFrame使用完全不同的API:Video for Windows

這些是可能共享相同的視頻捕獲裝置的兩個不同的API。所以,有可能你會在DirectShow中找到相同的設備,然後你開始構建捕獲圖,獲取界面,過濾器會希望在不啓動視頻捕獲的情況下接受亮度變化,然後它將會使它們是持久的,因此可通過VfW API在同一設備上使用。有了所有這些假設和複雜性,您可以通過DirectShow進行調整,同時通過VfW進行捕獲。不過,看起來完全轉向DirectShow更合理。

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); 
相關問題