首先,我们定义一个基类,方便后面扩展其他相机
using System;
using System.Net.NetworkInformation;
namespace VMPro
{
///
/// 相机基类
///
[Serializable]
internal class SDK_Base
{
///
/// 相机信息字符串,相当于每个相机的名字
///
internal string CameraInfoStr = string.Empty;
///
/// 等待硬触发完成
///
internal bool waitingHardTriggImageArrived = false;
///
/// 枚举相机
///
/// 是否成功
internal virtual bool EnumCamera()
{
return false;
}
///
/// 抓取一张图像
///
/// 图像
internal virtual HObject GrabOneImage()
{
return null;
}
///
/// 检查相机是否存在,即系统是否识别到此相机
///
/// 是否存在
internal virtual bool CheckExist()
{
return false;
}
///
/// 设置曝光时间
///
/// 曝光时间
internal virtual void SetExposureTime(double exposureTime)
{
}
///
/// 设置增益
///
/// 增益
internal virtual void SetGain(double gain)
{
}
///
/// 设置采集模式
///
/// 0=连续采集,即异步采集 1=单次采集,即同步采集
internal virtual void SetAcquisitionMode(int mode)
{
}
///
/// 设置采集图像的ROI
///
internal virtual void SetAcqRegion(int offsetV, int offsetH, int imageH, int imageW)
{
}
///
/// 关闭所有相机
///
internal virtual void CloseAllCamera()
{
}
///
/// 通过网卡的物理地址获取网卡名
///
/// 网卡名
internal string GetAdapterNameByMacAdd(string MacAdd)
{
try
{
MacAdd = MacAdd.Replace("-", "");
var networkInterface = NetworkInterface.GetAllNetworkInterfaces();
foreach (var item in networkInterface)
{
var localMacAdd = item.GetPhysicalAddress().ToString();
if (localMacAdd == MacAdd)
return item.Name;
}
return string.Empty;
}
catch (Exception ex)
{
Log.SaveError(ex);
return string.Empty;
}
}
}
}
接下来,对海康工业相机接口做一次封装
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows;
using MvCamCtrl.NET;
namespace CameraManager
{
///
/// 海康机器人相机
///
[Serializable]
internal class HIKRobotCamera : SDK_Base
{
internal HIKRobotCamera(string cameraInfoStr)
{
this.CameraInfoStr = cameraInfoStr;
}
///
/// 资源锁
///
private object obj = new object();
///
/// 相机集合 键:相机信息字符串 值:相机对象
///
private static Dictionary D_cameras = new Dictionary();
///
/// 实例对象
///
private static SDK_HIKVision _instance;
public static SDK_HIKVision Instance
{
get
{
if (_instance == null)
_instance = new SDK_HIKVision(string.Empty);
return _instance;
}
}
///
/// 枚举相机
///
/// 是否成功
internal override bool EnumCamera()
{
try
{
try
{
uint temp = MyCamera.MV_CC_GetSDKVersion_NET(); //用于试探是否安装了海康威视相机SDK
}
catch
{
return false;
}
int nRet = MyCamera.MV_OK;
MyCamera myCamera = new MyCamera();
MyCamera.MV_CC_DEVICE_INFO_LIST stDevList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref stDevList);
if (MyCamera.MV_OK == nRet)
{
MyCamera.MV_CC_DEVICE_INFO stDevInfo;
for (Int32 i = 0; i < stDevList.nDeviceNum; i++)
{
stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
if (MyCamera.MV_GIGE_DEVICE == stDevInfo.nTLayerType)
{
MyCamera.MV_GIGE_DEVICE_INFO stGigEDeviceInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
string adapterName = GetAdapterNameByMacAdd(stGigEDeviceInfo.nCurrentSubNetMask.ToString()); //网卡名
string sn = stGigEDeviceInfo.chSerialNumber; //序列号
string friendlyName = stGigEDeviceInfo.chManufacturerName; //相机型号
string vendorName = stGigEDeviceInfo.chModelName; //厂商
if (vendorName != "HIKVision") //相应品牌的SDK只允许识别对应品牌的相机,否则采图时会出错
continue;
stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
nRet = myCamera.MV_CC_CreateDevice_NET(ref stDevInfo);
nRet = myCamera.MV_CC_OpenDevice_NET();
nRet = myCamera.MV_CC_StartGrabbing_NET();
MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();
nRet = myCamera.MV_CC_GetIntValue_NET("PayloadSize", ref stParam);
UInt32 nPayloadSize = stParam.nCurValue;
myCamera.MV_CC_SetHeartBeatTimeout_NET(1000); //设置心跳时间为1秒
string cameraInfoStr = string.Format("{0} | {1} | {2} | {3}", adapterName, vendorName, friendlyName, sn);
Machine.UpdateStep(20 + (10 / (int)stDevList.nDeviceNum) * (i + 1), string.Format("初始化海康威视相机{0} [{1}]", i + 1, cameraInfoStr), true);
SDK_HIKVision sdk_HIKVision = new SDK_HIKVision(cameraInfoStr);
D_cameras.Add(cameraInfoStr, myCamera);
AcqImageTool.L_SDKCamera.Add(sdk_HIKVision);
Frm_FromCamera.Instance.cbx_cameraList.Add(cameraInfoStr);
}
else if (MyCamera.MV_USB_DEVICE == stDevInfo.nTLayerType)
{
MyCamera.MV_USB3_DEVICE_INFO stUsb3DeviceInfo = (MyCamera.MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(stDevInfo.SpecialInfo.stUsb3VInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO));
}
}
}
else
{
Frm_MessageBox.Instance.MessageBoxShow("枚举海康威视相机失败", TipType.Error);
return false;
}
return true;
}
catch (Exception ex)
{
Log.SaveError(ex);
return false;
}
}
///
/// 抓取一张图像
///
/// 图像
internal override HObject GrabOneImage()
{
try
{
lock (obj)
{
HObject image = null;
foreach (KeyValuePair item in D_cameras)
{
if (item.Key == CameraInfoStr)
{
MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();
int nRet = item.Value.MV_CC_GetIntValue_NET("PayloadSize", ref stParam);
if (MyCamera.MV_OK != nRet)
{
Frm_MessageBox.Instance.MessageBoxShow("相机采图异常\r\n可能原因:未正常关闭\r\n解决方案:重启电脑或5分钟后重启程序", TipType.Error);
break;
}
UInt32 nPayloadSize = stParam.nCurValue;
IntPtr pBufForDriver = Marshal.AllocHGlobal((int)nPayloadSize);
IntPtr pBufForSaveImage = IntPtr.Zero;
MyCamera.MV_FRAME_OUT_INFO_EX FrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
nRet = item.Value.MV_CC_GetOneFrameTimeout_NET(pBufForDriver, nPayloadSize, ref FrameInfo, 1000);
if (MyCamera.MV_OK == nRet)
{
if (pBufForSaveImage == IntPtr.Zero)
{
pBufForSaveImage = Marshal.AllocHGlobal((int)(FrameInfo.nHeight * FrameInfo.nWidth * 3 + 2048));
}
MyCamera.MV_SAVE_IMAGE_PARAM_EX stSaveParam = new MyCamera.MV_SAVE_IMAGE_PARAM_EX();
stSaveParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp;
stSaveParam.enPixelType = FrameInfo.enPixelType;
stSaveParam.pData = pBufForDriver;
stSaveParam.nDataLen = FrameInfo.nFrameLen;
stSaveParam.nHeight = FrameInfo.nHeight;
stSaveParam.nWidth = FrameInfo.nWidth;
stSaveParam.pImageBuffer = pBufForSaveImage;
stSaveParam.nBufferSize = (uint)(FrameInfo.nHeight * FrameInfo.nWidth * 3 + 2048);
stSaveParam.nJpgQuality = 80;
nRet = item.Value.MV_CC_SaveImageEx_NET(ref stSaveParam);
if (MyCamera.MV_OK != nRet)
{
Frm_MessageBox.Instance.MessageBoxShow("\r\n 采图异常,相机:" + CameraInfoStr, TipType.Error);
}
byte[] data = new byte[stSaveParam.nImageLen];
Marshal.Copy(pBufForSaveImage, data, 0, (int)stSaveParam.nImageLen);
//转化成Halcon对象
GCHandle hand = GCHandle.Alloc(data, GCHandleType.Pinned);
IntPtr pr = hand.AddrOfPinnedObject();
HOperatorSet.GenImage1(out image, new HTuple("byte"), stSaveParam.nWidth, stSaveParam.nHeight, pBufForDriver);
if (hand.IsAllocated)
hand.Free();
Marshal.FreeHGlobal(pBufForDriver);
Marshal.FreeHGlobal(pBufForSaveImage);
break;
}
else
{
Frm_MessageBox.Instance.MessageBoxShow("\r\n 采图异常,相机:" + CameraInfoStr, TipType.Error);
}
}
}
return image;
}
}
catch (Exception ex)
{
Log.SaveError(ex);
return null;
}
}
///
/// 检查相机是否存在,即系统是否识别到此相机
///
/// 是否存在
internal override bool CheckExist()
{
foreach (KeyValuePair item in D_cameras)
{
if (item.Key == CameraInfoStr)
return true;
}
return false;
}
///
/// 设置曝光时间
///
/// 曝光时间
internal override void SetExposureTime(double exposureTime)
{
try
{
foreach (KeyValuePair item in D_cameras)
{
if (item.Key == CameraInfoStr)
{
item.Value.MV_CC_SetFloatValue_NET("ExposureTime", (float)exposureTime * 1000);
Thread.Sleep(200); //海康威视相机,实测发现设置完曝光后200毫秒以后才能生效,所以如此,当然这会影响CT,所以有待进一步优化
return;
}
}
}
catch (Exception ex)
{
Log.SaveError(ex);
}
}
///
/// 设置增益
///
/// 增益
internal override void SetGain(double gain)
{
try
{
foreach (KeyValuePair item in D_cameras)
{
if (item.Key == CameraInfoStr)
{
item.Value.MV_CC_SetFloatValue_NET("Gain", (float)gain);
return;
}
}
}
catch (Exception ex)
{
Log.SaveError(ex);
}
}
///
/// 设置采集模式
///
/// 0=连续采集,即异步采集 1=单次采集,即同步采集
internal override void SetAcquisitionMode(int mode)
{
try
{
foreach (KeyValuePair item in D_cameras)
{
if (item.Key == CameraInfoStr)
{
//待完善
return;
}
}
}
catch (Exception ex)
{
Log.SaveError(ex);
}
}
///
/// 关闭所有相机
///
internal override void CloseAllCamera()
{
try
{
foreach (KeyValuePair item in D_cameras)
{
item.Value.MV_CC_StopGrabbing_NET();
item.Value.MV_CC_CloseDevice_NET();
item.Value.MV_CC_DestroyDevice_NET();
}
}
catch (Exception ex)
{
Log.SaveError(ex);
}
}
}
}