using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using OpenCvSharp;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Text;
namespace LB_VisionProcesses.Cameras
{
[Process("相机取图", Category = "取像工具", Description = "创建相机取图工具")]
public class CameraConfig : IProcess
{
///
/// 相机集合(Key:相机SN,Value:相机句柄)
///
public ConcurrentDictionary dicCameras { get; set; }
public BaseCamera Camera { get; set; }
public CameraConfig(ConcurrentDictionary dicCameras = null)
{
this.dicCameras = dicCameras;
strProcessName = "相机取图";
strProcessClass = "LB_VisionProcesses.CameraConfig.CommunicatorConfig";
Params.Inputs.Add("相机SN", "");
Params.Inputs.Add("触发模式", TriggerMode.On);
Params.Inputs.Add("触发方式", TriggerSource.Software);
Params.Inputs.Add("触发极性", TriggerPolarity.RisingEdge);
Params.Inputs.Add("触发消抖", 0);
Params.Inputs.Add("触发延时", 0);
Params.Inputs.Add("曝光时间", 1000);
Params.Inputs.Add("增益", 1);
Params.Inputs.Add("是否每次写入参数", false);
Params.Inputs.Add("是否本地取图", false);
Params.Inputs.Add("本地取图路径", "");
Params.Inputs.Add("本地取图序号", 0);
Params.Inputs.Add("超时时间", 1000);
Params.Inputs.Add("是否失败重新取图", false);
}
///
/// 加载算法
///
/// 完整路径带.json
///
public override bool Load(string fullPath = null)
{
try
{
if (string.IsNullOrEmpty(fullPath))
return false;
if (!fullPath.Contains(".json"))
{
Debug.WriteLine("文件路径不完整");
return false;
}
if (string.IsNullOrEmpty(fullPath) || fullPath.Trim() == "")
{
Debug.WriteLine("文件路径不完整");
return false;
}
// 获取不带文件名的目录路径
string directoryPath = Path.GetDirectoryName(fullPath);
strProcessName = Path.GetFileNameWithoutExtension(fullPath);
if (!File.Exists(fullPath))
{
Debug.WriteLine("文件不存在创建空文件");
Save(directoryPath);
return true;
}
string strJson = string.Empty;
using (StreamReader streamReader = new StreamReader(fullPath, Encoding.UTF8))
{
strJson = streamReader.ReadToEnd();
streamReader.Close();
}
Params = JsonConvert.DeserializeObject(strJson);
if (Params == null)
return false;
Params.FixDeserializedData();
#region 加载后把参数写入到相机中
bool isLocal = Convert.ToBoolean(Params.Inputs["是否本地取图"].ToString());
if (!isLocal)
{
string SN = Params.Inputs["相机SN"].ToString();
if (dicCameras == null || !dicCameras.ContainsKey(SN))
return false;
BaseCamera BaseCamera = dicCameras[SN];
if (BaseCamera == null)
return false;
if (!BaseCamera.isGrabbing)
{
if (!BaseCamera.StartGrabbing())
return false;
}
BaseCamera.SetCamConfig(this);
}
#endregion
return true;
}
catch { return false; }
}
///
/// 保存算法
///
/// 不带.json
///
public override bool Save(string filePath = null)
{
try
{
if (string.IsNullOrEmpty(filePath) || filePath.Trim() == "")
{
Debug.WriteLine("文件路径不完整");
return false;
}
string strJson = string.Empty;
var settings = new JsonSerializerSettings
{
Formatting = Newtonsoft.Json.Formatting.Indented,
// 自定义缩进(4空格)
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
}
};
strJson = JsonConvert.SerializeObject(Params, settings);
Params = JsonConvert.DeserializeObject(strJson);
if (Params == null)
return false;
//判断文件夹是否存在,防呆输入为文件名称
if (!Directory.Exists(filePath))
{
try
{
Directory.CreateDirectory(filePath);
}
catch (Exception)
{ }
}
File.WriteAllText(filePath + "//" + strProcessName + ".json", strJson, Encoding.UTF8);
return true;
}
catch { return false; }
}
public override bool Run()
{
DateTime StartTime = DateTime.Now;
try
{
InitRunParams();
string SN = string.Empty;
bool isLocal = Convert.ToBoolean(Params.Inputs["是否本地取图"]?.ToString());
bool isUpParams = Convert.ToBoolean(Params.Inputs["是否每次写入参数"]?.ToString());
bool isRegrab = Convert.ToBoolean(Params.Inputs["是否失败重新取图"]?.ToString());
int timeout = Convert.ToInt16(Params.Inputs["超时时间"]?.ToString());
if (isLocal)
{
if (Params.Inputs["本地取图路径"] is List)
{
List lstPaths = Params.Inputs["本地取图路径"] as List;
if (lstPaths != null && int.TryParse(Params.Inputs["本地取图序号"]?.ToString(), out int indexPath)
&& lstPaths.Count > indexPath)
{
SN = lstPaths[indexPath];
if (lstPaths.Count > indexPath + 1)
Params.Inputs["本地取图序号"] = indexPath + 1;
else
Params.Inputs["本地取图序号"] = 0;
Mat src = Cv2.ImRead(SN);
if (src != null && !src.Empty())
OutputImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(src);
}
}
}
else
{
SN = Params.Inputs["相机SN"].ToString();
if (dicCameras == null || !dicCameras.ContainsKey(SN))
{
Msg = $"相机[{SN}]不存在";
Result = false;
RunTime = (DateTime.Now - StartTime).TotalMilliseconds;
return Result;
}
if (Camera == null || Camera.SN != SN)
{
if (dicCameras.ContainsKey(SN))
Camera = dicCameras[SN];
else
Camera = null;
}
if (Camera == null)
{
Msg = $"相机[{SN}]未实例化";
Result = false;
RunTime = (DateTime.Now - StartTime).TotalMilliseconds;
return Result;
}
CameraConfig oriConfig = new CameraConfig();
if (isUpParams)
{
Camera.GetCamConfig(out oriConfig);
Camera.SetCamConfig(this);
}
if (!Enum.TryParse(Params.Inputs["触发方式"].ToString(), out TriggerSource TriggerSource))
{
Msg = $"相机[{SN}]设置的触发方式不正确,值为:{Params.Inputs["触发方式"].ToString()}";
Result = false;
RunTime = (DateTime.Now - StartTime).TotalMilliseconds;
return Result;
}
Bitmap bitmap = null;
int times = 5;
do
{
times--;
if (TriggerSource == TriggerSource.Software)
Camera.GetImageWithSoftTrigger(out bitmap, timeout);
else
Camera.GetImage(out bitmap, timeout);
if (bitmap != null)
break;
else if (isRegrab)
{
Debug.WriteLine($"取图失败,重新取图,剩余次数:{times}");
}
} while (times > 0 && isRegrab);
if (isUpParams)
Camera.SetCamConfig(oriConfig);
OutputImage = bitmap;
}
if (OutputImage == null)
{
Msg = $"相机[{SN}]获取图像失败";
Result = false;
}
}
catch (Exception ex)
{
Msg = ex.Message;
Result = false;
}
RunTime = (DateTime.Now - StartTime).TotalMilliseconds;
return Result;
}
public override void InitRunParams()
{
Result = true;
Msg = "";
OutputImage = null;
if (Record != null)
Record.Dispose();
}
public override void Dispose()
{
return;
}
public override object Clone()
{
try
{
var obj = (CameraConfig)MemberwiseClone(); // 浅拷贝
// 手动处理引用类型
if (OutputImage != null)
{
if (OutputImage is Bitmap)
obj.OutputImage = ((Bitmap)OutputImage).Clone();
}
return obj;
}
catch { return (CameraConfig)MemberwiseClone(); }
}
}
}