1304 lines
54 KiB
C#
1304 lines
54 KiB
C#
using OpenCvSharp;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Drawing.Imaging;
|
||
using System.Drawing;
|
||
using System.Linq;
|
||
using System.Runtime.CompilerServices;
|
||
using System.Runtime.InteropServices;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using MvCamCtrl.NET;
|
||
using OpenCvSharp.Dnn;
|
||
using System.Diagnostics;
|
||
using HalconDotNet;
|
||
using System.Xml.Linq;
|
||
|
||
namespace GuideGraspSys
|
||
{
|
||
public class HikCamDriver: CameraBase
|
||
{
|
||
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
|
||
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
|
||
/// <summary>
|
||
/// 创建相机集合,存放相机
|
||
/// </summary>
|
||
MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList;
|
||
MyCamera.MV_CC_DEVICE_INFO device;
|
||
|
||
MyCamera hkCamera = new MyCamera();
|
||
/// <summary>
|
||
/// 抓图回调
|
||
/// </summary>
|
||
MyCamera.cbOutputExdelegate ImageCallback;
|
||
|
||
Thread m_hReceiveThread = null;
|
||
|
||
/// <summary>
|
||
/// 异常回调
|
||
/// </summary>
|
||
MyCamera.cbExceptiondelegate pCallBackFunc;
|
||
HObject hPylonImage = new HObject();
|
||
List<string> CameraName = new List<string>();
|
||
|
||
MyCamera.MV_FRAME_OUT _frame = new MyCamera.MV_FRAME_OUT();
|
||
readonly ManualResetEvent _snapHandle = new ManualResetEvent(false);
|
||
bool _snapFlag = false;
|
||
|
||
// ch:Bitmap及其像素格式 | en:Bitmap and Pixel Format
|
||
Bitmap m_bitmap = null;
|
||
PixelFormat m_bitmapPixelFormat = PixelFormat.DontCare;
|
||
IntPtr m_ConvertDstBuf = IntPtr.Zero;
|
||
UInt32 m_nConvertDstBufLen = 0;
|
||
|
||
int nRet = MyCamera.MV_OK;
|
||
/// <summary>
|
||
/// 曝光时间
|
||
/// </summary>
|
||
public int ExposureTime { get; set; }
|
||
/// <summary>
|
||
/// 增益
|
||
/// </summary>
|
||
public int Gain { get; set; }
|
||
/// <summary>
|
||
/// 帧率
|
||
/// </summary>
|
||
public int FrameRate { get; set; }
|
||
|
||
|
||
public bool m_bGrabbing = false;
|
||
|
||
private static Object BufForDriverLock = new Object();
|
||
|
||
IntPtr m_BufForDriver = IntPtr.Zero;
|
||
|
||
UInt32 m_nBufSizeForDriver = 0;
|
||
MyCamera.MV_FRAME_OUT_INFO_EX m_stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
|
||
|
||
public delegate void MatImgTransferDelegate(Mat img);
|
||
public event MatImgTransferDelegate OnImgTransfer;
|
||
|
||
public delegate void BitmapTransferDelegate(Bitmap img);
|
||
public event BitmapTransferDelegate OnBitmapTransfer;
|
||
|
||
public Action<DateTime, Mat> OnHImageOutput { get; set; }
|
||
|
||
public static Dictionary<string,CameraInfor> allCamera=new Dictionary<string,CameraInfor>();
|
||
private CameraInfor currentCam;
|
||
|
||
public override bool CloserCamera()
|
||
{
|
||
m_bGrabbing = false;
|
||
hkCamera.MV_CC_StopGrabbing_NET();//停止采集
|
||
hkCamera.MV_CC_CloseDevice_NET();//关闭设备
|
||
hkCamera.MV_CC_DestroyDevice_NET();
|
||
return true;
|
||
}
|
||
/// <summary>
|
||
/// 开启硬触发
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public override bool EncoderGrap()
|
||
{
|
||
try
|
||
{
|
||
if (m_bGrabbing)
|
||
{
|
||
Console.WriteLine("Camera is now Continue Grabing Images!");
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
// ch:标志位置位true | en:Set position bit true
|
||
m_bGrabbing = true;
|
||
|
||
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
|
||
//设置使用硬触发模式
|
||
int nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
|
||
|
||
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
m_bGrabbing = false;
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
//public override List<string> FindCamera()
|
||
//{
|
||
// int nRet;
|
||
|
||
// System.GC.Collect();
|
||
// CameraName.Clear();
|
||
|
||
// nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
|
||
// if (0 != nRet)
|
||
// {
|
||
// Console.WriteLine("Not Find Camera!{0:x8}", nRet);
|
||
// return null;
|
||
// }
|
||
// for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
|
||
// {
|
||
// MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
|
||
// //网口相机
|
||
// if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
|
||
// {
|
||
// IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
|
||
// MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
|
||
// if (gigeInfo.chUserDefinedName != "")
|
||
// {
|
||
// Console.WriteLine("GigE:" + gigeInfo.chUserDefinedName + " (" + gigeInfo.chSerialNumber + ")");
|
||
// CameraName.Add("GigE:" + gigeInfo.chUserDefinedName + " (" + gigeInfo.chSerialNumber + ")");
|
||
// }
|
||
// else
|
||
// {
|
||
// Console.WriteLine("GigE: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")");
|
||
// CameraName.Add("GigE: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")");
|
||
// }
|
||
// }
|
||
// else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
|
||
// {
|
||
// IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stUsb3VInfo, 0);
|
||
// MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO));
|
||
// if (usbInfo.chUserDefinedName != "")
|
||
// {
|
||
// Console.WriteLine("USB: " + usbInfo.chUserDefinedName + " (" + usbInfo.chSerialNumber + ")");
|
||
// CameraName.Add("USB: " + usbInfo.chUserDefinedName + " (" + usbInfo.chSerialNumber + ")");
|
||
// }
|
||
// else
|
||
// {
|
||
// Console.WriteLine("USB: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")");
|
||
// CameraName.Add("USB: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")");
|
||
// }
|
||
// }
|
||
// }
|
||
// if (m_pDeviceList.nDeviceNum == 0)
|
||
// {
|
||
// Console.WriteLine("未能找到USB或者网线接口的相机", 0);
|
||
// return null;
|
||
// }
|
||
|
||
// return CameraName;
|
||
//}
|
||
public Dictionary<string, CameraInfor> EnumDevice()
|
||
{
|
||
System.GC.Collect();//强制对所有代进行及时垃圾回收
|
||
m_pDeviceList.nDeviceNum = 0; //初始化信息列表
|
||
int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
|
||
if (0 != nRet)
|
||
{
|
||
return null;
|
||
}
|
||
allCamera.Clear(); //清空设备列表
|
||
CameraInfor cameraInfor;
|
||
for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
|
||
{
|
||
MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));//获取第i个相机句柄的相机信息
|
||
cameraInfor = new CameraInfor();
|
||
cameraInfor.pDeviceInfo = m_pDeviceList.pDeviceInfo[i];//获取相机句柄
|
||
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
|
||
{
|
||
MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));//将通用相机信息结构体转化为Gige相机结构体
|
||
|
||
UInt32 nNetIp1 = (gigeInfo.nNetExport & 0xFF000000) >> 24;
|
||
UInt32 nNetIp2 = (gigeInfo.nNetExport & 0x00FF0000) >> 16;
|
||
UInt32 nNetIp3 = (gigeInfo.nNetExport & 0x0000FF00) >> 8;
|
||
UInt32 nNetIp4 = (gigeInfo.nNetExport & 0x000000FF);
|
||
|
||
// ch:显示IP | en:Display IP
|
||
UInt32 nIp1 = (gigeInfo.nCurrentIp & 0xFF000000) >> 24;
|
||
UInt32 nIp2 = (gigeInfo.nCurrentIp & 0x00FF0000) >> 16;
|
||
UInt32 nIp3 = (gigeInfo.nCurrentIp & 0x0000FF00) >> 8;
|
||
UInt32 nIp4 = (gigeInfo.nCurrentIp & 0x000000FF);
|
||
|
||
|
||
cameraInfor.serialNumber = gigeInfo.chSerialNumber;
|
||
cameraInfor.userDefinedName = gigeInfo.chUserDefinedName;
|
||
cameraInfor.manufacturerName = gigeInfo.chManufacturerName;
|
||
cameraInfor.modelName = gigeInfo.chModelName;
|
||
cameraInfor.deviceType = "GEV"; //千兆网工业相机技术之GigE Vision(GEV)
|
||
cameraInfor.deviceIPAdd = nIp1.ToString() + "." + nIp2.ToString() + "." + nIp3.ToString() + "." + nIp4.ToString();
|
||
allCamera.Add(cameraInfor.userDefinedName, cameraInfor);
|
||
}
|
||
else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
|
||
{
|
||
MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stUsb3VInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO));
|
||
cameraInfor.serialNumber = usbInfo.chSerialNumber;
|
||
cameraInfor.userDefinedName = usbInfo.chUserDefinedName;
|
||
cameraInfor.manufacturerName = usbInfo.chManufacturerName;
|
||
cameraInfor.modelName = usbInfo.chModelName;
|
||
cameraInfor.deviceType = "U3V";
|
||
allCamera.Add(cameraInfor.deviceIPAdd, cameraInfor);
|
||
}
|
||
|
||
}
|
||
return allCamera;
|
||
}
|
||
/// <summary>
|
||
/// 根据相机序列号开启相机
|
||
/// </summary>
|
||
/// <param name="CameraName"></param>
|
||
/// int cameraIndex
|
||
/// <returns></returns>
|
||
public override bool OpenCamera(string userDefinedName, IntPtr hWnd)
|
||
{
|
||
int nRet = 0;
|
||
currentCam = allCamera[userDefinedName];
|
||
//m_pDeviceList.pDeviceInfo[cameraIndex]
|
||
device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(allCamera[userDefinedName].pDeviceInfo, typeof(MyCamera.MV_CC_DEVICE_INFO));
|
||
IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
|
||
MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
|
||
|
||
|
||
if (null == hkCamera)
|
||
{
|
||
hkCamera = new MyCamera();
|
||
if (null == hkCamera)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
for (int i = 0; i < 10; i++)
|
||
{
|
||
nRet = hkCamera.MV_CC_CreateDevice_NET(ref device);
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
Thread.Sleep(1);
|
||
if (i == 9) Console.WriteLine("创建相机失败!{0:x8}", nRet);
|
||
continue;
|
||
}
|
||
nRet = hkCamera.MV_CC_OpenDevice_NET();
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
hkCamera.MV_CC_DestroyDevice_NET();
|
||
Thread.Sleep(10);
|
||
if (i == 9) Console.WriteLine("打开相机失败!{0:x8}", nRet);
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
//探测网络最佳包大小(只对gige相机有效)
|
||
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
|
||
{
|
||
int nPacketSize = hkCamera.MV_CC_GetOptimalPacketSize_NET();
|
||
if (nPacketSize > 0)
|
||
{
|
||
nRet = hkCamera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
|
||
if (nRet != MyCamera.MV_OK)
|
||
{
|
||
Console.WriteLine("Warning: Set Packet Size failed {0:x8}", nRet);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine("Warning: Get Packet Size failed {0:x8}", nPacketSize);
|
||
}
|
||
}
|
||
|
||
SetTriggerMode(true);
|
||
SetSoftTrigger(true);
|
||
|
||
//注册断线重连回调函数
|
||
nRet = hkCamera.MV_CC_RegisterExceptionCallBack_NET(pCallBackFunc, IntPtr.Zero);
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
return false;
|
||
}
|
||
GC.KeepAlive(pCallBackFunc);
|
||
//注册图像回调函数
|
||
//ImageCallback = new MyCamera.cbOutputExdelegate(ImageCallbackFunc);
|
||
//nRet = hkCamera.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
Console.WriteLine("Register image callback failed!");
|
||
return false;
|
||
}
|
||
|
||
// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
|
||
hkCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS);
|
||
//设置开启触发模式
|
||
nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
|
||
//设置开启软触发模式
|
||
//hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
|
||
//使用软触发命令
|
||
//nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
m_bGrabbing = false;
|
||
return false;
|
||
}
|
||
//开始采集
|
||
// nRet = hkCamera.MV_CC_StartGrabbing_NET();
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
Console.WriteLine("开启相机采集失败! {0:x8}", nRet);
|
||
return false;
|
||
}
|
||
|
||
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 设置触发模式
|
||
/// </summary>
|
||
/// <param name="isTrigger">触发模式:true;连续采集模式:false</param>
|
||
public void SetTriggerMode(bool isTrigger)
|
||
{
|
||
if (isTrigger)
|
||
{
|
||
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
|
||
}
|
||
else
|
||
{
|
||
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置软触发
|
||
/// </summary>
|
||
/// <param name="trigBySoft"></param>
|
||
public void SetSoftTrigger(bool trigBySoft)
|
||
{
|
||
if (trigBySoft)
|
||
{
|
||
hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
|
||
}
|
||
else
|
||
{
|
||
//外部触发源:Line0~Line3,默认用Line0
|
||
hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
|
||
}
|
||
}
|
||
|
||
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
//public override bool OneGrap()
|
||
//{
|
||
// try
|
||
// {
|
||
// if (m_bGrabbing)
|
||
// {
|
||
// Console.WriteLine("Camera is now Continue Grabing Images!");
|
||
|
||
// return false;
|
||
// }
|
||
// else
|
||
// {
|
||
// // ch:标志位置位true | en:Set position bit true
|
||
// //m_bGrabbing = true;
|
||
// int nRet;
|
||
// MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT();
|
||
// //设置开启触发模式
|
||
// nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
|
||
// //设置开启软触发模式
|
||
// nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
|
||
|
||
// //使用软触发命令
|
||
// nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
|
||
|
||
|
||
// if (MyCamera.MV_OK != nRet)
|
||
// {
|
||
// throw new Exception($"相机拍照触发失败:{nRet}");
|
||
// }
|
||
// //nRet = hkCamera.MV_CC_GetImageBuffer_NET(ref frameInfo, 1000);
|
||
// //nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref frameInfo);
|
||
// if (MyCamera.MV_OK != nRet)
|
||
// {
|
||
// m_bGrabbing = false;
|
||
// return false;
|
||
// }
|
||
// else
|
||
// {
|
||
// //if (frameInfo.pBufAddr != IntPtr.Zero)
|
||
// //{
|
||
// if (nRet == MyCamera.MV_OK)
|
||
// {
|
||
// var pFrameInfo = frameInfo.stFrameInfo;
|
||
|
||
// //himg.GenImage1("byte", pFrameInfo.nWidth, pFrameInfo.nHeight, frameInfo.pBufAddr);
|
||
// Mat mat = Mat.FromPixelData(pFrameInfo.nWidth, pFrameInfo.nHeight, MatType.CV_8UC3, frameInfo.pBufAddr);
|
||
// //Bitmap a = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
|
||
// //OnDeliverImg?.Invoke(_mat);
|
||
// Cv2.ImWrite("test.jpg", mat);
|
||
// OnImgTransfer?.Invoke(mat);
|
||
// }
|
||
// //}
|
||
// }
|
||
|
||
// // HeventSlim.Wait();
|
||
// return true;
|
||
// }
|
||
// }
|
||
// catch (Exception)
|
||
// {
|
||
// return false;
|
||
// }
|
||
|
||
//}
|
||
|
||
bool IsGrabImg;
|
||
public void GrabImg()
|
||
{
|
||
IsGrabImg = true;
|
||
int nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
|
||
MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT();
|
||
|
||
//nRet = m_MyCamera.MV_CC_GetImageBuffer_NET(ref frameInfo,10);
|
||
//nRet = m_MyCamera.MV_CC_FreeImageBuffer_NET(ref frameInfo);
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
//ShowErrorMsg("Trigger Software Fail!", nRet);
|
||
}
|
||
}
|
||
|
||
|
||
public void StartGarb(IntPtr handle)
|
||
{
|
||
int nRet;
|
||
nRet = NecessaryOperBeforeGrab();
|
||
|
||
m_bGrabbing = true;
|
||
IsGrabImg = false;
|
||
m_hReceiveThread = new Thread(new ParameterizedThreadStart(ReceiveThreadProcess));
|
||
m_hReceiveThread.Start(handle);
|
||
|
||
m_stFrameInfo.nFrameLen = 0;
|
||
|
||
m_stFrameInfo.enPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined;
|
||
// nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
|
||
//设置开启软触发模式
|
||
//nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
|
||
// ch:开始采集 | en:Start Grabbing
|
||
nRet = hkCamera.MV_CC_StartGrabbing_NET();
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
m_bGrabbing = false;
|
||
m_hReceiveThread.Join();
|
||
//ShowErrorMsg("Start Grabbing Fail!", nRet);
|
||
return;
|
||
}
|
||
}
|
||
|
||
//public void StopGrabbing()
|
||
//{
|
||
// int nRet = hkCamera.MV_CC_StopGrabbing_NET();
|
||
// if (nRet != MyCamera.MV_OK)
|
||
// {
|
||
// //ShowAlarm(string.Format("相机{0}结束采集失败,错误代码:{1}", m_Name, nRet));
|
||
// }
|
||
|
||
//}
|
||
|
||
public void ReceiveThreadProcess(object handle)
|
||
{
|
||
MyCamera.MV_FRAME_OUT stFrameInfo = new MyCamera.MV_FRAME_OUT();
|
||
MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO();
|
||
MyCamera.MV_PIXEL_CONVERT_PARAM stConvertInfo = new MyCamera.MV_PIXEL_CONVERT_PARAM();
|
||
int nRet = MyCamera.MV_OK;
|
||
|
||
while (m_bGrabbing)
|
||
{
|
||
nRet = hkCamera.MV_CC_GetImageBuffer_NET(ref stFrameInfo, 1000);
|
||
if (nRet == MyCamera.MV_OK)
|
||
{
|
||
lock (BufForDriverLock)
|
||
{
|
||
if (m_BufForDriver == IntPtr.Zero || stFrameInfo.stFrameInfo.nFrameLen > m_nBufSizeForDriver)
|
||
{
|
||
if (m_BufForDriver != IntPtr.Zero)
|
||
{
|
||
Marshal.Release(m_BufForDriver);
|
||
m_BufForDriver = IntPtr.Zero;
|
||
}
|
||
|
||
m_BufForDriver = Marshal.AllocHGlobal((Int32)stFrameInfo.stFrameInfo.nFrameLen);
|
||
if (m_BufForDriver == IntPtr.Zero)
|
||
{
|
||
return;
|
||
}
|
||
m_nBufSizeForDriver = stFrameInfo.stFrameInfo.nFrameLen;
|
||
}
|
||
|
||
m_stFrameInfo = stFrameInfo.stFrameInfo;
|
||
CopyMemory(m_BufForDriver, stFrameInfo.pBufAddr, stFrameInfo.stFrameInfo.nFrameLen);
|
||
|
||
stConvertInfo.nWidth = stFrameInfo.stFrameInfo.nWidth;
|
||
stConvertInfo.nHeight = stFrameInfo.stFrameInfo.nHeight;
|
||
stConvertInfo.enSrcPixelType = stFrameInfo.stFrameInfo.enPixelType;
|
||
stConvertInfo.pSrcData = stFrameInfo.pBufAddr;
|
||
stConvertInfo.nSrcDataLen = stFrameInfo.stFrameInfo.nFrameLen;
|
||
stConvertInfo.pDstBuffer = m_ConvertDstBuf;
|
||
stConvertInfo.nDstBufferSize = m_nConvertDstBufLen;
|
||
if (PixelFormat.Format8bppIndexed == m_bitmap.PixelFormat)
|
||
{
|
||
stConvertInfo.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
|
||
hkCamera.MV_CC_ConvertPixelType_NET(ref stConvertInfo);
|
||
}
|
||
else
|
||
{
|
||
stConvertInfo.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed;
|
||
hkCamera.MV_CC_ConvertPixelType_NET(ref stConvertInfo);
|
||
}
|
||
|
||
// ch:保存Bitmap数据 | en:Save Bitmap Data
|
||
BitmapData bitmapData = m_bitmap.LockBits(new Rectangle(0, 0, stConvertInfo.nWidth, stConvertInfo.nHeight), ImageLockMode.ReadWrite, m_bitmap.PixelFormat);
|
||
CopyMemory(bitmapData.Scan0, stConvertInfo.pDstBuffer, (UInt32)(bitmapData.Stride * m_bitmap.Height));
|
||
m_bitmap.UnlockBits(bitmapData);
|
||
|
||
}
|
||
if (RemoveCustomPixelFormats(stFrameInfo.stFrameInfo.enPixelType))
|
||
{
|
||
hkCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
|
||
continue;
|
||
}
|
||
|
||
nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
|
||
if (IsGrabImg)
|
||
{
|
||
if (MyCamera.MV_OK == nRet)
|
||
{
|
||
if (stFrameInfo.pBufAddr != IntPtr.Zero)
|
||
{
|
||
stDisplayInfo.hWnd = (IntPtr)handle;
|
||
stDisplayInfo.pData = stFrameInfo.pBufAddr;
|
||
stDisplayInfo.nDataLen = stFrameInfo.stFrameInfo.nFrameLen;
|
||
stDisplayInfo.nWidth = stFrameInfo.stFrameInfo.nWidth;
|
||
stDisplayInfo.nHeight = stFrameInfo.stFrameInfo.nHeight;
|
||
stDisplayInfo.enPixelType = stFrameInfo.stFrameInfo.enPixelType;
|
||
hkCamera.MV_CC_DisplayOneFrame_NET(ref stDisplayInfo);
|
||
//nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo);
|
||
var pFrameInfo = stFrameInfo.stFrameInfo;
|
||
Mat ab = new Mat(pFrameInfo.nHeight, pFrameInfo.nWidth, MatType.CV_8UC3, stFrameInfo.pBufAddr);
|
||
//OnImgTransfer?.Invoke(ab);
|
||
OnHImageOutput?.Invoke(DateTime.Now, ab);
|
||
//Cv2.ImWrite("test.jpg", ab);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
|
||
}
|
||
}
|
||
}
|
||
public void ConvertToImage(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
|
||
{
|
||
int nRet;
|
||
//HObject img = new HObject();
|
||
Mat matImag = new Mat();
|
||
//Bitmap bitmap = new Bitmap();
|
||
IntPtr pImageBuf = IntPtr.Zero;
|
||
int nImageBufSize = 0;
|
||
//Bitmap cameraImg;
|
||
IntPtr pTemp = IntPtr.Zero;
|
||
if (IsColorPixelFormat(pFrameInfo.enPixelType))
|
||
{
|
||
//cameraImg = new Bitmap(pFrameInfo.nWidth, pFrameInfo.nHeight, pFrameInfo.nWidth * 3, System.Drawing.Imaging.PixelFormat.Format24bppRgb,pData);
|
||
|
||
//bmp.Save("1.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
|
||
|
||
if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
|
||
{
|
||
pTemp = pData;
|
||
}
|
||
else
|
||
{
|
||
if (IntPtr.Zero == pImageBuf || nImageBufSize < (pFrameInfo.nWidth * pFrameInfo.nHeight * 3))
|
||
{
|
||
if (pImageBuf != IntPtr.Zero)
|
||
{
|
||
Marshal.FreeHGlobal(pImageBuf);
|
||
pImageBuf = IntPtr.Zero;
|
||
}
|
||
pImageBuf = Marshal.AllocHGlobal((int)pFrameInfo.nWidth * pFrameInfo.nHeight * 3);
|
||
if (IntPtr.Zero == pImageBuf)
|
||
{
|
||
Console.WriteLine("图像采集为空");
|
||
return;
|
||
}
|
||
nImageBufSize = pFrameInfo.nWidth * pFrameInfo.nHeight * 3;
|
||
}
|
||
MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();
|
||
|
||
stPixelConvertParam.pSrcData = pData;//源数据
|
||
stPixelConvertParam.nWidth = pFrameInfo.nWidth;//图像宽度
|
||
stPixelConvertParam.nHeight = pFrameInfo.nHeight;//图像高度
|
||
stPixelConvertParam.enSrcPixelType = pFrameInfo.enPixelType;//源数据的格式
|
||
stPixelConvertParam.nSrcDataLen = pFrameInfo.nFrameLen;
|
||
|
||
stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
|
||
stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
|
||
stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;
|
||
|
||
|
||
nRet = hkCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
Console.WriteLine("图像转换异常");
|
||
return;
|
||
}
|
||
pTemp = stPixelConvertParam.pDstBuffer;
|
||
}
|
||
try
|
||
{
|
||
HOperatorSet.GenImageInterleaved(out hPylonImage, (HTuple)pTemp, (HTuple)"rgb", (HTuple)pFrameInfo.nWidth, (HTuple)pFrameInfo.nHeight, -1, "byte", 0, 0, 0, 0, -1, 0);
|
||
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
Console.WriteLine(ex.ToString());
|
||
return;
|
||
}
|
||
}
|
||
else if (IsMonoPixelFormat(pFrameInfo.enPixelType))
|
||
{
|
||
if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
|
||
{
|
||
pTemp = pData;
|
||
}
|
||
else
|
||
{
|
||
if (IntPtr.Zero == pImageBuf || nImageBufSize < (pFrameInfo.nWidth * pFrameInfo.nHeight))
|
||
{
|
||
if (pImageBuf != IntPtr.Zero)
|
||
{
|
||
Marshal.FreeHGlobal(pImageBuf);
|
||
pImageBuf = IntPtr.Zero;
|
||
}
|
||
|
||
pImageBuf = Marshal.AllocHGlobal((int)pFrameInfo.nWidth * pFrameInfo.nHeight);
|
||
if (IntPtr.Zero == pImageBuf)
|
||
{
|
||
Console.WriteLine("图像采集为空");
|
||
return;
|
||
}
|
||
nImageBufSize = pFrameInfo.nWidth * pFrameInfo.nHeight;
|
||
}
|
||
|
||
MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();
|
||
|
||
stPixelConvertParam.pSrcData = pData;//源数据
|
||
stPixelConvertParam.nWidth = pFrameInfo.nWidth;//图像宽度
|
||
stPixelConvertParam.nHeight = pFrameInfo.nHeight;//图像高度
|
||
stPixelConvertParam.enSrcPixelType = pFrameInfo.enPixelType;//源数据的格式
|
||
stPixelConvertParam.nSrcDataLen = pFrameInfo.nFrameLen;
|
||
|
||
stPixelConvertParam.nDstBufferSize = (uint)nImageBufSize;
|
||
stPixelConvertParam.pDstBuffer = pImageBuf;//转换后的数据
|
||
stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
|
||
nRet = hkCamera.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
Console.WriteLine("图像转换异常");
|
||
return;
|
||
}
|
||
pTemp = stPixelConvertParam.pDstBuffer; ;
|
||
}
|
||
try
|
||
{
|
||
//cameraImg = new Bitmap();
|
||
// HOperatorSet.GenImage1Extern(out hPylonImage, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, pTemp, IntPtr.Zero);
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
MessageBox.Show(ex.ToString());
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine("采集图像格式错误,不为彩色和黑白图像");
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
//GetImage(hPylonImage);//调用相机基类的函数,用于传出变量
|
||
//hPylonImage.Dispose();
|
||
m_bGrabbing = false;
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Console.WriteLine(e.ToString());
|
||
return;
|
||
}
|
||
}
|
||
private Boolean IsMono(UInt32 enPixelType)
|
||
{
|
||
switch (enPixelType)
|
||
{
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono1p:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono2p:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono4p:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8_Signed:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono14:
|
||
case (UInt32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono16:
|
||
return true;
|
||
default:
|
||
return false;
|
||
}
|
||
}
|
||
private Int32 NecessaryOperBeforeGrab()
|
||
{
|
||
// ch:取图像宽 | en:Get Iamge Width
|
||
MyCamera.MVCC_INTVALUE_EX stWidth = new MyCamera.MVCC_INTVALUE_EX();
|
||
int nRet = hkCamera.MV_CC_GetIntValueEx_NET("Width", ref stWidth);
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
//ShowErrorMsg("Get Width Info Fail!", nRet);
|
||
return nRet;
|
||
}
|
||
// ch:取图像高 | en:Get Iamge Height
|
||
MyCamera.MVCC_INTVALUE_EX stHeight = new MyCamera.MVCC_INTVALUE_EX();
|
||
nRet = hkCamera.MV_CC_GetIntValueEx_NET("Height", ref stHeight);
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
//ShowErrorMsg("Get Height Info Fail!", nRet);
|
||
return nRet;
|
||
}
|
||
// ch:取像素格式 | en:Get Pixel Format
|
||
MyCamera.MVCC_ENUMVALUE stPixelFormat = new MyCamera.MVCC_ENUMVALUE();
|
||
nRet = hkCamera.MV_CC_GetEnumValue_NET("PixelFormat", ref stPixelFormat);
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
//ShowErrorMsg("Get Pixel Format Fail!", nRet);
|
||
return nRet;
|
||
}
|
||
|
||
// ch:设置bitmap像素格式,申请相应大小内存 | en:Set Bitmap Pixel Format, alloc memory
|
||
if ((Int32)MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined == stPixelFormat.nCurValue)
|
||
{
|
||
//ShowErrorMsg("Unknown Pixel Format!", MyCamera.MV_E_UNKNOW);
|
||
return MyCamera.MV_E_UNKNOW;
|
||
}
|
||
else if (IsMono(stPixelFormat.nCurValue))
|
||
{
|
||
m_bitmapPixelFormat = PixelFormat.Format8bppIndexed;
|
||
|
||
if (IntPtr.Zero != m_ConvertDstBuf)
|
||
{
|
||
Marshal.Release(m_ConvertDstBuf);
|
||
m_ConvertDstBuf = IntPtr.Zero;
|
||
}
|
||
|
||
// Mono8为单通道
|
||
m_nConvertDstBufLen = (UInt32)(stWidth.nCurValue * stHeight.nCurValue);
|
||
m_ConvertDstBuf = Marshal.AllocHGlobal((Int32)m_nConvertDstBufLen);
|
||
if (IntPtr.Zero == m_ConvertDstBuf)
|
||
{
|
||
//ShowErrorMsg("Malloc Memory Fail!", MyCamera.MV_E_RESOURCE);
|
||
return MyCamera.MV_E_RESOURCE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m_bitmapPixelFormat = PixelFormat.Format24bppRgb;
|
||
|
||
if (IntPtr.Zero != m_ConvertDstBuf)
|
||
{
|
||
Marshal.FreeHGlobal(m_ConvertDstBuf);
|
||
m_ConvertDstBuf = IntPtr.Zero;
|
||
}
|
||
|
||
// RGB为三通道
|
||
m_nConvertDstBufLen = (UInt32)(3 * stWidth.nCurValue * stHeight.nCurValue);
|
||
m_ConvertDstBuf = Marshal.AllocHGlobal((Int32)m_nConvertDstBufLen);
|
||
if (IntPtr.Zero == m_ConvertDstBuf)
|
||
{
|
||
//ShowErrorMsg("Malloc Memory Fail!", MyCamera.MV_E_RESOURCE);
|
||
return MyCamera.MV_E_RESOURCE;
|
||
}
|
||
}
|
||
|
||
// 确保释放保存了旧图像数据的bitmap实例,用新图像宽高等信息new一个新的bitmap实例
|
||
if (null != m_bitmap)
|
||
{
|
||
m_bitmap.Dispose();
|
||
m_bitmap = null;
|
||
}
|
||
m_bitmap = new Bitmap((Int32)stWidth.nCurValue, (Int32)stHeight.nCurValue, m_bitmapPixelFormat);
|
||
|
||
// ch:Mono8格式,设置为标准调色板 | en:Set Standard Palette in Mono8 Format
|
||
if (PixelFormat.Format8bppIndexed == m_bitmapPixelFormat)
|
||
{
|
||
ColorPalette palette = m_bitmap.Palette;
|
||
for (int i = 0; i < palette.Entries.Length; i++)
|
||
{
|
||
palette.Entries[i] = Color.FromArgb(i, i, i);
|
||
}
|
||
m_bitmap.Palette = palette;
|
||
}
|
||
|
||
return MyCamera.MV_OK;
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 相机重连开启
|
||
/// </summary>
|
||
/// <param name="CameraName"></param>
|
||
/// <returns></returns>
|
||
public override bool ReconnectCamera(string CameraName)
|
||
{
|
||
CloserCamera();
|
||
for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
|
||
{
|
||
device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
|
||
IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
|
||
MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
|
||
if (gigeInfo.chSerialNumber == CameraName)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
int index = 0;
|
||
while (true)
|
||
{
|
||
int nRet = hkCamera.MV_CC_CreateDevice_NET(ref device);
|
||
index++;
|
||
if (index > 1000)
|
||
{
|
||
Console.WriteLine("相机重连超时,请检查相机安装");
|
||
nRet = -1;
|
||
break;
|
||
}
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
Thread.Sleep(5);
|
||
continue;
|
||
}
|
||
nRet = hkCamera.MV_CC_OpenDevice_NET();
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
Thread.Sleep(5);
|
||
hkCamera.MV_CC_DestroyDevice_NET();
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
Thread.Sleep(5);
|
||
hkCamera.MV_CC_DestroyDevice_NET();
|
||
continue;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void ImageCallbackFunc(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
|
||
{
|
||
//Console.WriteLine("Get one frame: Width[" + Convert.ToString(pFrameInfo.nWidth) + "] , Height[" + Convert.ToString(pFrameInfo.nHeight)
|
||
// + "] , FrameNum[" + Convert.ToString(pFrameInfo.nFrameNum) + "]");
|
||
|
||
ConvertToImage(pData, ref pFrameInfo, pUser);
|
||
}
|
||
|
||
|
||
public Action<Mat> OnDeliverImg { get; set; }
|
||
|
||
|
||
|
||
public void Snapshot()
|
||
{
|
||
Stopwatch sw = new Stopwatch();
|
||
sw.Start();
|
||
// ImageSet set = new ImageSet();
|
||
// set.SnapshotCount = SnapshotCount;
|
||
// set.SnapshotFileName = SnapshotFileNames;
|
||
|
||
//InitialImageSet(set);
|
||
MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT();
|
||
nRet = MyCamera.MV_OK;
|
||
if (true)
|
||
{
|
||
// ch: 触发命令 || en: Trigger command
|
||
nRet = hkCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
|
||
if (MyCamera.MV_OK != nRet)
|
||
{
|
||
throw new Exception($"相机拍照触发失败:{nRet}");
|
||
}
|
||
|
||
nRet = hkCamera.MV_CC_GetImageBuffer_NET(ref frameInfo, 1000);
|
||
nRet = hkCamera.MV_CC_FreeImageBuffer_NET(ref frameInfo);
|
||
}
|
||
else
|
||
{
|
||
_snapHandle.Reset();
|
||
_snapFlag = true;
|
||
_snapHandle.WaitOne();
|
||
//lock (_imgCallBackLock)
|
||
{
|
||
frameInfo.stFrameInfo = _frame.stFrameInfo;
|
||
frameInfo.pBufAddr = _frame.pBufAddr;
|
||
}
|
||
}
|
||
|
||
// ch:获取一帧图像 | en:Get one image
|
||
if (MyCamera.MV_OK == nRet)
|
||
{
|
||
if (frameInfo.pBufAddr != IntPtr.Zero)
|
||
{
|
||
if (nRet == MyCamera.MV_OK)
|
||
{
|
||
var pFrameInfo = frameInfo.stFrameInfo;
|
||
HImage hImage = new HImage();
|
||
hImage.GenImage1("byte", pFrameInfo.nWidth, pFrameInfo.nHeight, frameInfo.pBufAddr);
|
||
Mat mat = new Mat();
|
||
Bitmap a = hImage.ConvertHImageToBitmap();
|
||
OnBitmapTransfer?.Invoke(a);
|
||
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
throw new Exception($"Grap Image Failed:{nRet:x8}");
|
||
}
|
||
|
||
sw.Stop();
|
||
//LogAsync(DateTime.Now, LogLevel.Information, $"取像耗时:{sw.ElapsedMilliseconds} ms");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 转化像素为Bit图像
|
||
/// </summary>
|
||
/// <param name="pData"></param>
|
||
/// <param name="pFrameInfo"></param>
|
||
public Bitmap GetBitmap(int nWidth, int nHeight, int nBpp, byte[] DataBuf, int nCompress = 1)
|
||
{
|
||
int nNewH = nHeight / nCompress;
|
||
int nNewW = nWidth / nCompress;
|
||
|
||
|
||
Bitmap BitmapImage = new Bitmap(nNewW, nNewH, PixelFormat.Format24bppRgb);
|
||
BitmapData srcBmpData =
|
||
BitmapImage.LockBits(
|
||
new Rectangle(0, 0, BitmapImage.Width, BitmapImage.Height),
|
||
ImageLockMode.ReadWrite, BitmapImage.PixelFormat);
|
||
|
||
switch (nBpp)
|
||
{
|
||
case 0:
|
||
unsafe
|
||
{
|
||
byte* psrcBuffer = (byte*)srcBmpData.Scan0.ToPointer();
|
||
|
||
int nIndex = 0;
|
||
|
||
for (int i = 0; i < nHeight; i += nCompress)
|
||
{
|
||
for (int j = 0; j < nWidth; j += nCompress)
|
||
{
|
||
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j];
|
||
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j];
|
||
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j];
|
||
}
|
||
}
|
||
|
||
}
|
||
break;
|
||
|
||
case 1:
|
||
unsafe
|
||
{
|
||
byte* psrcBuffer = (byte*)srcBmpData.Scan0.ToPointer();
|
||
|
||
int nCount = nWidth * nHeight;
|
||
int nStep = nCount * 2;
|
||
int nIndex = 0;
|
||
|
||
for (int i = 0; i < nHeight; i += nCompress)
|
||
{
|
||
for (int j = 0; j < nWidth; j += nCompress)
|
||
{
|
||
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j + nStep];
|
||
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j + nCount];
|
||
psrcBuffer[nIndex++] = DataBuf[i * nWidth + j];
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
BitmapImage.UnlockBits(srcBmpData);
|
||
return BitmapImage;
|
||
}
|
||
|
||
|
||
public void SetHeartBeatTime(uint value)
|
||
{
|
||
try
|
||
{
|
||
//判断是否是网口相机
|
||
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
|
||
{
|
||
hkCamera.MV_CC_SetHeartBeatTimeout_NET(value);
|
||
}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
|
||
}
|
||
}
|
||
|
||
public override bool SetExpoureTime(int ExposureTime)
|
||
{
|
||
try
|
||
{
|
||
hkCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
|
||
int nRet = hkCamera.MV_CC_SetFloatValue_NET("ExposureTime", ExposureTime);
|
||
if (nRet != MyCamera.MV_OK)
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
catch (Exception)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 判断是否为彩色图像
|
||
/// </summary>
|
||
/// <param name="mvGvspPixelType"></param>
|
||
/// <returns></returns>
|
||
private bool IsColorPixelFormat(MyCamera.MvGvspPixelType enType)
|
||
{
|
||
switch (enType)
|
||
{
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGBA8_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGRA8_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed:
|
||
return true;
|
||
default:
|
||
return false;
|
||
}
|
||
}
|
||
private bool IsMonoPixelFormat(MyCamera.MvGvspPixelType enType)
|
||
{
|
||
switch (enType)
|
||
{
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
|
||
case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
|
||
return true;
|
||
default:
|
||
return false;
|
||
}
|
||
}
|
||
private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat)
|
||
{
|
||
Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000));
|
||
if (0x80000000 == nResult)
|
||
{
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
public void SetTriggerMode()
|
||
{
|
||
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
|
||
}
|
||
public void SetTriggerModeON()
|
||
{
|
||
hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
|
||
}
|
||
public void SetTriggerSource()
|
||
{
|
||
hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
|
||
}
|
||
public void SetTriggerSourceLine0()
|
||
{
|
||
hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
|
||
}
|
||
public void SetTriggerMode1()
|
||
{
|
||
int nRet;
|
||
nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
|
||
//设置开启软触发模式
|
||
nRet = hkCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
|
||
}
|
||
|
||
}
|
||
public static class HalconHelper
|
||
{
|
||
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
|
||
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
|
||
public static Bitmap ConvertHImageToBitmap(this HObject hImage)
|
||
{
|
||
HOperatorSet.CountChannels(hImage, out HTuple chanels);
|
||
if (chanels.I == 1)
|
||
{
|
||
return hImage.ConvertHImageTo8GrayBitmap();
|
||
}
|
||
else
|
||
{
|
||
return hImage.ConvertHImageToRGBBitmap();
|
||
// return hImage.HObject2BitmapRGB();
|
||
}
|
||
}
|
||
public static Bitmap ConvertHImageTo8GrayBitmap(this HObject hImage)
|
||
{
|
||
try
|
||
{
|
||
HTuple type, width, height, pointer;
|
||
HOperatorSet.GetImagePointer1(hImage, out pointer, out type, out width, out height);
|
||
|
||
Bitmap bmp = new Bitmap(width.I, height.I, PixelFormat.Format8bppIndexed);
|
||
ColorPalette pal = bmp.Palette;
|
||
for (int i = 0; i <= 255; i++)
|
||
{
|
||
pal.Entries[i] = Color.FromArgb(255, i, i, i);
|
||
}
|
||
bmp.Palette = pal;
|
||
|
||
BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
|
||
|
||
if (width % 4 == 0)
|
||
{
|
||
CopyMemory(bitmapData.Scan0, (IntPtr)pointer.D, (uint)(bitmapData.Stride * height.I));
|
||
}
|
||
else
|
||
{
|
||
Parallel.For(0, height.I, h =>
|
||
{
|
||
CopyMemory(bitmapData.Scan0 + h * bitmapData.Stride, (IntPtr)(pointer.D + h * width.I), (uint)width.I);
|
||
});
|
||
}
|
||
|
||
bmp.UnlockBits(bitmapData);
|
||
return bmp;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
public static Bitmap ConvertHImageToRGBBitmap(this HObject hImage)
|
||
{
|
||
try
|
||
{
|
||
HOperatorSet.GetImagePointer3(hImage, out HTuple pointRed, out HTuple pointGreen, out HTuple pointBlue, out HTuple type, out HTuple width, out HTuple height);
|
||
|
||
Bitmap image = new Bitmap(width.I, height.I, PixelFormat.Format24bppRgb);
|
||
BitmapData imageData = image.LockBits(new Rectangle(0, 0, width.I, height.I), ImageLockMode.ReadWrite, image.PixelFormat);
|
||
|
||
IntPtr pR = (IntPtr)pointRed.D;
|
||
IntPtr pG = (IntPtr)pointGreen.D;
|
||
IntPtr pB = (IntPtr)pointBlue.D;
|
||
|
||
Parallel.For(0, imageData.Height, h =>
|
||
{
|
||
Parallel.For(0, imageData.Width, w =>
|
||
{
|
||
int dest = h * imageData.Stride + w * 3;
|
||
int source = h * imageData.Width + w;
|
||
|
||
Marshal.WriteByte(imageData.Scan0, dest, Marshal.ReadByte(pB, source));
|
||
Marshal.WriteByte(imageData.Scan0, dest + 1, Marshal.ReadByte(pG, source));
|
||
Marshal.WriteByte(imageData.Scan0, dest + 2, Marshal.ReadByte(pR, source));
|
||
});
|
||
});
|
||
|
||
image.UnlockBits(imageData);
|
||
return image;
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
}
|
||
public class CameraInfor
|
||
{
|
||
public string userDefinedName { get; set; } //用户定义的名字
|
||
public string serialNumber { get; set; } //序列号
|
||
public string deviceIPAdd { get; set; } //设备IP地址
|
||
public string manufacturerName { get; set; }//制造厂商名
|
||
public string modelName { get; set; } //型号名称
|
||
public string deviceType { get; set; } //型号名称
|
||
public IntPtr pDeviceInfo; //相机句柄
|
||
public float ExposureTime { get; set; } //曝光时间
|
||
public float Gain { get; set; } //增益
|
||
public float ResultingFrameRate { get; set; } //帧率
|
||
public bool isOpenTriggerMode { get; set; } //是否打开触发方式
|
||
}
|
||
public class ASCameraParamInfor
|
||
{
|
||
/// <summary>
|
||
/// 曝光时间
|
||
/// </summary>
|
||
public float ExposureTime { get; set; }
|
||
/// <summary>
|
||
/// 增益
|
||
/// </summary>
|
||
public float Gain { get; set; }
|
||
/// <summary>
|
||
/// 获取帧率
|
||
/// </summary>
|
||
public float FrameRate { get; set; }
|
||
}
|
||
|
||
}
|