C#--DirectShowLib 关闭自动白平衡和自动曝光时间
一、前言
因项目需要需关闭相机自身的自动白平衡和自动曝光时间,统统设定为恒定值,开始实验了opencvCvSharp,但是不起作用,故实验了更底层的 DirectShowLib ,可成功关闭相机自带的自动白平衡和自动曝光时间,再使用 opencvCvSharp 读取摄像头
二、 代码
(1)安装 DirectShowLib 包, 直接在nuget
简单整2按钮2文本框,用于输入需要定义的白平衡温度值和曝光时间值,曝光值-3表示是10的-3次方的意思,值越大则曝光时间越长,图像越亮;白平衡温度值是有范围,可以通过接口 int hr = videoProcAmp.GetRange(prop, out minValue, out maxValue, out steppingDelta, out defaultValue, out flags); 查询获得,温度值越大则偏暖色
(2)重点代码
using DirectShowLib;
using System.Runtime.InteropServices;
using OpenCvSharp;public class CameraManager{private IBaseFilter cameraFilter;private DsDevice cameraDevice; // DirectShow 设备public void InitializeCamera(){try{// 枚举视频输入设备var devices = DsDevice.GetDevicesOfCat(DirectShowLib.FilterCategory.VideoInputDevice);if (devices.Length == 0){Console.WriteLine("No video input devices found.");return;}// 选择第一个设备(通常是默认相机)cameraDevice = devices[0];// 使用 Moniker 来创建相机的 BaseFilter 对象object cameraObject = null;Guid iid = typeof(IBaseFilter).GUID;cameraDevice.Mon.BindToObject(null, null, ref iid, out cameraObject);cameraFilter = cameraObject as IBaseFilter;if (cameraFilter == null){Console.WriteLine("Failed to create camera filter.");return;}Console.WriteLine("Camera initialized successfully.");}catch (Exception ex){Console.WriteLine($"Error initializing camera: {ex.Message}");}}// Getter 方法获取相机的 BaseFilter 对象public IBaseFilter GetCameraFilter(){return cameraFilter;}// 释放相机资源public void CloseCamera(){if (cameraFilter != null){Marshal.ReleaseComObject(cameraFilter);cameraFilter = null;}cameraDevice = null;Console.WriteLine("Camera resources released.");}}private void button3_Click(object sender, EventArgs e) {int expos_v = int.Parse(textBox2.Text);int wb_v = int.Parse(textBox3.Text);int hr;CameraManager cameraManager = new CameraManager();cameraManager.InitializeCamera();IBaseFilter cameraFilter = cameraManager.GetCameraFilter();if (cameraFilter != null){// 在这里可以继续操作相机,比如设置属性、连接到视频源等// 例如关闭相机的自动白平衡:// IAMCameraControl cameraControl = cameraFilter as IAMCameraControl;if (cameraControl != null){hr = cameraControl.Set(DirectShowLib.CameraControlProperty.Exposure, expos_v, DirectShowLib.CameraControlFlags.Manual/* 设置关闭白平衡的值 */);DsError.ThrowExceptionForHR(hr);}IAMVideoProcAmp videoProcAmp = cameraFilter as IAMVideoProcAmp;if (videoProcAmp != null){// 获取 WhiteBalance 属性 VideoProcAmpProperty prop = VideoProcAmpProperty.WhiteBalance;// 获取当前值int minValue, maxValue, steppingDelta, defaultValue;VideoProcAmpFlags flags;// 这一句获取白平衡参数,范围2800-6500 ,默认是4600//int hr = videoProcAmp.GetRange(prop, out minValue, out maxValue, out steppingDelta, out defaultValue, out flags); hr = videoProcAmp.Set(prop, wb_v, VideoProcAmpFlags.Manual);if (hr >= 0){textBox1.Text = "白平衡设置成功";}else{textBox1.Text = "白平衡设置失败";}}else{}}}private void button4_Click(object sender, EventArgs e){// 打开摄像头using (VideoCapture capture = new VideoCapture(0 , VideoCaptureAPIs.DSHOW )){// 设置分辨率和帧率// 检查摄像头是否成功打开if (!capture.IsOpened()){Console.WriteLine("无法打开摄像头.");return;}capture.Set(VideoCaptureProperties.FrameWidth,3840 ); // 设置宽度capture.Set(VideoCaptureProperties.FrameHeight, 2880); // 设置高度capture.Set(VideoCaptureProperties.FourCC, VideoWriter.FourCC('M', 'J', 'P', 'G'));//capture.Set(VideoCaptureProperties.Fps, 20); // 设置帧率// 获取摄像头的宽度和高度int width = (int)capture.Get(VideoCaptureProperties.FrameWidth);int height = (int)capture.Get(VideoCaptureProperties.FrameHeight);// 创建窗口以显示图像string windowName = $"sp{width}*{height}";Cv2.NamedWindow(windowName);Cv2.NamedWindow("cap");// 循环获取并显示图像int count = 0;while (true){count++;Stopwatch stopwatch = new Stopwatch();stopwatch.Start();// 从摄像头捕获一帧图像Mat frame = new Mat();capture.Read(frame);stopwatch.Stop();//textBox1.Text = $"Milliseconds elapsed: {count}";// 检查是否成功捕获图像if (frame.Empty()){Console.WriteLine("无法从摄像头捕获图像.");break;}// 在窗口中显示图像Cv2.ImShow(windowName , frame);// 等待并检测按键,按下 ESC 键退出循环int key = Cv2.WaitKey(1);if (key == 27) // ASCII码 27 表示 ESC 键break;else if (key == 32) // ASCII码 27 表示 ESC 键{Cv2.ImShow("cap", frame);Cv2.ImWrite("cap.png", frame);}}// 释放资源capture.Release();Cv2.DestroyAllWindows();}}
三、效果
白平衡温度值3000
白平衡温度值6200