first commit
This commit is contained in:
106
DH.Do3Think/CameraBase.cs
Normal file
106
DH.Do3Think/CameraBase.cs
Normal file
@ -0,0 +1,106 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing.Imaging;
|
||||
using DVPCameraType;
|
||||
using OpenCvSharp;
|
||||
|
||||
namespace DH.Devices.Camera
|
||||
{
|
||||
public class CameraBase
|
||||
{
|
||||
public volatile int SnapshotCount = 0;
|
||||
[Category("采图模式")]
|
||||
[Description("是否连续模式。true:连续模式采图;false:触发模式采图")]
|
||||
[DisplayName("连续模式")]
|
||||
public bool IsContinueMode { get; set; } = false;
|
||||
|
||||
[Category("采图模式")]
|
||||
[Description("是否硬触发模式。true:硬触发;false:软触发")]
|
||||
[DisplayName("硬触发")]
|
||||
public bool IsHardwareTrigger { get; set; } = false;
|
||||
|
||||
public string SerialNumber { get; set; } = string.Empty;
|
||||
public string CameraName { get; set; } = string.Empty;
|
||||
|
||||
public dvpStreamFormat dvpStreamFormat = dvpStreamFormat.S_RGB24;
|
||||
|
||||
[Category("采图模式")]
|
||||
[Description("是否传感器直接硬触发。true:传感器硬触发,不通过软件触发;false:通过软件触发IO 的硬触发模式")]
|
||||
[DisplayName("是否传感器直接硬触发")]
|
||||
public bool IsDirectHardwareTrigger { get; set; } = false;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 增益
|
||||
/// </summary>
|
||||
[Category("相机设置")]
|
||||
[DisplayName("增益")]
|
||||
[Description("Gain:增益,-1:不设置,不同型号相机的增益,请参考mvs")]
|
||||
public float Gain { get; set; } = -1;
|
||||
|
||||
[Category("图像旋转")]
|
||||
[Description("默认旋转,相机开启后默认不旋转")]
|
||||
[DisplayName("默认旋转")]
|
||||
public virtual float RotateImage { get; set; } = 0;
|
||||
|
||||
|
||||
|
||||
[Category("相机设置")]
|
||||
[DisplayName("硬触发后的延迟")]
|
||||
[Description("TriggerDelay:硬触发后的延迟,单位:us 微秒")]
|
||||
public float TriggerDelay { get; set; } = 0;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 滤波时间
|
||||
/// </summary>
|
||||
[Category("相机设置")]
|
||||
[DisplayName("滤波时间")]
|
||||
[Description("LineDebouncerTime:I/O去抖时间 单位:us")]
|
||||
public int LineDebouncerTime { get; set; } = 0;
|
||||
|
||||
|
||||
|
||||
public Action<DateTime, CameraBase, Mat> OnHImageOutput { get; set; }
|
||||
/// <summary>
|
||||
/// 相机连接
|
||||
/// </summary>
|
||||
/// <returns>是否成功</returns>
|
||||
public virtual bool CameraConnect() { return false; }
|
||||
|
||||
/// <summary>
|
||||
/// 相机断开
|
||||
/// </summary>
|
||||
/// <returns>是否成功</returns>
|
||||
public virtual bool CameraDisConnect() { return false; }
|
||||
|
||||
/// <summary>
|
||||
/// 抓取一张图像
|
||||
/// </summary>
|
||||
/// <returns>图像</returns>
|
||||
//internal virtual HObject GrabOneImage(string cameraName) { return null; }
|
||||
/// <summary>
|
||||
/// 设置曝光时间
|
||||
/// </summary>
|
||||
/// <param name="exposureTime">曝光时间</param>
|
||||
public virtual void SetExposure(int exposureTime, string cameraName) { }
|
||||
/// <summary>
|
||||
/// 设置增益
|
||||
/// </summary>
|
||||
/// <param name="exposure">增益</param>
|
||||
public virtual void SetGain(int gain, string cameraName) { }
|
||||
/// <summary>
|
||||
/// 设置采集模式
|
||||
/// </summary>
|
||||
/// <param name="mode">0=连续采集,即异步采集 1=单次采集,即同步采集</param>
|
||||
internal virtual void SetAcquisitionMode(int mode) { }
|
||||
/// <summary>
|
||||
/// 设置采集图像的ROI
|
||||
/// </summary>
|
||||
internal virtual void SetAcqRegion(int offsetV, int offsetH, int imageH, int imageW, string cameraName) { }
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
26
DH.Do3Think/DH.Devices.Camera.csproj
Normal file
26
DH.Do3Think/DH.Devices.Camera.csproj
Normal file
@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<BaseOutputPath>..\</BaseOutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
|
||||
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="DVPCameraCS64">
|
||||
<HintPath>..\..\pudemo\DHControlVision\libs\DVPCameraCS_Net6.0\x64\DVPCameraCS64.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
398
DH.Do3Think/Do3ThinkCamera.cs
Normal file
398
DH.Do3Think/Do3ThinkCamera.cs
Normal file
@ -0,0 +1,398 @@
|
||||
using System.Diagnostics;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Xml.Linq;
|
||||
using DVPCameraType;
|
||||
using OpenCvSharp;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
|
||||
|
||||
namespace DH.Devices.Camera
|
||||
{
|
||||
|
||||
public class Do3ThinkCamera : CameraBase
|
||||
{
|
||||
|
||||
private dvpCameraInfo stDevInfo = new dvpCameraInfo();
|
||||
private dvpStatus nRet = dvpStatus.DVP_STATUS_OK;
|
||||
private DVPCamera.dvpEventCallback pCallBackFunc;
|
||||
private uint m_handle;
|
||||
|
||||
public int m_n_dev_count = 0;
|
||||
private DVPCamera.dvpStreamCallback ImageCallback;
|
||||
public int m_CamCount = 0;
|
||||
public Double m_dfDisplayCount = 0;
|
||||
public Do3ThinkCamera()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public bool IsValidHandle(uint handle)
|
||||
{
|
||||
bool bValidHandle = false;
|
||||
dvpStatus status = DVPCamera.dvpIsValid(handle, ref bValidHandle);
|
||||
if (status == dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
return bValidHandle;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override bool CameraConnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
nRet = DVPCamera.dvpOpenByUserId(CameraName,
|
||||
dvpOpenMode.OPEN_NORMAL,
|
||||
ref m_handle);
|
||||
|
||||
// ch:打开设备 | en:Open device
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Create device failed:{nRet:x8}");
|
||||
}
|
||||
|
||||
nRet = DVPCamera.dvpSetTargetFormat(m_handle, dvpStreamFormat);
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Set image format failed:{nRet:x8}");
|
||||
}
|
||||
|
||||
dvpCameraInfo camerainfo = new dvpCameraInfo();
|
||||
nRet = DVPCamera.dvpGetCameraInfo(m_handle, ref camerainfo);
|
||||
|
||||
SerialNumber= camerainfo.SerialNumber;
|
||||
// ch:注册异常回调函数 | en:Register Exception Callback
|
||||
//nRet = DVPCamera.dvpRegisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
|
||||
//if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
//{
|
||||
// throw new Exception($"Register expection callback failed:{nRet}");
|
||||
//}
|
||||
//GC.KeepAlive(pCallBackFunc);
|
||||
|
||||
//// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
|
||||
//if (IIConfig.IsContinueMode)
|
||||
//{
|
||||
// // ch:设置触发模式为off || en:set trigger mode as off
|
||||
// nRet = DVPCamera.dvpSetTriggerState(m_handle, false);
|
||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
// {
|
||||
// throw new Exception("Set TriggerMode failed!");
|
||||
// }
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// ch:设置触发模式为on || en:set trigger mode as on
|
||||
nRet = DVPCamera.dvpSetTriggerState(m_handle, true);
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
{
|
||||
throw new Exception("Set TriggerMode failed!");
|
||||
}
|
||||
|
||||
// 硬触发
|
||||
//if (IIConfig.IsHardwareTrigger)
|
||||
//{
|
||||
// ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
|
||||
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
{
|
||||
throw new Exception("Set Line1 Trigger failed!");
|
||||
}
|
||||
|
||||
// ch:注册回调函数 | en:Register image callback
|
||||
ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc);
|
||||
nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
{
|
||||
throw new Exception("Register image callback failed!");
|
||||
}
|
||||
//}
|
||||
//else // 软触发
|
||||
//{
|
||||
// nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
|
||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
// {
|
||||
// throw new Exception("Set Software Trigger failed!");
|
||||
// }
|
||||
//}
|
||||
|
||||
// ch:开启抓图 || en: start grab image
|
||||
nRet = DVPCamera.dvpStart(m_handle);
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
{
|
||||
throw new Exception($"Start grabbing failed:{nRet:x8}");
|
||||
}
|
||||
//// 曝光
|
||||
//if (IIConfig.DefaultExposure != 0)
|
||||
//{
|
||||
// SetExposure(IIConfig.DefaultExposure);
|
||||
//}
|
||||
//// 增益
|
||||
//if (IIConfig.Gain >= 0)
|
||||
//{
|
||||
// SetGain(IIConfig.Gain);
|
||||
//}
|
||||
//SetPictureRoi(IIConfig.VelocityPara.A_Pic_X, IIConfig.VelocityPara.A_Pic_Y, IIConfig.VelocityPara.Width, IIConfig.VelocityPara.Hight);
|
||||
|
||||
//// 设置 触发延迟
|
||||
//if (IIConfig.TriggerDelay > 0)
|
||||
//{
|
||||
// nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay);
|
||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
// {
|
||||
// throw new Exception("Set TriggerDelay failed!");
|
||||
// }
|
||||
//}
|
||||
|
||||
//// 信号消抖
|
||||
//if (IIConfig.LineDebouncerTime > 0)
|
||||
//{
|
||||
// nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime);
|
||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
// {
|
||||
// throw new Exception($"LineDebouncerTime set failed:{nRet}");
|
||||
// }
|
||||
//}
|
||||
|
||||
//IIConfig.PropertyChanged -= IIConfig_PropertyChanged;
|
||||
//IIConfig.PropertyChanged += IIConfig_PropertyChanged;
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void IIConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
//if (e.PropertyName == "IsHardwareTrigger" && !IIConfig.IsContinueMode)
|
||||
//{
|
||||
// // ch:停止抓图 | en:Stop grab image
|
||||
// nRet = DVPCamera.dvpStop(m_handle);
|
||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
// {
|
||||
// throw new Exception($"Stop grabbing failed{nRet:x8}");
|
||||
// }
|
||||
|
||||
// // 硬触发
|
||||
// if (IIConfig.IsHardwareTrigger)
|
||||
// {
|
||||
// // ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
|
||||
// nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
|
||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
// {
|
||||
// throw new Exception("Set Line1 Trigger failed!");
|
||||
// }
|
||||
|
||||
// // ch:注册回调函数 | en:Register image callback
|
||||
// ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc);
|
||||
// nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
|
||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
// {
|
||||
// throw new Exception("Register image callback failed!");
|
||||
// }
|
||||
// }
|
||||
// else // 软触发
|
||||
// {
|
||||
// nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
|
||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
// {
|
||||
// throw new Exception("Set Software Trigger failed!");
|
||||
// }
|
||||
// }
|
||||
|
||||
// // ch:开启抓图 || en: start grab image
|
||||
// nRet = DVPCamera.dvpStart(m_handle);
|
||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
// {
|
||||
// throw new Exception($"Start grabbing failed:{nRet:x8}");
|
||||
// }
|
||||
// // 曝光
|
||||
// if (IIConfig.DefaultExposure != 0)
|
||||
// {
|
||||
// SetExposure(IIConfig.DefaultExposure);
|
||||
// }
|
||||
// // 增益
|
||||
// if (IIConfig.Gain >= 0)
|
||||
// {
|
||||
// SetGain(IIConfig.Gain);
|
||||
// }
|
||||
|
||||
// // 设置 触发延迟
|
||||
// if (IIConfig.TriggerDelay > 0)
|
||||
// {
|
||||
// nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay);
|
||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
// {
|
||||
// throw new Exception("Set TriggerDelay failed!");
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 信号消抖
|
||||
// if (IIConfig.LineDebouncerTime > 0)
|
||||
// {
|
||||
// nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime);
|
||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
// {
|
||||
// throw new Exception($"LineDebouncerTime set failed:{nRet}");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置曝光值
|
||||
/// </summary>
|
||||
/// <param name="exposure">曝光值</param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
private void SetExposure(double exposure)
|
||||
{
|
||||
// 关闭自动曝光
|
||||
nRet = DVPCamera.dvpSetAeOperation(m_handle, dvpAeOperation.AE_OP_OFF);
|
||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
throw new Exception($"Exposure set failed:{nRet}");
|
||||
}
|
||||
// 设置曝光值
|
||||
nRet = DVPCamera.dvpSetExposure(m_handle, exposure);
|
||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
throw new Exception($"Exposure set failed:{nRet}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置增益
|
||||
/// </summary>
|
||||
/// <param name="gain"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
private void SetGain(float gain)
|
||||
{
|
||||
// 设置增益
|
||||
nRet = DVPCamera.dvpSetAnalogGain(m_handle, gain);
|
||||
|
||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
throw new Exception($"Gain set failed:{nRet}");
|
||||
}
|
||||
}
|
||||
private void SetPictureRoi(int x, int y, int W, int H)
|
||||
{
|
||||
dvpRegion dvpR = new dvpRegion();
|
||||
|
||||
dvpR.X = x;
|
||||
dvpR.Y = y;
|
||||
dvpR.W = W;
|
||||
dvpR.H = H;
|
||||
// 设置增益
|
||||
nRet = DVPCamera.dvpSetRoi(m_handle, dvpR);
|
||||
|
||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
throw new Exception($"SetRoi set failed:{nRet}");
|
||||
}
|
||||
}
|
||||
|
||||
public int ImageCallbackFunc(uint handle, dvpStreamEvent _event, IntPtr pContext, ref dvpFrame refFrame, IntPtr pBuffer)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
Interlocked.Increment(ref SnapshotCount);
|
||||
|
||||
|
||||
int nWidth = refFrame.iWidth;
|
||||
int nHeight = refFrame.iHeight;
|
||||
Mat cvImage = new Mat();
|
||||
|
||||
// 根据图像格式创建Mat
|
||||
switch (refFrame.format)
|
||||
{
|
||||
case dvpImageFormat.FORMAT_RGB24:
|
||||
cvImage = Mat.FromPixelData(nHeight, nWidth, MatType.CV_8UC3, pBuffer);
|
||||
Cv2.CvtColor(cvImage, cvImage, ColorConversionCodes.RGB2BGR);
|
||||
break;
|
||||
|
||||
case dvpImageFormat.FORMAT_BGR24:
|
||||
cvImage = Mat.FromPixelData(nHeight, nWidth, MatType.CV_8UC3, pBuffer);
|
||||
break;
|
||||
|
||||
case dvpImageFormat.FORMAT_MONO:
|
||||
cvImage = Mat.FromPixelData(nHeight, nWidth, MatType.CV_8UC1, pBuffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported format: {refFrame.format}");
|
||||
}
|
||||
OnHImageOutput?.Invoke(DateTime.Now, this, cvImage);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool CameraDisConnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
dvpStreamState StreamState = new dvpStreamState();
|
||||
nRet = DVPCamera.dvpGetStreamState(m_handle, ref StreamState);
|
||||
Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK);
|
||||
if (StreamState == dvpStreamState.STATE_STARTED)
|
||||
{
|
||||
// stop camera
|
||||
nRet = DVPCamera.dvpStop(m_handle);
|
||||
Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK);
|
||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
throw new Exception($"Stop grabbing failed{nRet:x8}");
|
||||
}
|
||||
}
|
||||
|
||||
nRet = DVPCamera.dvpUnregisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
|
||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
throw new Exception($"Unregister expection callback failed:{nRet}");
|
||||
}
|
||||
|
||||
// ch:关闭设备 | en:Close device
|
||||
nRet = DVPCamera.dvpClose(m_handle);
|
||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
throw new Exception($"Close device failed{nRet:x8}");
|
||||
}
|
||||
|
||||
m_handle = 0;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user