机器视觉C# 调用相机:从 USB 摄像头到海康工业相机(WinForms WPF)
机器视觉C# 调用相机从 USB 摄像头到海康工业相机WinForms WPF 前言在工业自动化、医疗影像或简单软件开发中调用摄像头是一个绕不开的话题。在项目中同时遇到了两种需求通用 USB 相机如笔记本自带摄像头、普通免驱 USB 摄像头。专业工业相机如海康威视Hikvision的机器视觉相机需要调用厂商 SDK。本文将带你分别使用WinForms和WPF框架通过C#语言实现这两种相机的调用。文章不仅会提供可直接运行的代码还会附带详细的思路解析和常见踩坑点希望能为你的项目提供一份可靠的参考。 环境准备开发工具Visual Studio 2022 / 2019目标框架.NET 6.0 / .NET Framework 4.7.2 及以上NuGet 包通用 USBOpenCvSharp4.Windows或AForge.NET本文使用OpenCvSharp海康相机需前往 海康机器人官网 下载MVS机器视觉软件并引用其 SDK。第一部分通用 USB 相机调用基于 OpenCvSharp对于普通的 USB 摄像头Windows 系统通过 DirectShow 驱动识别。我们可以使用OpenCvSharp库来轻松操作。1. 核心思路OpenCV 的VideoCapture类封装了 DirectShow只需传入摄像头 ID通常为 0, 1, 2…即可打开设备。2. WinForms 实现实时显示步骤一安装 NuGetInstall-Package OpenCvSharp4.Windows步骤二界面设计拖拽一个PictureBox用于显示画面一个Button用于启动。步骤三后台代码usingOpenCvSharp;usingOpenCvSharp.Extensions;usingSystem;usingSystem.Threading;usingSystem.Windows.Forms;namespaceUSBCamera_WinForms{publicpartialclassForm1:Form{privateVideoCapture_capture;privateThread_captureThread;privatebool_isRunningfalse;publicForm1(){InitializeComponent();}privatevoidbtnStart_Click(objectsender,EventArgse){if(_isRunning)return;// 0 代表第一个 USB 摄像头如果笔记本自带摄像头通常是 0外接可能是 1_capturenewVideoCapture(0);if(!_capture.IsOpened()){MessageBox.Show(无法打开摄像头请检查设备连接。);return;}_isRunningtrue;_captureThreadnewThread(CaptureFrame);_captureThread.IsBackgroundtrue;_captureThread.Start();}privatevoidCaptureFrame(){while(_isRunning){using(MatframenewMat()){_capture.Read(frame);if(frame.Empty())continue;// 将 OpenCV 的 Mat 转换为 WinForms 的 Bitmapusing(BitmapbitmapBitmapConverter.ToBitmap(frame)){// 跨线程更新 UIpictureBox1.Invoke(newAction((){pictureBox1.Image?.Dispose();// 释放旧图像防止内存泄漏pictureBox1.ImagenewBitmap(bitmap);}));}}Thread.Sleep(30);// 控制帧率约 30fps}}privatevoidForm1_FormClosing(objectsender,FormClosingEventArgse){_isRunningfalse;_captureThread?.Join(1000);_capture?.Release();_capture?.Dispose();}}}3. WPF 实现WPF 与 WinForms 不同不能直接接收Bitmap。我们需要借助WriteableBitmap来实现高性能渲染。步骤一界面 XAMLWindowx:ClassUSBCamera_WPF.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlTitleUSB相机 WPF版Height450Width800GridImagex:NamevideoImageStretchUniformBackgroundBlack/Buttonx:NamebtnStartContent打开相机Width100Height30HorizontalAlignmentRightVerticalAlignmentBottomMargin10ClickBtnStart_Click//Grid/Window步骤二后台逻辑usingOpenCvSharp;usingOpenCvSharp.WpfExtensions;usingSystem.Threading;usingSystem.Windows;usingSystem.Windows.Media.Imaging;namespaceUSBCamera_WPF{publicpartialclassMainWindow:Window{privateVideoCapture_capture;privateThread_captureThread;privatevolatilebool_isRunningfalse;publicMainWindow(){InitializeComponent();}privatevoidBtnStart_Click(objectsender,RoutedEventArgse){if(_isRunning)return;_capturenewVideoCapture(0);if(!_capture.IsOpened()){MessageBox.Show(无法打开摄像头);return;}_isRunningtrue;_captureThreadnewThread(CaptureCamera);_captureThread.IsBackgroundtrue;_captureThread.Start();}privatevoidCaptureCamera(){while(_isRunning){using(MatframenewMat()){_capture.Read(frame);if(frame.Empty())continue;// 关键点Mat 转 WriteableBitmap (WPF 专用)varbitmapframe.ToWriteableBitmap();// 调度到 UI 线程更新Application.Current.Dispatcher.Invoke((){videoImage.Sourcebitmap;});}Thread.Sleep(30);}}protectedoverridevoidOnClosing(System.ComponentModel.CancelEventArgse){_isRunningfalse;_captureThread?.Join(1000);_capture?.Release();base.OnClosing(e);}}}第二部分海康工业相机调用基于 MVS SDK海康的工业相机如网口或 USB3.0 接口功能强大但必须依赖官方 SDK。下面是调用海康相机的基本流程。1. 环境配置下载并安装 MVS机器视觉软件。安装完成后在项目中添加对MvCameraControl.Net.dll的引用。路径通常在C:\Program Files (x86)\MVS\Development\Bin\如果是网口相机请确保 PC 和相机 IP 在同一网段。2. 核心调用步骤WinForms WPF 通用这里以 WinForms 为例展示如何枚举设备、打开相机、注册回调获取图像。代码示例usingMvCameraControl;usingSystem;usingSystem.Drawing;usingSystem.Windows.Forms;namespaceHikCamera_Demo{publicpartialclassFormHik:Form{privateMyCamera_cameranull;privatebool_isGrabbingfalse;publicFormHik(){InitializeComponent();}privatevoidbtnEnum_Click(objectsender,EventArgse){// 1. 枚举设备MyCamera.MV_CC_DEVICE_INFO_LISTdeviceListnewMyCamera.MV_CC_DEVICE_INFO_LIST();intnRetMyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE|MyCamera.MV_USB_DEVICE,refdeviceList);if(nRet!MyCamera.MV_OK||deviceList.nDeviceNum0){MessageBox.Show(未发现相机);return;}// 假设取第一个设备MyCamera.MV_CC_DEVICE_INFOdeviceInfo(MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(deviceList.pDeviceInfo[0],typeof(MyCamera.MV_CC_DEVICE_INFO));// 2. 创建设备实例_cameranewMyCamera();nRet_camera.MV_CC_CreateDevice_NET(refdeviceInfo);if(nRet!MyCamera.MV_OK){MessageBox.Show(创建设备失败);return;}// 3. 连接设备nRet_camera.MV_CC_OpenDevice_NET();if(nRet!MyCamera.MV_OK){MessageBox.Show(连接失败);return;}// 4. 设置触发模式为连续自动出图_camera.MV_CC_SetEnumValue_NET(TriggerMode,0);// 0: 关, 1: 开// 5. 注册图像回调_camera.MV_CC_RegisterImageCallBack_NET(ImageCallback,IntPtr.Zero);// 6. 开始采集_camera.MV_CC_StartGrabbing_NET();_isGrabbingtrue;btnEnum.Enabledfalse;MessageBox.Show(相机启动成功);}// 图像回调函数在 SDK 子线程中执行privatevoidImageCallback(IntPtrpData,refMyCamera.MV_FRAME_OUT_INFO_EXpFrameInfo,IntPtrpUser){if(!_isGrabbing)return;try{// 将原始数据转换为 Bitmap// 根据像素格式进行转换这里是简单示例假设是 BGR8byte[]buffernewbyte[pFrameInfo.nFrameLen];Marshal.Copy(pData,buffer,0,(int)pFrameInfo.nFrameLen);// 根据宽高创建 BitmapBitmapbitmapnewBitmap((int)pFrameInfo.nWidth,(int)pFrameInfo.nHeight,System.Drawing.Imaging.PixelFormat.Format24bppRgb);System.Drawing.Imaging.BitmapDatabmpDatabitmap.LockBits(newRectangle(0,0,bitmap.Width,bitmap.Height),System.Drawing.Imaging.ImageLockMode.WriteOnly,bitmap.PixelFormat);Marshal.Copy(buffer,0,bmpData.Scan0,(int)pFrameInfo.nFrameLen);bitmap.UnlockBits(bmpData);// 更新 UI注意跨线程pictureBox1.Invoke(newAction((){pictureBox1.Image?.Dispose();pictureBox1.Imagebitmap;}));}catch(Exceptionex){Console.WriteLine(回调异常ex.Message);}}privatevoidFormHik_FormClosing(objectsender,FormClosingEventArgse){if(_camera!null){_isGrabbingfalse;_camera.MV_CC_StopGrabbing_NET();_camera.MV_CC_CloseDevice_NET();_camera.MV_CC_DestroyDevice_NET();}}}}⚠️ 注意海康 SDK 的像素格式PixelFormat很多如 Mono8、BayerRG8、RGB24必须根据相机实际设置进行转换。回调函数是非 UI 线程更新图像时必须使用Invoke或Dispatcher。记得在项目属性中勾选“允许不安全代码”如果使用指针操作。 参考文档与资源OpenCV 官方文档https://docs.opencv.org/OpenCvSharp GitHubhttps://github.com/shimat/opencvsharp海康机器人 MVS 开发指南安装 MVS 后在Development\Doc目录下有详细的《SDK 开发指南.pdf》。DirectShow 替代方案如果不想用 OpenCV也可以使用AForge.NET或MediaCaptureUWP但 OpenCV 的跨平台性和功能完整性更强。 总结与避坑指南1. 框架选择建议WinForms开发速度快适合简单的工业软件原型但界面美观度稍逊。WPF界面设计灵活支持 MVVM 模式适合复杂交互的桌面应用。2. 常见问题相机打开失败检查相机是否被其他软件占用如系统相机应用、其他调试程序。内存泄漏在实时显示时务必释放旧的Bitmap或WriteableBitmap对象否则内存会持续飙升。海康相机找不到网口相机关闭防火墙固定 IP。USB 相机安装 MVS 自带的驱动通过 MVS 工具卸载系统的UVC驱动安装厂商驱动。3. 性能优化使用Queue缓冲机制处理回调避免 UI 渲染阻塞相机回调线程。对于高分辨率相机建议将图像缩放后再显示减轻 UI 压力。 结语本文覆盖了从简单的 USB 摄像头到专业的海康工业相机在 C# 中的调用方法并分别给出了 WinForms 和 WPF 的示例。希望这篇博客能帮助你快速上手相机的开发。如果你在实现过程中遇到任何问题欢迎在评论区留言交流Happy Coding!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2452745.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!