1.海康的MVS最新版本5.0比之前的版本要简单好用些,我针对新版本写了一个简单的帮助文件
using Avalonia.Interactivity;
using Avalonia.Media.Imaging;
using aaa.Factories;
using aaa.ViewModels;
using MvCameraControl;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
namespace aaa.Helper
{
public class HikCameraHelper
{
// ch:枚举的相机类型 | en:TLayerType for enumerate devices
static readonly DeviceTLayerType enumTLayerType = DeviceTLayerType.MvGigEDevice | DeviceTLayerType.MvUsbDevice
| DeviceTLayerType.MvGenTLGigEDevice | DeviceTLayerType.MvGenTLCXPDevice | DeviceTLayerType.MvGenTLCameraLinkDevice | DeviceTLayerType.MvGenTLXoFDevice;
static List<IDeviceInfo> deviceInfoList = new List<IDeviceInfo>();
static IDevice device = null;
public static bool isGrabbing = true; // ch:是否正在取图 | en: Grabbing flag
Thread receiveThread = null; // ch:接收图像线程 | en: Receive image thread
IntPtr pictureBoxHandle = IntPtr.Zero; // ch:显示图像的控件句柄 | en: Control handle for image display
public static List<string> CameraList = new List<string>();
public string SelectedCamera { get; set; }
public static void InitHikCamera()
{
SDKSystem.Initialize();
}
public static List<string> GetDeviceList()
{
// if (DataContext is MainViewModel vm)
{
//List<string> CameraList = new List<string>();
CameraList.Clear();
// ch:创建设备列表 | en:Create Device List
// cbDeviceList.Items.Clear();
int nRet = DeviceEnumerator.EnumDevices(enumTLayerType, out deviceInfoList);
if (nRet != MvError.MV_OK)
{
// ShowErrorMsg("Enumerate devices fail!", nRet);
return CameraList;
}
// ch:在窗体列表中显示设备名 | en:Display device name in the form list
for (int i = 0; i < deviceInfoList.Count; i++)
{
IDeviceInfo deviceInfo = deviceInfoList[i];
// IGigEDevice gigEDevice = (IGigEDevice)deviceInfo;
IGigEDeviceInfo gigEDevice = (IGigEDeviceInfo)deviceInfo;
//gigEDevice.CurrentIp
// IGigEDeviceInfo gigeDevInfo = devInfo as IGigEDeviceInfo;
uint nIp1 = ((gigEDevice.CurrentIp & 0xff000000) >> 24);
uint nIp2 = ((gigEDevice.CurrentIp & 0x00ff0000) >> 16);
uint nIp3 = ((gigEDevice.CurrentIp & 0x0000ff00) >> 8);
uint nIp4 = (gigEDevice.CurrentIp & 0x000000ff);
Console.WriteLine("DevIP: {0}.{1}.{2}.{3}", nIp1, nIp2, nIp3, nIp4);
// gigEDevice.n
if (deviceInfo.UserDefinedName != "")
{
//deviceInfo.
CameraList.Add(deviceInfo.TLayerType.ToString() + ": " + deviceInfo.UserDefinedName + " (" + deviceInfo.SerialNumber + ")");
}
else
{
CameraList.Add(deviceInfo.TLayerType.ToString() + ": " + deviceInfo.ManufacturerName + $" IP: [{nIp1}.{nIp2}.{nIp3}.{nIp4}] " + deviceInfo.ModelName + " (" + deviceInfo.SerialNumber + ")");
}
}
return CameraList;
}
}
public static void OpenCamera(string CameraIP)
{
int ret = 0;
// if ( )
{
int index = CameraList.FindIndex(s => s.Contains(CameraIP));
// vm.CameraList.ind(vm.CameraIP);
IDeviceInfo deviceInfo = deviceInfoList[index];
/*创建相机实例*/
device = DeviceFactory.CreateDevice(deviceInfo);
/*打开相机*/
ret = device.Open();
// vm.ProgramLog = $"相机打开 ret = {ret}";
//MessageBox.Show(errorMsg, "PROMPT");
/*如果是网口相机*/
if (device is IGigEDevice)
{
IGigEDevice gigEDevice = device as IGigEDevice;
/*配置网口相机的最佳包大小*/
int packetSize;
gigEDevice.GetOptimalPacketSize(out packetSize);
gigEDevice.Parameters.SetIntValue("GevSCPSPacketSize", packetSize);
}
else if (device is IUSBDevice)
{
/*设置USB同步读写超时时间*/
IUSBDevice usbDevice = device as IUSBDevice;
usbDevice.SetSyncTimeOut(1000);
}
// ch:设置采集连续模式 | en:Set Continues Acquisition Mode
device.Parameters.SetEnumValueByString("AcquisitionMode", "Continuous");
device.Parameters.SetEnumValueByString("TriggerMode", "Off");
//receiveThread = new Thread(ReceiveThreadProcess);
//receiveThread.Start();
// ch:开启抓图线程 | en: Start the grabbing thread
//Thread GrabThread = new Thread(FrameGrabThread);
//GrabThread.Start(device.StreamGrabber);
//GrabThread.Abort();
// ch:开启抓图 | en: start grab image
ret = device.StreamGrabber.StartGrabbing();
if (ret != MvError.MV_OK)
{
isGrabbing = false;
// receiveThread.Join();
Console.WriteLine("Start grabbing failed:{0:x8}", ret);
return;
}
// vm.ProgramLog = $"开始采集 ret = {ret}";
}
}
public static void CloseCamera(string CameraIP)
{
int ret = 0;
//if (DataContext is MainViewModel vm)
{
isGrabbing = false;
ret = device.StreamGrabber.StopGrabbing();
/*关闭相机*/
ret = device.Close();
if (ret != MvError.MV_OK)
{
Console.WriteLine("Close device fail: {0}", ret);
}
else
{
Console.WriteLine("Close device success!");
}
// ch:销毁设备 | en:Destroy device
device.Dispose();
device = null;
/*销毁相机实例*/
// device.Dispose();
// device = null;
//vm.ProgramLog = $"相机关闭 ret = {ret}";
}
}
public static CameraBitmap GetCameraFrame()
{
CameraBitmap cameraBitmap = new CameraBitmap();
// Bitmap bitmap = null;
IFrameOut frameOut;
int nRet = device.StreamGrabber.GetImageBuffer(1000, out frameOut);
if (MvError.MV_OK == nRet)
{
IImage inputImage = frameOut.Image;
OpenCvSharp.Mat mat = ByteToMatColor(inputImage.PixelData, ((int)inputImage.Width), ((int)inputImage.Height));
cameraBitmap.bitmap = ToAvaloniaBitmap(mat);
}
else
{
//vm.ProgramLog = $"获取当前帧失败 {nRet} {DateTime.Now}";
}
device.StreamGrabber.FreeImageBuffer(frameOut);
cameraBitmap.nRet = nRet;
return cameraBitmap;
}
public static OpenCvSharp.Mat ByteToMatColor(byte[] data, int width, int height)
{
OpenCvSharp.Mat src = new OpenCvSharp.Mat(height, width, OpenCvSharp.MatType.CV_8UC3);
int length = height * width * 3; // or src.Height * src.Step;
Marshal.Copy(data, 0, src.Data, length);
return src;
}
public static Bitmap ToAvaloniaBitmap(OpenCvSharp.Mat mat)
{
if (mat == null || mat.Empty())
throw new ArgumentNullException(nameof(mat));
OpenCvSharp.Mat matRgb = new OpenCvSharp.Mat();
// OpenCV 默认为 BGR 格式,必须转成 RGB
if (mat.Channels() == 3)
{
OpenCvSharp.Cv2.CvtColor(mat, matRgb, OpenCvSharp.ColorConversionCodes.BGR2RGB);
}
// 灰度图
else if (mat.Channels() == 1)
{
OpenCvSharp.Cv2.CvtColor(mat, matRgb, OpenCvSharp.ColorConversionCodes.GRAY2BGR);
OpenCvSharp.Cv2.CvtColor(matRgb, matRgb, OpenCvSharp.ColorConversionCodes.BGR2RGB);
}
else
{
matRgb = mat.Clone();
}
try
{
// 内存流编码为 JPG/PNG
using var ms = new System.IO.MemoryStream();
matRgb.WriteToStream(ms);
// 关键:Avalonia 从流创建 Bitmap
ms.Position = 0;
return new Bitmap(ms);
}
finally
{
matRgb.Dispose(); // 必须释放,防止内存泄漏
}
}
}
public class CameraBitmap
{
public int nRet = 0;
public Bitmap bitmap=null;
}
}


1624

被折叠的 条评论
为什么被折叠?



