Compare commits
2 Commits
e7736217db
...
a9d02a5a9d
Author | SHA1 | Date | |
---|---|---|---|
a9d02a5a9d | |||
|
b8c83e459d |
@ -5,6 +5,26 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Platforms>AnyCPU;X64</Platforms>
|
<Platforms>AnyCPU;X64</Platforms>
|
||||||
|
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Helper\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="halcondotnet">
|
||||||
|
<HintPath>..\x64\Debug\halcondotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="hdevenginedotnet">
|
||||||
|
<HintPath>..\x64\Debug\hdevenginedotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
39
DH.Commons/GlobalVar.cs
Normal file
39
DH.Commons/GlobalVar.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
|
||||||
|
namespace XKRS.Common.Model
|
||||||
|
{
|
||||||
|
public static class GlobalVar
|
||||||
|
{
|
||||||
|
|
||||||
|
//public const string SEPERATOR = "|";
|
||||||
|
|
||||||
|
//public static ContainerBuilder Builder { get; set; } = new ContainerBuilder();
|
||||||
|
|
||||||
|
//private static object containerLock = new object();
|
||||||
|
|
||||||
|
//private static IContainer container = null;
|
||||||
|
//public static IContainer Container
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// if (container == null)
|
||||||
|
// {
|
||||||
|
// lock (containerLock)
|
||||||
|
// {
|
||||||
|
// if (container == null)
|
||||||
|
// {
|
||||||
|
// container = Builder.Build();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return container;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public static void InitialAutoFac()
|
||||||
|
//{
|
||||||
|
// Container = Builder.Build();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
677
DH.Commons/Helper/HDevEngineTool.cs
Normal file
677
DH.Commons/Helper/HDevEngineTool.cs
Normal file
@ -0,0 +1,677 @@
|
|||||||
|
using HalconDotNet;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace XKRS.Common.Model
|
||||||
|
{
|
||||||
|
public class HDevEngineTool : IDisposable
|
||||||
|
{
|
||||||
|
#region 常量
|
||||||
|
|
||||||
|
// path of external procedures
|
||||||
|
readonly string ProcedurePath = Environment.CurrentDirectory + "\\Vision\\";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 成员变量
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理过程名
|
||||||
|
/// </summary>
|
||||||
|
public string ProcedureName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// hdev程序启动引擎
|
||||||
|
/// </summary>
|
||||||
|
private readonly HDevEngine myEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 过程载入工具 .hdvp
|
||||||
|
/// </summary>
|
||||||
|
private HDevProcedureCall procedureCall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 程序运行是否成功
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSuccessful { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 控制参数字典
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, HTuple> InputTupleDic { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 图形参数字典
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, HObject> InputImageDic { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 初始化
|
||||||
|
/// <summary>
|
||||||
|
/// 实例化 默认搜索路径为: 启动路径//Vision//
|
||||||
|
/// </summary>
|
||||||
|
public HDevEngineTool()
|
||||||
|
{
|
||||||
|
ProcedureName = "";
|
||||||
|
myEngine = new HDevEngine();
|
||||||
|
myEngine.SetProcedurePath(ProcedurePath);
|
||||||
|
|
||||||
|
InputImageDic = new Dictionary<string, HObject>();
|
||||||
|
InputTupleDic = new Dictionary<string, HTuple>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实例化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">外部函数搜索路径</param>
|
||||||
|
public HDevEngineTool(string path)
|
||||||
|
{
|
||||||
|
myEngine = new HDevEngine();
|
||||||
|
myEngine.SetProcedurePath(path);
|
||||||
|
|
||||||
|
InputImageDic = new Dictionary<string, HObject>();
|
||||||
|
InputTupleDic = new Dictionary<string, HTuple>();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置函数运行所需参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_tupleDictionary">控制参数</param>
|
||||||
|
/// <param name="_imageDictionary">图形参数</param>
|
||||||
|
public void SetDictionary(Dictionary<string, HTuple> _tupleDictionary, Dictionary<string, HObject> _imageDictionary)
|
||||||
|
{
|
||||||
|
InputTupleDic = _tupleDictionary;
|
||||||
|
InputImageDic = _imageDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 载入过程 .hdvp
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="procedureName">过程名</param>
|
||||||
|
public void LoadProcedure(string procedureName)
|
||||||
|
{
|
||||||
|
ProcedureName = procedureName;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HDevProcedure procedure = new HDevProcedure(procedureName);
|
||||||
|
procedureCall = new HDevProcedureCall(procedure);
|
||||||
|
}
|
||||||
|
catch (HDevEngineException Ex)
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("HDevProgram {0} Load fail ,Error Line : {1}, Line number: {2}, Halcon error number : {3}", Ex.ProcedureName, Ex.LineText, Ex.LineNumber, Ex.HalconError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行过程
|
||||||
|
/// </summary>
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
public bool RunProcedure(out string errorMsg, out int timeElasped)
|
||||||
|
{
|
||||||
|
//lock (_runLock)
|
||||||
|
{
|
||||||
|
errorMsg = "";
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, HTuple> pair in InputTupleDic)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputCtrlParamTuple(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, HObject> pair in InputImageDic)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputIconicParamObject(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
procedureCall.Execute();
|
||||||
|
|
||||||
|
IsSuccessful = true;
|
||||||
|
}
|
||||||
|
catch (HDevEngineException ex)
|
||||||
|
{
|
||||||
|
IsSuccessful = false;
|
||||||
|
errorMsg = $"HDevProgram {ex.ProcedureName} Run fail , Line number: {ex.LineNumber}, Halcon error number : {ex.HalconError},ex:{ex.Message}";
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sw.Stop();
|
||||||
|
timeElasped = (int)sw.ElapsedMilliseconds;
|
||||||
|
}
|
||||||
|
return IsSuccessful;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object _runLock = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// 执行过程
|
||||||
|
/// </summary>
|
||||||
|
public Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> RunProcedure(Dictionary<string, HTuple> inputHTupleDict, Dictionary<string, HObject> inputImgDict, List<string> outputHTuples = null, List<string> outputObjs = null)
|
||||||
|
{
|
||||||
|
lock (_runLock)
|
||||||
|
{
|
||||||
|
string errorMsg = "";
|
||||||
|
int timeElasped = 0;
|
||||||
|
bool result = false;
|
||||||
|
Dictionary<string, HTuple> outputHTupleDict = new Dictionary<string, HTuple>();
|
||||||
|
Dictionary<string, HObject> outputObjDict = new Dictionary<string, HObject>();
|
||||||
|
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (inputHTupleDict != null && inputHTupleDict.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, HTuple> pair in inputHTupleDict)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputCtrlParamTuple(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InputImageDic != null && inputImgDict.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, HObject> pair in inputImgDict)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputIconicParamObject(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
procedureCall.Execute();
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
catch (HDevEngineException ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
errorMsg += $"HDevProgram {ex.ProcedureName} Run fail , Line number: {ex.LineNumber}, Halcon error number : {ex.HalconError},ex:{ex.Message}";
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sw.Stop();
|
||||||
|
timeElasped = (int)sw.ElapsedMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
if (outputHTuples != null && outputHTuples.Count > 0)
|
||||||
|
{
|
||||||
|
outputHTuples.ForEach(t =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
outputHTupleDict[t] = procedureCall.GetOutputCtrlParamTuple(t);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
errorMsg += $"\r\n获取{t}结果异常:{ex.Message}";
|
||||||
|
|
||||||
|
outputHTupleDict[t] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputObjs != null && outputObjs.Count > 0)
|
||||||
|
{
|
||||||
|
outputObjs.ForEach(t =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
outputObjDict[t] = procedureCall.GetOutputIconicParamObject(t);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
errorMsg += $"\r\n获取{t}结果异常:{ex.Message}";
|
||||||
|
|
||||||
|
outputObjDict[t] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = new Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int>(result, outputHTupleDict, outputObjDict, errorMsg, timeElasped);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HTuple GetResultTuple(string key)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (IsSuccessful)
|
||||||
|
{
|
||||||
|
return procedureCall.GetOutputCtrlParamTuple(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new HTuple();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new HTuple();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public HObject GetResultObject(string key, bool ignoreError = false)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (ignoreError || IsSuccessful)
|
||||||
|
{
|
||||||
|
return procedureCall.GetOutputIconicParamObject(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new HObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new HObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
procedureCall?.Dispose();
|
||||||
|
myEngine?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HalconHelper
|
||||||
|
{
|
||||||
|
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
|
||||||
|
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
|
||||||
|
|
||||||
|
public static HImage Convert8GrayBitmapToHImage(this Bitmap bmp)
|
||||||
|
{
|
||||||
|
HImage himage = new HImage();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//判断输入图像不为null
|
||||||
|
if (bmp == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//重绘himage
|
||||||
|
//HImage curImage = new HImage();
|
||||||
|
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
|
||||||
|
himage.GenImage1("byte", bmp.Width, bmp.Height, bmpData.Scan0);
|
||||||
|
bmp.UnlockBits(bmpData);
|
||||||
|
//himage = curImage;
|
||||||
|
}
|
||||||
|
return himage;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 HObject2BitmapRGB(this HObject hObject)
|
||||||
|
{
|
||||||
|
////获取图像尺寸
|
||||||
|
HTuple width0, height0, type, width, height;
|
||||||
|
//获取图像尺寸
|
||||||
|
HOperatorSet.GetImageSize(hObject, out width0, out height0);
|
||||||
|
// 创建交错格式图像
|
||||||
|
HOperatorSet.InterleaveChannels(hObject, out HObject InterImage, "argb", "match", 255); //"rgb", 4 * width0, 0 "argb", "match", 255
|
||||||
|
|
||||||
|
//获取交错格式图像指针
|
||||||
|
HOperatorSet.GetImagePointer1(InterImage, out HTuple Pointer, out type, out width, out height);
|
||||||
|
IntPtr ptr = Pointer;
|
||||||
|
//构建新Bitmap图像
|
||||||
|
Bitmap res32 = new Bitmap(width / 4, height, width, PixelFormat.Format32bppArgb, ptr); // Format32bppArgb Format24bppRgb
|
||||||
|
|
||||||
|
//32位Bitmap转24位
|
||||||
|
var res24 = new Bitmap(res32.Width, res32.Height, PixelFormat.Format24bppRgb);
|
||||||
|
Graphics graphics = Graphics.FromImage(res24);
|
||||||
|
graphics.DrawImage(res32, new Rectangle(0, 0, res32.Width, res32.Height));
|
||||||
|
|
||||||
|
return res24;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 static Bitmap ConvertHImageTo16GrayBitmap(this HImage originHImage)
|
||||||
|
{
|
||||||
|
//IntPtr pointer = hImage.GetImagePointer1(out string type, out int width, out int height);
|
||||||
|
|
||||||
|
//int widthIn4 = (int)Math.Ceiling(width / 4.0) * 4;
|
||||||
|
|
||||||
|
////Bitmap bmp = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb);
|
||||||
|
//Bitmap showImage = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb);
|
||||||
|
|
||||||
|
//Rectangle rect = new Rectangle(0, 0, widthIn4, height);
|
||||||
|
////BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb);
|
||||||
|
//BitmapData showImageData = showImage.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb);
|
||||||
|
//unsafe
|
||||||
|
//{
|
||||||
|
// byte* data = (byte*)pointer;
|
||||||
|
// //byte* bitmapBuffer = (byte*)bitmapData.Scan0;
|
||||||
|
// byte* showBitmapBuffer = (byte*)showImageData.Scan0;
|
||||||
|
|
||||||
|
// Parallel.For(0, width * height, i =>
|
||||||
|
// {
|
||||||
|
// int index = (i + 1) % width + widthIn4 * ((int)Math.Floor((double)(i + 1) / width)) - 1;
|
||||||
|
|
||||||
|
// //showBitmapBuffer[index * 6] = bitmapBuffer[index * 6] = data[i * 2];
|
||||||
|
// //showBitmapBuffer[index * 6 + 1] = bitmapBuffer[index * 6 + 1] = data[i * 2 + 1];
|
||||||
|
// showBitmapBuffer[index * 6] = data[i * 2];
|
||||||
|
// showBitmapBuffer[index * 6 + 1] = data[i * 2 + 1];
|
||||||
|
// });
|
||||||
|
//}
|
||||||
|
|
||||||
|
////bmp.UnlockBits(bitmapData);
|
||||||
|
//showImage.UnlockBits(showImageData);
|
||||||
|
|
||||||
|
//return showImage;
|
||||||
|
|
||||||
|
// dev_set_draw('margin')
|
||||||
|
//read_image(Image, '0.tif')
|
||||||
|
|
||||||
|
HImage hImage = originHImage.Clone();
|
||||||
|
|
||||||
|
//* 如果16位图像非常暗的话,建议在这一步进行提亮,因为后面8位图像大幅度提亮易造成色阶断裂,出现不连续的像素块
|
||||||
|
// * scale_image(Image, Image, 25, 0)
|
||||||
|
//hImage = hImage.ScaleImage(25.0, 0.0);
|
||||||
|
|
||||||
|
//get_domain(Image, rectangle)
|
||||||
|
//* 获取全图中像素灰度值的最大和最小值
|
||||||
|
//min_max_gray(rectangle, Image, 0, Min, Max, range)
|
||||||
|
hImage.MinMaxGray(hImage.GetDomain(), 0, out double min, out double max, out double range);
|
||||||
|
|
||||||
|
//* 将16位图的灰度值映射到0 - 255上
|
||||||
|
double mult = 255.0 / (max - min);
|
||||||
|
double add = -mult * min;
|
||||||
|
hImage = hImage.ScaleImage(mult, add);
|
||||||
|
|
||||||
|
//* 转换为'byte'类型
|
||||||
|
//convert_image_type(Image_scaled, ImageConverted, 'byte')
|
||||||
|
hImage = hImage.ConvertImageType("byte");
|
||||||
|
|
||||||
|
Bitmap showImage = hImage.ConvertHImageTo8GrayBitmap();
|
||||||
|
|
||||||
|
hImage.Dispose();
|
||||||
|
|
||||||
|
return showImage;
|
||||||
|
|
||||||
|
//* 如果转换以后图像整体对比度太低的话,可以提高对比度(这里是对8位图像处理)
|
||||||
|
//Min:= 20
|
||||||
|
//Max:= 160
|
||||||
|
//Mult:= 255.0 / (Max - Min)
|
||||||
|
//Add:= -Mult * Min
|
||||||
|
//scale_image(ImageConverted, ImageConverted_scaled, Mult, Add)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<double> HTupleToDouble(this HTuple tuple)
|
||||||
|
{
|
||||||
|
List<double> list = new List<double>();
|
||||||
|
|
||||||
|
for (int i = 0; i < tuple.Length; i++)
|
||||||
|
{
|
||||||
|
list.Add(tuple[i].D);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static HImage ConvertHObjectToHImage(this HObject obj)
|
||||||
|
{
|
||||||
|
HOperatorSet.CountChannels(obj, out HTuple channels);
|
||||||
|
|
||||||
|
HImage img = new HImage();
|
||||||
|
if (channels.I == 1)
|
||||||
|
{
|
||||||
|
HTuple pointer, type, width, height;
|
||||||
|
HOperatorSet.GetImagePointer1(obj, out pointer, out type, out width, out height);
|
||||||
|
|
||||||
|
img.GenImage1(type, width, height, pointer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HTuple pRed, pGreen, pBlue, type, width, height;
|
||||||
|
HOperatorSet.GetImagePointer3(obj, out pRed, out pGreen, out pBlue, out type, out width, out height);
|
||||||
|
|
||||||
|
img.GenImage3(type, width, height, pRed, pGreen, pBlue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 灰度图转换为伪彩图
|
||||||
|
public static Bitmap ConvertGrayImageToPesudoColorfulImage(this HImage hImage, double max = 0, double min = 0, double zoom = 1, bool isShowHeightTip = false, int zResolution = 100000)
|
||||||
|
{
|
||||||
|
hImage.GetImageSize(out int width, out int height);
|
||||||
|
hImage.MinMaxGray(new HRegion(0.0, 0.0, width, height), 3, out HTuple roiMin, out HTuple roiMax, out _);
|
||||||
|
|
||||||
|
if (max == 0)
|
||||||
|
{
|
||||||
|
max = roiMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min == 0)
|
||||||
|
{
|
||||||
|
min = roiMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mult = 235 / (zoom * (max - min));
|
||||||
|
double add = (0 - mult) * min * zoom + 10;
|
||||||
|
HOperatorSet.ScaleImage(hImage, out HObject imageScaled, mult, add);
|
||||||
|
HOperatorSet.ConvertImageType(imageScaled, out imageScaled, "byte");
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
|
HOperatorSet.GetImagePointer1(imageScaled, out HTuple pointer, out HTuple type, out _, out _);
|
||||||
|
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
|
||||||
|
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
byte* data = (byte*)(IntPtr)pointer;
|
||||||
|
byte* bitmapDataBuff = (byte*)bitmapData.Scan0;
|
||||||
|
|
||||||
|
if (width % 4 != 0)
|
||||||
|
{
|
||||||
|
Parallel.For(0, height, h =>
|
||||||
|
{
|
||||||
|
Parallel.For(0, width, w =>
|
||||||
|
{
|
||||||
|
byte gray = data[h * width + w];
|
||||||
|
byte[] convertBytes = ConvertByteToColorfulArray(gray);
|
||||||
|
|
||||||
|
Marshal.Copy(convertBytes, 0, (IntPtr)(bitmapDataBuff + h * bitmapData.Stride + w * 3), 3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Parallel.For(0, width * height, i =>
|
||||||
|
{
|
||||||
|
byte gray = data[i];
|
||||||
|
byte[] convertBytes = ConvertByteToColorfulArray(gray);
|
||||||
|
|
||||||
|
Marshal.Copy(convertBytes, 0, (IntPtr)(bitmapDataBuff + i * 3), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bitmap.UnlockBits(bitmapData);
|
||||||
|
|
||||||
|
if (isShowHeightTip)
|
||||||
|
{
|
||||||
|
List<byte> lableList = new List<byte>() { 5, 30, 60, 90, 120, 150, 180, 210, 240, 255 };
|
||||||
|
Dictionary<double, Color> lableColorDict = lableList.ToDictionary(
|
||||||
|
u => (u - add) / (mult * zResolution),
|
||||||
|
u =>
|
||||||
|
{
|
||||||
|
byte[] colorBytes = ConvertByteToColorfulArray(u);
|
||||||
|
return Color.FromArgb(colorBytes[2], colorBytes[1], colorBytes[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
using (Graphics g = Graphics.FromImage(bitmap))
|
||||||
|
{
|
||||||
|
int rectHeight = (int)(bitmap.Height / (5.0 * lableColorDict.Count));
|
||||||
|
Font font = new Font("宋体", (int)(rectHeight * 0.75), GraphicsUnit.Pixel);
|
||||||
|
|
||||||
|
string lable = lableColorDict.ElementAt(0).Key.ToString("f3");
|
||||||
|
SizeF lableSize = g.MeasureString(lable, font);
|
||||||
|
int rectWidth = (int)(lableSize.Width * 1.5);
|
||||||
|
|
||||||
|
int startX = 0;
|
||||||
|
int startY = 0;
|
||||||
|
foreach (KeyValuePair<double, Color> pair in lableColorDict)
|
||||||
|
{
|
||||||
|
g.FillRectangle(new SolidBrush(pair.Value), startX, startY, rectWidth, rectHeight);
|
||||||
|
g.DrawString(pair.Key.ToString("f3"), font, new SolidBrush(Color.White), (float)(startX + (rectWidth - lableSize.Width) / 2.0), (float)(startY + (rectHeight - lableSize.Height) / 2.0));
|
||||||
|
|
||||||
|
startY += rectHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
//LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"转换耗时{sw.ElapsedMilliseconds}ms");
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] ConvertByteToColorfulArray(byte gray)
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[3];
|
||||||
|
if (gray == 0)
|
||||||
|
{
|
||||||
|
bytes[2] = 255;
|
||||||
|
bytes[1] = 255;
|
||||||
|
bytes[0] = 255;
|
||||||
|
}
|
||||||
|
if (gray > 0 && gray <= 63)
|
||||||
|
{
|
||||||
|
bytes[2] = 0;
|
||||||
|
bytes[+1] = (byte)(254 - 4 * gray);
|
||||||
|
bytes[0] = 255;
|
||||||
|
}
|
||||||
|
if (gray >= 64 && gray <= 127)
|
||||||
|
{
|
||||||
|
bytes[2] = 0;
|
||||||
|
bytes[1] = (byte)(4 * gray - 254);
|
||||||
|
bytes[0] = (byte)(510 - 4 * gray);
|
||||||
|
}
|
||||||
|
if (gray >= 128 && gray <= 191)
|
||||||
|
{
|
||||||
|
bytes[2] = (byte)(4 * gray - 510);
|
||||||
|
bytes[1] = 255;
|
||||||
|
bytes[0] = 0;
|
||||||
|
}
|
||||||
|
if (gray >= 192 && gray <= 255)
|
||||||
|
{
|
||||||
|
bytes[2] = 255;
|
||||||
|
bytes[1] = (byte)(1022 - 4 * gray);
|
||||||
|
bytes[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
724
DH.Commons/Helper/OpenCVEngineTool.cs
Normal file
724
DH.Commons/Helper/OpenCVEngineTool.cs
Normal file
@ -0,0 +1,724 @@
|
|||||||
|
using HalconDotNet;
|
||||||
|
using OpenCvSharp;
|
||||||
|
using OpenCvSharp.Extensions;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace XKRS.Common.Model
|
||||||
|
{
|
||||||
|
public class OpenCVEngineTool : IDisposable
|
||||||
|
{
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class OpenCVHelper
|
||||||
|
{
|
||||||
|
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
|
||||||
|
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
|
||||||
|
|
||||||
|
|
||||||
|
public static byte[] MatToBytes(this Mat image)
|
||||||
|
{
|
||||||
|
if (image != null && image.Data != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
int size = (int)(image.Total() * image.ElemSize());
|
||||||
|
byte[] bytes = new byte[size];
|
||||||
|
Marshal.Copy(image.Data, bytes, 0, size);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取水平拼接图片
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="map1"></param>
|
||||||
|
/// <param name="map2"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Bitmap GetHConcatImage(Bitmap map1, Bitmap map2)
|
||||||
|
{
|
||||||
|
var mat1 = map1.ToMat();
|
||||||
|
var mat2 = map2.ToMat();
|
||||||
|
//var maxChannel = Math.Max(mat1.Channels(), mat2.Channels());
|
||||||
|
//var maxType = Math.Max(mat1.Type(), mat2.Type());
|
||||||
|
|
||||||
|
//转通道数
|
||||||
|
mat1 = mat1.CvtColor(ColorConversionCodes.GRAY2BGRA);
|
||||||
|
//转位深
|
||||||
|
mat1.ConvertTo(mat1, mat2.Type());
|
||||||
|
Mat resMat = new Mat(mat1.Height, mat1.Width, mat2.Type(), new Scalar(0));
|
||||||
|
Cv2.HConcat(mat1, mat2, resMat);
|
||||||
|
mat1.Dispose();
|
||||||
|
mat2.Dispose();
|
||||||
|
return resMat.ToBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat To3Channels(this Mat img)
|
||||||
|
{
|
||||||
|
if (img == null)
|
||||||
|
return null;
|
||||||
|
Mat resMat = new Mat(img.Rows, img.Cols, MatType.CV_8UC3);
|
||||||
|
Mat[] channels = new Mat[3]; ;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
channels[i] = img;
|
||||||
|
}
|
||||||
|
Cv2.Merge(channels, resMat);
|
||||||
|
img.Dispose();
|
||||||
|
img = null;
|
||||||
|
return resMat;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 把OpenCV图像转换到Halcon图像
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mImage">OpenCV图像_Mat</param>
|
||||||
|
/// <returns>Halcon图像_HObject</returns>
|
||||||
|
public static HObject MatToHImage(Mat mImage)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HObject hImage;
|
||||||
|
int matChannels = 0; // 通道数
|
||||||
|
Type matType = null;
|
||||||
|
uint width, height; // 宽,高
|
||||||
|
width = height = 0; // 宽,高初始化
|
||||||
|
|
||||||
|
// 获取通道数
|
||||||
|
matChannels = mImage.Channels();
|
||||||
|
if (matChannels == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (matChannels == 1) // 单通道
|
||||||
|
//if (true) // 单通道
|
||||||
|
{
|
||||||
|
IntPtr ptr; // 灰度图通道
|
||||||
|
Mat[] mats = mImage.Split();
|
||||||
|
|
||||||
|
// 改自:Mat.GetImagePointer1(mImage, out ptr, out matType, out width, out height); // ptr=2157902018096 cType=byte width=830 height=822
|
||||||
|
ptr = mats[0].Data; // 取灰度图值
|
||||||
|
matType = mImage.GetType(); // byte
|
||||||
|
height = (uint)mImage.Rows; // 高
|
||||||
|
width = (uint)mImage.Cols; // 宽
|
||||||
|
|
||||||
|
// 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, newScalar(0));
|
||||||
|
byte[] dataGrayScaleImage = new byte[width * height]; //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (byte* ptrdata = dataGrayScaleImage)
|
||||||
|
{
|
||||||
|
|
||||||
|
#region 按行复制
|
||||||
|
//for (int i = 0; i < height; i++)
|
||||||
|
//{
|
||||||
|
// CopyMemory((IntPtr)(ptrdata + width * i), new IntPtr((long)ptr + width *i), width);
|
||||||
|
//}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
CopyMemory((IntPtr)ptrdata, new IntPtr((long)ptr), width * height);
|
||||||
|
HOperatorSet.GenImage1(out hImage, "byte", width, height, (IntPtr)ptrdata);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hImage;
|
||||||
|
}
|
||||||
|
else if (matChannels == 3) // 三通道
|
||||||
|
{
|
||||||
|
IntPtr ptrRed; // R通道图
|
||||||
|
IntPtr ptrGreen; // G通道图
|
||||||
|
IntPtr ptrBlue; // B通道图
|
||||||
|
Mat[] mats = mImage.Split();
|
||||||
|
|
||||||
|
ptrRed = mats[0].Data; // 取R通道值
|
||||||
|
ptrGreen = mats[1].Data; // 取G通道值
|
||||||
|
ptrBlue = mats[2].Data; // 取B通道值
|
||||||
|
matType = mImage.GetType(); // 类型
|
||||||
|
height = (uint)mImage.Rows; // 高
|
||||||
|
width = (uint)mImage.Cols; // 宽
|
||||||
|
|
||||||
|
// 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));
|
||||||
|
byte[] dataRed = new byte[width * height]; //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
byte[] dataGreen = new byte[width * height];
|
||||||
|
byte[] dataBlue = new byte[width * height];
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (byte* ptrdataRed = dataRed, ptrdataGreen = dataGreen, ptrdataBlue = dataBlue)
|
||||||
|
{
|
||||||
|
|
||||||
|
#region 按行复制
|
||||||
|
//HImage himg = new HImage("byte", width, height, (IntPtr)ptrdataRed);
|
||||||
|
//for (int i = 0; i < height; i++)
|
||||||
|
//{
|
||||||
|
// CopyMemory((IntPtr)(ptrdataRed + width * i), new IntPtr((long)ptrRed +width * i), width);
|
||||||
|
// CopyMemory((IntPtr)(ptrdataGreen + width * i), new IntPtr((long)ptrGreen+ width * i), width);
|
||||||
|
// CopyMemory((IntPtr)(ptrdataBlue + width * i), new IntPtr((long)ptrBlue +width * i), width);
|
||||||
|
//}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
CopyMemory((IntPtr)ptrdataRed, new IntPtr((long)ptrRed), width* height); // 复制R通道
|
||||||
|
CopyMemory((IntPtr)ptrdataGreen, new IntPtr((long)ptrGreen), width * height); // 复制G通道
|
||||||
|
CopyMemory((IntPtr)ptrdataBlue, new IntPtr((long)ptrBlue), width * height); // 复制B通道
|
||||||
|
HOperatorSet.GenImage3(out hImage, "byte", width, height, (IntPtr)ptrdataRed, (IntPtr)ptrdataGreen, (IntPtr)ptrdataBlue); // 合成
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hImage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Mat HImageToMat(this HObject hobj)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Mat mImage;
|
||||||
|
HTuple htChannels;
|
||||||
|
HTuple cType = null;
|
||||||
|
HTuple width, height;
|
||||||
|
width = height = 0;
|
||||||
|
|
||||||
|
HOperatorSet.CountChannels(hobj, out htChannels);
|
||||||
|
|
||||||
|
if (htChannels.Length == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (htChannels[0].I == 1)
|
||||||
|
{
|
||||||
|
HTuple ptr;
|
||||||
|
HOperatorSet.GetImagePointer1(hobj, out ptr, out cType, out width, out height);
|
||||||
|
mImage = new Mat(height, width, MatType.CV_8UC1, new Scalar(0));
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
CopyMemory(mImage.Data, new IntPtr((byte*)ptr.IP), (uint)(width * height));// CopyMemory(要复制到的地址,复制源的地址,复制的长度)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mImage;
|
||||||
|
}
|
||||||
|
else if (htChannels[0].I == 3)
|
||||||
|
{
|
||||||
|
HTuple ptrRed;
|
||||||
|
HTuple ptrGreen;
|
||||||
|
HTuple ptrBlue;
|
||||||
|
|
||||||
|
HOperatorSet.GetImagePointer3(hobj, out ptrRed, out ptrGreen, out ptrBlue, out cType, out width, out height);
|
||||||
|
Mat pImageRed = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
Mat pImageGreen = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
Mat pImageBlue = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
mImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC3, new Scalar(0, 0, 0));
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
CopyMemory(pImageRed.Data, new IntPtr((byte*)ptrRed.IP), (uint)(width * height)); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Red
|
||||||
|
CopyMemory(pImageGreen.Data, new IntPtr((byte*)ptrGreen.IP), (uint)(width * height)); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Green
|
||||||
|
CopyMemory(pImageBlue.Data, new IntPtr((byte*)ptrBlue.IP), (uint)(width * height)); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Blue
|
||||||
|
|
||||||
|
}
|
||||||
|
Mat[] multi = new Mat[] { pImageBlue, pImageGreen, pImageRed };
|
||||||
|
Cv2.Merge(multi, mImage);
|
||||||
|
pImageRed.Dispose();
|
||||||
|
pImageRed = null;
|
||||||
|
pImageGreen.Dispose();
|
||||||
|
pImageGreen = null;
|
||||||
|
pImageBlue.Dispose();
|
||||||
|
pImageBlue = null;
|
||||||
|
return mImage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从内存流中指定位置,读取数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="curStream"></param>
|
||||||
|
/// <param name="startPosition"></param>
|
||||||
|
/// <param name="length"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int ReadData(MemoryStream curStream, int startPosition, int length)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
byte[] tempData = new byte[length];
|
||||||
|
curStream.Position = startPosition;
|
||||||
|
curStream.Read(tempData, 0, length);
|
||||||
|
result = BitConverter.ToInt32(tempData, 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用byte[]数据,生成三通道 BMP 位图
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="originalImageData"></param>
|
||||||
|
/// <param name="originalWidth"></param>
|
||||||
|
/// <param name="originalHeight"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Bitmap CreateColorBitmap(byte[] originalImageData, int originalWidth, int originalHeight, byte[] color_map)
|
||||||
|
{
|
||||||
|
// 指定8位格式,即256色
|
||||||
|
Bitmap resultBitmap = new Bitmap(originalWidth, originalHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
|
||||||
|
// 将该位图存入内存中
|
||||||
|
MemoryStream curImageStream = new MemoryStream();
|
||||||
|
resultBitmap.Save(curImageStream, System.Drawing.Imaging.ImageFormat.Bmp);
|
||||||
|
curImageStream.Flush();
|
||||||
|
|
||||||
|
// 由于位图数据需要DWORD对齐(4byte倍数),计算需要补位的个数
|
||||||
|
int curPadNum = ((originalWidth * 8 + 31) / 32 * 4) - originalWidth;
|
||||||
|
|
||||||
|
// 最终生成的位图数据大小
|
||||||
|
int bitmapDataSize = ((originalWidth * 8 + 31) / 32 * 4) * originalHeight;
|
||||||
|
|
||||||
|
// 数据部分相对文件开始偏移,具体可以参考位图文件格式
|
||||||
|
int dataOffset = ReadData(curImageStream, 10, 4);
|
||||||
|
|
||||||
|
|
||||||
|
// 改变调色板,因为默认的调色板是32位彩色的,需要修改为256色的调色板
|
||||||
|
int paletteStart = 54;
|
||||||
|
int paletteEnd = dataOffset;
|
||||||
|
int color = 0;
|
||||||
|
|
||||||
|
for (int i = paletteStart; i < paletteEnd; i += 4)
|
||||||
|
{
|
||||||
|
byte[] tempColor = new byte[4];
|
||||||
|
tempColor[0] = (byte)color;
|
||||||
|
tempColor[1] = (byte)color;
|
||||||
|
tempColor[2] = (byte)color;
|
||||||
|
tempColor[3] = (byte)0;
|
||||||
|
color++;
|
||||||
|
|
||||||
|
curImageStream.Position = i;
|
||||||
|
curImageStream.Write(tempColor, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最终生成的位图数据,以及大小,高度没有变,宽度需要调整
|
||||||
|
byte[] destImageData = new byte[bitmapDataSize];
|
||||||
|
int destWidth = originalWidth + curPadNum;
|
||||||
|
|
||||||
|
// 生成最终的位图数据,注意的是,位图数据 从左到右,从下到上,所以需要颠倒
|
||||||
|
for (int originalRowIndex = originalHeight - 1; originalRowIndex >= 0; originalRowIndex--)
|
||||||
|
{
|
||||||
|
int destRowIndex = originalHeight - originalRowIndex - 1;
|
||||||
|
|
||||||
|
for (int dataIndex = 0; dataIndex < originalWidth; dataIndex++)
|
||||||
|
{
|
||||||
|
// 同时还要注意,新的位图数据的宽度已经变化destWidth,否则会产生错位
|
||||||
|
destImageData[destRowIndex * destWidth + dataIndex] = originalImageData[originalRowIndex * originalWidth + dataIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将流的Position移到数据段
|
||||||
|
curImageStream.Position = dataOffset;
|
||||||
|
|
||||||
|
// 将新位图数据写入内存中
|
||||||
|
curImageStream.Write(destImageData, 0, bitmapDataSize);
|
||||||
|
|
||||||
|
curImageStream.Flush();
|
||||||
|
|
||||||
|
// 将内存中的位图写入Bitmap对象
|
||||||
|
resultBitmap = new Bitmap(curImageStream);
|
||||||
|
|
||||||
|
resultBitmap = Convert8to24(resultBitmap, color_map); // 转为3通道图像
|
||||||
|
|
||||||
|
return resultBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实现单通道到多通道
|
||||||
|
public static Bitmap Convert8to24(this Bitmap bmp, byte[] color_map)
|
||||||
|
{
|
||||||
|
|
||||||
|
Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
|
||||||
|
BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
|
||||||
|
|
||||||
|
//计算实际8位图容量
|
||||||
|
int size8 = bitmapData.Stride * bmp.Height;
|
||||||
|
byte[] grayValues = new byte[size8];
|
||||||
|
|
||||||
|
//// 申请目标位图的变量,并将其内存区域锁定
|
||||||
|
Bitmap TempBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format24bppRgb);
|
||||||
|
BitmapData TempBmpData = TempBmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
|
||||||
|
|
||||||
|
|
||||||
|
//// 获取图像参数以及设置24位图信息
|
||||||
|
int stride = TempBmpData.Stride; // 扫描线的宽度
|
||||||
|
int offset = stride - TempBmp.Width; // 显示宽度与扫描线宽度的间隙
|
||||||
|
IntPtr iptr = TempBmpData.Scan0; // 获取bmpData的内存起始位置
|
||||||
|
int scanBytes = stride * TempBmp.Height;// 用stride宽度,表示这是内存区域的大小
|
||||||
|
|
||||||
|
// 下面把原始的显示大小字节数组转换为内存中实际存放的字节数组
|
||||||
|
byte[] pixelValues = new byte[scanBytes]; //为目标数组分配内存
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, grayValues, 0, size8);
|
||||||
|
|
||||||
|
for (int i = 0; i < bmp.Height; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int j = 0; j < bitmapData.Stride; j++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (j >= bmp.Width)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int indexSrc = i * bitmapData.Stride + j;
|
||||||
|
int realIndex = i * TempBmpData.Stride + j * 3;
|
||||||
|
|
||||||
|
// color_id:就是预测出来的结果
|
||||||
|
int color_id = (int)grayValues[indexSrc] % 256;
|
||||||
|
|
||||||
|
if (color_id == 0) // 分割中类别1对应值1,而背景往往为0,因此这里就将背景置为[0, 0, 0]
|
||||||
|
{
|
||||||
|
// 空白
|
||||||
|
pixelValues[realIndex] = 0;
|
||||||
|
pixelValues[realIndex + 1] = 0;
|
||||||
|
pixelValues[realIndex + 2] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 替换为color_map中的颜色值
|
||||||
|
pixelValues[realIndex] = color_map[color_id * 3];
|
||||||
|
pixelValues[realIndex + 1] = color_map[color_id * 3 + 1];
|
||||||
|
pixelValues[realIndex + 2] = color_map[color_id * 3 + 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parallel.For(0, width * height, i =>
|
||||||
|
// {
|
||||||
|
// int index = (i + 1) % width + widthIn4 * ((i + 1) / width) - 1;
|
||||||
|
|
||||||
|
// showBitmapBuffer[index * 6] = bitmapBuffer[index * 6] = data[i * 2];
|
||||||
|
// showBitmapBuffer[index * 6 + 1] = bitmapBuffer[index * 6 + 1] = data[i * 2 + 1];
|
||||||
|
// });
|
||||||
|
|
||||||
|
// 用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
|
||||||
|
Marshal.Copy(pixelValues, 0, iptr, scanBytes);
|
||||||
|
TempBmp.UnlockBits(TempBmpData); // 解锁内存区域
|
||||||
|
bmp.UnlockBits(bitmapData);
|
||||||
|
return TempBmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取伪彩色图的RGB值 -- 同时也是适用于检测框分类颜色
|
||||||
|
public static byte[] GetColorMap(int num_classes = 256)
|
||||||
|
{
|
||||||
|
num_classes += 1;
|
||||||
|
byte[] color_map = new byte[num_classes * 3];
|
||||||
|
for (int i = 0; i < num_classes; i++)
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
int lab = i;
|
||||||
|
while (lab != 0)
|
||||||
|
{
|
||||||
|
color_map[i * 3] |= (byte)(((lab >> 0) & 1) << (7 - j));
|
||||||
|
color_map[i * 3 + 1] |= (byte)(((lab >> 1) & 1) << (7 - j));
|
||||||
|
color_map[i * 3 + 2] |= (byte)(((lab >> 2) & 1) << (7 - j));
|
||||||
|
|
||||||
|
j += 1;
|
||||||
|
lab >>= 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去掉底色
|
||||||
|
color_map = color_map.Skip(3).ToArray();
|
||||||
|
return color_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGrayMap
|
||||||
|
public static byte[] GetGrayMap(int num_classes = 256)
|
||||||
|
{
|
||||||
|
byte[] color_map = new byte[num_classes];
|
||||||
|
for (int i = 0; i < num_classes; i++)
|
||||||
|
{
|
||||||
|
if (i <= 100)
|
||||||
|
color_map[i] = 0;
|
||||||
|
if (i > 100 && i <= 200)
|
||||||
|
color_map[i] = 100;
|
||||||
|
if (i > 200)
|
||||||
|
color_map[i] = 255;
|
||||||
|
|
||||||
|
}
|
||||||
|
return color_map;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 像素点阵转换为bitmap 二值化图
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rawValues">byte[]数组</param>
|
||||||
|
/// <param name="width">图片的宽度</param>
|
||||||
|
/// <param name="height">图片的高度</param>
|
||||||
|
/// <returns>bitmap图片</returns>
|
||||||
|
public static Bitmap CreateBinaryBitmap(byte[] rawValues, int width, int height)
|
||||||
|
{
|
||||||
|
Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
//获取图像参数
|
||||||
|
int stride = bmpData.Stride; // 扫描线的宽度
|
||||||
|
int offset = stride - width; // 显示宽度与扫描线宽度的间隙
|
||||||
|
IntPtr iptr = bmpData.Scan0; // 获取bmpData的内存起始位置
|
||||||
|
int scanBytes = stride * height;// 用stride宽度,表示这是内存区域的大小
|
||||||
|
//下面把原始的显示大小字节数组转换为内存中实际存放的字节数组
|
||||||
|
int posScan = 0, posReal = 0;// 分别设置两个位置指针,指向源数组和目标数组
|
||||||
|
byte[] pixelValues = new byte[scanBytes]; //为目标数组分配内存
|
||||||
|
for (int x = 0; x < height; x++)
|
||||||
|
{
|
||||||
|
//下面的循环节是模拟行扫描
|
||||||
|
for (int y = 0; y < width; y++)
|
||||||
|
{
|
||||||
|
pixelValues[posScan++] = rawValues[posReal++] == 0 ? (byte)0 : (byte)255;
|
||||||
|
}
|
||||||
|
posScan += offset; //行扫描结束,要将目标位置指针移过那段“间隙”
|
||||||
|
}
|
||||||
|
//用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
|
||||||
|
Marshal.Copy(pixelValues, 0, iptr, scanBytes);
|
||||||
|
bmp.UnlockBits(bmpData); // 解锁内存区域
|
||||||
|
//下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度
|
||||||
|
ColorPalette tempPalette;
|
||||||
|
using (Bitmap tempBmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed))
|
||||||
|
{
|
||||||
|
tempPalette = tempBmp.Palette;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
tempPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bmp.Palette = tempPalette;
|
||||||
|
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 像素点阵转换为bitmap灰度图
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rawValues">byte[]数组</param>
|
||||||
|
/// <param name="width">图片的宽度</param>
|
||||||
|
/// <param name="height">图片的高度</param>
|
||||||
|
/// <returns>bitmap图片</returns>
|
||||||
|
public static Bitmap CreateGrayBitmap(byte[] rawValues, int width, int height)
|
||||||
|
{
|
||||||
|
Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
//获取图像参数
|
||||||
|
int stride = bmpData.Stride; // 扫描线的宽度
|
||||||
|
int offset = stride - width; // 显示宽度与扫描线宽度的间隙
|
||||||
|
IntPtr iptr = bmpData.Scan0; // 获取bmpData的内存起始位置
|
||||||
|
int scanBytes = stride * height;// 用stride宽度,表示这是内存区域的大小
|
||||||
|
//下面把原始的显示大小字节数组转换为内存中实际存放的字节数组
|
||||||
|
int posScan = 0, posReal = 0;// 分别设置两个位置指针,指向源数组和目标数组
|
||||||
|
byte[] pixelValues = new byte[scanBytes]; //为目标数组分配内存
|
||||||
|
for (int x = 0; x < height; x++)
|
||||||
|
{
|
||||||
|
//下面的循环节是模拟行扫描
|
||||||
|
for (int y = 0; y < width; y++)
|
||||||
|
{
|
||||||
|
pixelValues[posScan++] = rawValues[posReal++];
|
||||||
|
}
|
||||||
|
posScan += offset; //行扫描结束,要将目标位置指针移过那段“间隙”
|
||||||
|
}
|
||||||
|
//用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
|
||||||
|
Marshal.Copy(pixelValues, 0, iptr, scanBytes);
|
||||||
|
bmp.UnlockBits(bmpData); // 解锁内存区域
|
||||||
|
//下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度
|
||||||
|
ColorPalette tempPalette;
|
||||||
|
using (Bitmap tempBmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed))
|
||||||
|
{
|
||||||
|
tempPalette = tempBmp.Palette;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
tempPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bmp.Palette = tempPalette;
|
||||||
|
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//分别基于像素(GetPixel和SetPixel)、基于内存、基于指针这三种方法增强图片对比度。
|
||||||
|
// 第一种方法:像素提取法。速度慢 基于像素:400-600ms
|
||||||
|
public static Bitmap MethodBaseOnPixel(Bitmap bitmap, int degree)
|
||||||
|
{
|
||||||
|
Color curColor;
|
||||||
|
int grayR, grayG, grayB;
|
||||||
|
|
||||||
|
double Deg = (100.0 + degree) / 100.0;
|
||||||
|
for (int i = 0; i < bitmap.Width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < bitmap.Height; j++)
|
||||||
|
{
|
||||||
|
curColor = bitmap.GetPixel(i, j);
|
||||||
|
grayR = Convert.ToInt32((((curColor.R / 255.0 - 0.5) * Deg + 0.5)) * 255);
|
||||||
|
grayG = Convert.ToInt32((((curColor.G / 255.0 - 0.5) * Deg + 0.5)) * 255);
|
||||||
|
grayB = Convert.ToInt32((((curColor.B / 255.0 - 0.5) * Deg + 0.5)) * 255);
|
||||||
|
if (grayR < 0)
|
||||||
|
grayR = 0;
|
||||||
|
else if (grayR > 255)
|
||||||
|
grayR = 255;
|
||||||
|
|
||||||
|
if (grayB < 0)
|
||||||
|
grayB = 0;
|
||||||
|
else if (grayB > 255)
|
||||||
|
grayB = 255;
|
||||||
|
|
||||||
|
if (grayG < 0)
|
||||||
|
grayG = 0;
|
||||||
|
else if (grayG > 255)
|
||||||
|
grayG = 255;
|
||||||
|
|
||||||
|
bitmap.SetPixel(i, j, Color.FromArgb(grayR, grayG, grayB));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第二种方法:基于内存 17-18ms
|
||||||
|
public static unsafe Bitmap MethodBaseOnMemory(Bitmap bitmap, int degree)
|
||||||
|
{
|
||||||
|
if (bitmap == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
double Deg = (100.0 + degree) / 100.0;
|
||||||
|
|
||||||
|
int width = bitmap.Width;
|
||||||
|
int height = bitmap.Height;
|
||||||
|
|
||||||
|
int length = height * 3 * width;
|
||||||
|
byte[] RGB = new byte[length];
|
||||||
|
|
||||||
|
BitmapData data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
|
||||||
|
|
||||||
|
System.IntPtr Scan0 = data.Scan0;
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(Scan0, RGB, 0, length);
|
||||||
|
|
||||||
|
double gray = 0;
|
||||||
|
for (int i = 0; i < RGB.Length; i += 3)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
gray = (((RGB[i + j] / 255.0 - 0.5) * Deg + 0.5)) * 255.0;
|
||||||
|
if (gray > 255)
|
||||||
|
gray = 255;
|
||||||
|
|
||||||
|
if (gray < 0)
|
||||||
|
gray = 0;
|
||||||
|
RGB[i + j] = (byte)gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(RGB, 0, Scan0, length);// 此处Copy是之前Copy的逆操作
|
||||||
|
bitmap.UnlockBits(data);
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
//第三种方法:基于指针 20-23ms
|
||||||
|
public static unsafe Bitmap MethodBaseOnPtr(Bitmap b, int degree)
|
||||||
|
{
|
||||||
|
if (b == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
double num = 0.0;
|
||||||
|
double num2 = (100.0 + degree) / 100.0;
|
||||||
|
num2 *= num2;
|
||||||
|
int width = b.Width;
|
||||||
|
int height = b.Height;
|
||||||
|
BitmapData bitmapdata = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
|
||||||
|
byte* numPtr = (byte*)bitmapdata.Scan0;
|
||||||
|
|
||||||
|
int offset = bitmapdata.Stride - (width * 3);
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < width; j++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
num = ((((((double)numPtr[k]) / 255.0) - 0.5) * num2) + 0.5) * 255.0;
|
||||||
|
if (num < 0.0)
|
||||||
|
{
|
||||||
|
num = 0.0;
|
||||||
|
}
|
||||||
|
if (num > 255.0)
|
||||||
|
{
|
||||||
|
num = 255.0;
|
||||||
|
}
|
||||||
|
numPtr[k] = (byte)num;
|
||||||
|
}
|
||||||
|
numPtr += 3;
|
||||||
|
|
||||||
|
}
|
||||||
|
numPtr += offset;
|
||||||
|
}
|
||||||
|
b.UnlockBits(bitmapdata);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double GetRoiArae(Mat src, Rect rect)
|
||||||
|
{
|
||||||
|
//初始面积为0
|
||||||
|
double Area = 0;
|
||||||
|
//获取感兴趣区域
|
||||||
|
src = src[rect];
|
||||||
|
//转为单通道
|
||||||
|
Mat gray = src.CvtColor(ColorConversionCodes.BGR2GRAY);
|
||||||
|
//二值化
|
||||||
|
Mat binary = gray.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
|
||||||
|
|
||||||
|
//求轮廓 不连通会有多个闭合区域
|
||||||
|
OpenCvSharp.Point[][] contours;
|
||||||
|
HierarchyIndex[] hierarchy;
|
||||||
|
Cv2.FindContours(binary, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple);
|
||||||
|
for (int i = 0; i < contours.Count(); i++)
|
||||||
|
{
|
||||||
|
//所有面积相加
|
||||||
|
Area += Cv2.ContourArea(contours[i], false);
|
||||||
|
}
|
||||||
|
return Area;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ namespace DH.Devices.Camera
|
|||||||
|
|
||||||
public class Do3ThinkCamera : CameraBase
|
public class Do3ThinkCamera : CameraBase
|
||||||
{
|
{
|
||||||
|
|
||||||
private dvpCameraInfo stDevInfo = new dvpCameraInfo();
|
private dvpCameraInfo stDevInfo = new dvpCameraInfo();
|
||||||
private dvpStatus nRet = dvpStatus.DVP_STATUS_OK;
|
private dvpStatus nRet = dvpStatus.DVP_STATUS_OK;
|
||||||
private DVPCamera.dvpEventCallback pCallBackFunc;
|
private DVPCamera.dvpEventCallback pCallBackFunc;
|
||||||
@ -24,7 +24,7 @@ namespace DH.Devices.Camera
|
|||||||
public Double m_dfDisplayCount = 0;
|
public Double m_dfDisplayCount = 0;
|
||||||
public Do3ThinkCamera()
|
public Do3ThinkCamera()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ namespace DH.Devices.Camera
|
|||||||
dvpCameraInfo camerainfo = new dvpCameraInfo();
|
dvpCameraInfo camerainfo = new dvpCameraInfo();
|
||||||
nRet = DVPCamera.dvpGetCameraInfo(m_handle, ref camerainfo);
|
nRet = DVPCamera.dvpGetCameraInfo(m_handle, ref camerainfo);
|
||||||
|
|
||||||
SerialNumber= camerainfo.SerialNumber;
|
SerialNumber = camerainfo.SerialNumber;
|
||||||
// ch:注册异常回调函数 | en:Register Exception Callback
|
// ch:注册异常回调函数 | en:Register Exception Callback
|
||||||
//nRet = DVPCamera.dvpRegisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
|
//nRet = DVPCamera.dvpRegisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
|
||||||
//if (nRet != dvpStatus.DVP_STATUS_OK)
|
//if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||||
@ -87,82 +87,82 @@ namespace DH.Devices.Camera
|
|||||||
//}
|
//}
|
||||||
//else
|
//else
|
||||||
//{
|
//{
|
||||||
// ch:设置触发模式为on || en:set trigger mode as on
|
// ch:设置触发模式为on || en:set trigger mode as on
|
||||||
nRet = DVPCamera.dvpSetTriggerState(m_handle, true);
|
nRet = DVPCamera.dvpSetTriggerState(m_handle, true);
|
||||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||||
{
|
{
|
||||||
throw new Exception("Set TriggerMode failed!");
|
throw new Exception("Set TriggerMode failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 硬触发
|
// 硬触发
|
||||||
//if (IIConfig.IsHardwareTrigger)
|
//if (IIConfig.IsHardwareTrigger)
|
||||||
//{
|
//{
|
||||||
// ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
|
// ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
|
||||||
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
|
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
|
||||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||||
{
|
{
|
||||||
throw new Exception("Set Line1 Trigger failed!");
|
throw new Exception("Set Line1 Trigger failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ch:注册回调函数 | en:Register image callback
|
// ch:注册回调函数 | en:Register image callback
|
||||||
ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc);
|
ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc);
|
||||||
nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
|
nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
|
||||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||||
{
|
{
|
||||||
throw new Exception("Register image callback failed!");
|
throw new Exception("Register image callback failed!");
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
//else // 软触发
|
//else // 软触发
|
||||||
//{
|
//{
|
||||||
// nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
|
// nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
|
||||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||||
// {
|
// {
|
||||||
// throw new Exception("Set Software Trigger failed!");
|
// throw new Exception("Set Software Trigger failed!");
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// ch:开启抓图 || en: start grab image
|
// ch:开启抓图 || en: start grab image
|
||||||
nRet = DVPCamera.dvpStart(m_handle);
|
nRet = DVPCamera.dvpStart(m_handle);
|
||||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||||
{
|
{
|
||||||
throw new Exception($"Start grabbing failed:{nRet:x8}");
|
throw new Exception($"Start grabbing failed:{nRet:x8}");
|
||||||
}
|
}
|
||||||
//// 曝光
|
//// 曝光
|
||||||
//if (IIConfig.DefaultExposure != 0)
|
//if (IIConfig.DefaultExposure != 0)
|
||||||
//{
|
//{
|
||||||
// SetExposure(IIConfig.DefaultExposure);
|
// SetExposure(IIConfig.DefaultExposure);
|
||||||
//}
|
//}
|
||||||
//// 增益
|
//// 增益
|
||||||
//if (IIConfig.Gain >= 0)
|
//if (IIConfig.Gain >= 0)
|
||||||
//{
|
//{
|
||||||
// SetGain(IIConfig.Gain);
|
// SetGain(IIConfig.Gain);
|
||||||
//}
|
//}
|
||||||
//SetPictureRoi(IIConfig.VelocityPara.A_Pic_X, IIConfig.VelocityPara.A_Pic_Y, IIConfig.VelocityPara.Width, IIConfig.VelocityPara.Hight);
|
//SetPictureRoi(IIConfig.VelocityPara.A_Pic_X, IIConfig.VelocityPara.A_Pic_Y, IIConfig.VelocityPara.Width, IIConfig.VelocityPara.Hight);
|
||||||
|
|
||||||
//// 设置 触发延迟
|
//// 设置 触发延迟
|
||||||
//if (IIConfig.TriggerDelay > 0)
|
//if (IIConfig.TriggerDelay > 0)
|
||||||
//{
|
//{
|
||||||
// nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay);
|
// nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay);
|
||||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||||
// {
|
// {
|
||||||
// throw new Exception("Set TriggerDelay failed!");
|
// throw new Exception("Set TriggerDelay failed!");
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//// 信号消抖
|
//// 信号消抖
|
||||||
//if (IIConfig.LineDebouncerTime > 0)
|
//if (IIConfig.LineDebouncerTime > 0)
|
||||||
//{
|
//{
|
||||||
// nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime);
|
// nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime);
|
||||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||||
// {
|
// {
|
||||||
// throw new Exception($"LineDebouncerTime set failed:{nRet}");
|
// throw new Exception($"LineDebouncerTime set failed:{nRet}");
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//IIConfig.PropertyChanged -= IIConfig_PropertyChanged;
|
//IIConfig.PropertyChanged -= IIConfig_PropertyChanged;
|
||||||
//IIConfig.PropertyChanged += IIConfig_PropertyChanged;
|
//IIConfig.PropertyChanged += IIConfig_PropertyChanged;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@ -258,20 +258,20 @@ namespace DH.Devices.Camera
|
|||||||
/// <exception cref="Exception"></exception>
|
/// <exception cref="Exception"></exception>
|
||||||
private void SetExposure(double exposure)
|
private void SetExposure(double exposure)
|
||||||
{
|
{
|
||||||
// 关闭自动曝光
|
// 关闭自动曝光
|
||||||
nRet = DVPCamera.dvpSetAeOperation(m_handle, dvpAeOperation.AE_OP_OFF);
|
nRet = DVPCamera.dvpSetAeOperation(m_handle, dvpAeOperation.AE_OP_OFF);
|
||||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||||
{
|
{
|
||||||
throw new Exception($"Exposure set failed:{nRet}");
|
throw new Exception($"Exposure set failed:{nRet}");
|
||||||
}
|
}
|
||||||
// 设置曝光值
|
// 设置曝光值
|
||||||
nRet = DVPCamera.dvpSetExposure(m_handle, exposure);
|
nRet = DVPCamera.dvpSetExposure(m_handle, exposure);
|
||||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||||
{
|
{
|
||||||
throw new Exception($"Exposure set failed:{nRet}");
|
throw new Exception($"Exposure set failed:{nRet}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -309,16 +309,23 @@ namespace DH.Devices.Camera
|
|||||||
public int ImageCallbackFunc(uint handle, dvpStreamEvent _event, IntPtr pContext, ref dvpFrame refFrame, IntPtr pBuffer)
|
public int ImageCallbackFunc(uint handle, dvpStreamEvent _event, IntPtr pContext, ref dvpFrame refFrame, IntPtr pBuffer)
|
||||||
{
|
{
|
||||||
Mat cvImage = new Mat();
|
Mat cvImage = new Mat();
|
||||||
|
if (this.CameraName.Equals("Cam1"))
|
||||||
|
{
|
||||||
|
Console.WriteLine( );
|
||||||
|
}
|
||||||
|
if (this.CameraName.Equals("Cam2"))
|
||||||
|
{
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
Interlocked.Increment(ref SnapshotCount);
|
Interlocked.Increment(ref SnapshotCount);
|
||||||
|
|
||||||
|
|
||||||
int nWidth = refFrame.iWidth;
|
int nWidth = refFrame.iWidth;
|
||||||
int nHeight = refFrame.iHeight;
|
int nHeight = refFrame.iHeight;
|
||||||
|
|
||||||
// 根据图像格式创建Mat
|
// 根据图像格式创建Mat
|
||||||
switch (refFrame.format)
|
switch (refFrame.format)
|
||||||
{
|
{
|
||||||
@ -336,7 +343,8 @@ namespace DH.Devices.Camera
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException($"Unsupported format: {refFrame.format}");
|
cvImage = Mat.FromPixelData(nHeight, nWidth, MatType.CV_8UC1, pBuffer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Mat smat = cvImage.Clone();
|
Mat smat = cvImage.Clone();
|
||||||
OnHImageOutput?.Invoke(DateTime.Now, this, smat);
|
OnHImageOutput?.Invoke(DateTime.Now, this, smat);
|
||||||
@ -349,7 +357,7 @@ namespace DH.Devices.Camera
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace XKRS.Device.SolidMotionCard
|
namespace DH.Devices.Motion
|
||||||
{
|
{
|
||||||
|
|
||||||
public enum FuncRet
|
public enum FuncRet
|
||||||
|
@ -73,7 +73,7 @@ namespace DH.Devices.Motion
|
|||||||
[Category("机台配置")]
|
[Category("机台配置")]
|
||||||
[DisplayName("机台类型")]
|
[DisplayName("机台类型")]
|
||||||
[Description("机台类型")]
|
[Description("机台类型")]
|
||||||
public MachineDiskType MachineDiskType { get; set; } = MachineDiskType.DoubleDisk;
|
public MachineDiskType MachineDiskType { get; set; } = MachineDiskType.SingleDisk;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -111,12 +111,12 @@ namespace DH.Devices.Motion
|
|||||||
[DisplayName("输出IO总数")]
|
[DisplayName("输出IO总数")]
|
||||||
public int OutputNums { get; set; } = 16;
|
public int OutputNums { get; set; } = 16;
|
||||||
|
|
||||||
//[Category("IO配置")]
|
[Category("IO配置")]
|
||||||
//[DisplayName("IO定义集合")]
|
[DisplayName("IO定义集合")]
|
||||||
//[Description("IO定义集合")]
|
[Description("IO定义集合")]
|
||||||
//[TypeConverter(typeof(CollectionCountConvert))]
|
//[TypeConverter(typeof(CollectionCountConvert))]
|
||||||
//[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
|
// [Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
|
||||||
//public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>();
|
public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>();
|
||||||
|
|
||||||
[Category("IO配置")]
|
[Category("IO配置")]
|
||||||
[DisplayName("是否信号模式")]
|
[DisplayName("是否信号模式")]
|
||||||
@ -194,35 +194,35 @@ namespace DH.Devices.Motion
|
|||||||
public List<BlowSetting> BlowSettings { get; set; } = new List<BlowSetting>();
|
public List<BlowSetting> BlowSettings { get; set; } = new List<BlowSetting>();
|
||||||
|
|
||||||
|
|
||||||
//[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
//[DisplayName("转盘运转方向")]
|
[DisplayName("转盘运转方向")]
|
||||||
//[Description("转盘运转方向,顺时针或逆时针")]
|
[Description("转盘运转方向,顺时针或逆时针")]
|
||||||
//[TypeConverter(typeof(EnumDescriptionConverter<RotationDirectionEnum>))]
|
//[TypeConverter(typeof(EnumDescriptionConverter<RotationDirectionEnum>))]
|
||||||
//public RotationDirectionEnum MotionDir { get; set; } = RotationDirectionEnum.Clockwise;
|
public RotationDirectionEnum MotionDir { get; set; } = RotationDirectionEnum.Clockwise;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
[DisplayName("物料尺寸最大值")]
|
[DisplayName("物料尺寸最大值")]
|
||||||
[Description("物料尺寸最大值,单位:脉冲")]
|
[Description("物料尺寸最大值,单位:脉冲")]
|
||||||
public uint PieceMaxSize { get; set; } = 2000;
|
public uint PieceMaxSize { get; set; } = 20000;
|
||||||
|
|
||||||
|
|
||||||
[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
[DisplayName("物料尺寸最小值")]
|
[DisplayName("物料尺寸最小值")]
|
||||||
[Description("物料尺寸最小值,单位:脉冲")]
|
[Description("物料尺寸最小值,单位:脉冲")]
|
||||||
public uint PieceMinSize { get; set; } = 1500;
|
public uint PieceMinSize { get; set; } = 10;
|
||||||
|
|
||||||
|
|
||||||
[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
[DisplayName("物料最小间隔")]
|
[DisplayName("物料最小间隔")]
|
||||||
[Description("物料最小间隔,单位:脉冲")]
|
[Description("物料最小间隔,单位:脉冲")]
|
||||||
public uint MinDistance { get; set; } = 2000;
|
public uint MinDistance { get; set; } = 10;
|
||||||
|
|
||||||
[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
[DisplayName("两个物料之间触发最小间隔时间")]
|
[DisplayName("两个物料之间触发最小间隔时间")]
|
||||||
[Description("两个物料之间触发最小间隔时间,单位:ms")]
|
[Description("两个物料之间触发最小间隔时间,单位:ms")]
|
||||||
public uint MinTimeInterval { get; set; } = 10;
|
public uint MinTimeInterval { get; set; } = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -550,7 +550,7 @@ namespace DH.Devices.Motion
|
|||||||
[Category("回原点参数")]
|
[Category("回原点参数")]
|
||||||
[DisplayName("回原点方式")]
|
[DisplayName("回原点方式")]
|
||||||
[Description("HomeMode:回原点方式")]
|
[Description("HomeMode:回原点方式")]
|
||||||
public GoHomeMode HomeMode { get; set; } = GoHomeMode.Negative_Ne_Center_H_Positive_N_Stop_HNeO_Offset_Po;
|
public GoHomeMode HomeMode { get; set; } = GoHomeMode.Negative_Ne_Center_H_Positive_N_Index_HPoO_Offset_Po;
|
||||||
|
|
||||||
|
|
||||||
[Category("回原点参数")]
|
[Category("回原点参数")]
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
using DH.Commons.Enums;
|
using DH.Commons.Enums;
|
||||||
using DH.Devices.Motion;
|
using DH.Devices.Motion;
|
||||||
using MCDLL_NET;
|
using MCDLL_NET;
|
||||||
|
using OpenCvSharp;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using static System.Collections.Specialized.BitVector32;
|
||||||
|
|
||||||
|
|
||||||
namespace XKRS.Device.SolidMotionCard
|
namespace DH.Devices.Motion
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@ -150,22 +152,32 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
.ToDictionary(a => a.AxisIndex, a => new ManualResetEvent(true));
|
.ToDictionary(a => a.AxisIndex, a => new ManualResetEvent(true));
|
||||||
|
|
||||||
// 初始化时关闭所有轴,停止筛选 begin =======
|
// 初始化时关闭所有轴,停止筛选 begin =======
|
||||||
AllMoveStop();
|
//AllMoveStop();
|
||||||
AllAxisOff();
|
|
||||||
|
// CMCDLL_NET.MCF_Axis_Stop_Net(0, AxisStopMode.AxisStopIMD, 0);
|
||||||
|
|
||||||
|
//CMCDLL_NET.MCF_Set_Axis_Stop_Profile_Net(0, 50000, 0, 0, 0);
|
||||||
|
// CMCDLL_NET.MCF_Axis_Stop_Net(0, AxisStopMode.AxisStopDEC, 0);
|
||||||
|
AxisStop();
|
||||||
|
//AllAxisOff();
|
||||||
|
var ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(0, (ushort)ServoLogic.Servo_Open, 0);
|
||||||
|
|
||||||
StopSorting();
|
StopSorting();
|
||||||
|
|
||||||
// 初始化时关闭所有轴,停止筛选 end =======
|
// 初始化时关闭所有轴,停止筛选 end =======
|
||||||
|
|
||||||
AllAxisOn();
|
//AllAxisOn();
|
||||||
Start();
|
Start();
|
||||||
MonitorPosition();
|
MonitorPosition();
|
||||||
MonitorAxisStatus();
|
MonitorAxisStatus();
|
||||||
MonitorPieces();
|
|
||||||
|
|
||||||
CustomStart();
|
CustomStart();
|
||||||
|
|
||||||
|
|
||||||
|
MonitorPieces();
|
||||||
isconnected = true;
|
isconnected = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@ -276,53 +288,56 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
for (ushort station = 0; station < BoardCount; station++)
|
for (ushort station = 0; station < BoardCount; station++)
|
||||||
{
|
{
|
||||||
// 关闭调试测试后的位置比较
|
// 关闭调试测试后的位置比较
|
||||||
|
//关闭调试测试后的位置比较
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
rtn = CMCDLL_NET.MCF_Set_Compare_Config_Net((ushort)i, 0, 0, station);
|
rtn = CMCDLL_NET.MCF_Set_Compare_Config_Net((ushort)i, 0, 0, station);
|
||||||
|
Console.WriteLine($"MCF_Set_Compare_Config_Net {i}::{rtn}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.配置物件设置
|
//2.配置物件设置
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Piece_Size_Net(PieceMaxSize, PieceMinSize, station);
|
rtn = CMCDLL_NET.MCF_Sorting_Set_Piece_Size_Net(PieceMaxSize, PieceMinSize, station);
|
||||||
|
Console.WriteLine($"MCF_Sorting_Set_Piece_Size_Net::{rtn}");
|
||||||
|
|
||||||
|
rtn = CMCDLL_NET.MCF_Sorting_Set_Piece_Place_Net(MinDistance, MinTimeInterval, station);
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Piece_Place_Net(MinDistance, MinTimeInterval, station);
|
Console.WriteLine($"MCF_Sorting_Set_Piece_Place_Net::{rtn}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BoardCount < 2)
|
//if (BoardCount < 2)
|
||||||
{
|
//{
|
||||||
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0);
|
// // rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0);
|
||||||
// 3.配置相机设置
|
// // 3.配置相机设置
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0);
|
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0);
|
||||||
//设置来料使能 0 是默认 1是开始
|
// //设置来料使能 0 是默认 1是开始
|
||||||
//
|
// //
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Enable_Net((ushort)SortingInputSetting.BitInputNumber, 1);
|
// rtn = CMCDLL_NET.MCF_Sorting_Set_Input_Enable_Net((ushort)SortingInputSetting.BitInputNumber, 1);
|
||||||
//设置物件检测有效电平 0是低电平 1是高电平
|
// //设置物件检测有效电平 0是低电平 1是高电平
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Logic_Net((ushort)SortingInputSetting.BitInputNumber, 0);
|
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Logic_Net((ushort)SortingInputSetting.BitInputNumber, 0);
|
||||||
//设置来料检测编码器 双转盘要设置两个轴
|
// //设置来料检测编码器 双转盘要设置两个轴
|
||||||
/*Bit_Input_Number:设置位号。
|
// /*Bit_Input_Number:设置位号。
|
||||||
取值: Bit_Input_0, Bit_Input_1。
|
// 取值: Bit_Input_0, Bit_Input_1。
|
||||||
Axis: 轴号。
|
// Axis: 轴号。
|
||||||
Source:跟随方式
|
// Source:跟随方式
|
||||||
取值:0:命令
|
// 取值:0:命令
|
||||||
1:编码器(默认)
|
// 1:编码器(默认)
|
||||||
StationNumber: 站点号;*/
|
// StationNumber: 站点号;*/
|
||||||
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)IIConfig.SortingInputSetting.BitInputNumber, 0, 1);
|
// // rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)IIConfig.SortingInputSetting.BitInputNumber, 0, 1);
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)SortingInputSetting.BitInputNumber, 1, 1);
|
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)SortingInputSetting.BitInputNumber, 1, 1);
|
||||||
|
|
||||||
|
|
||||||
//rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(
|
// //rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(
|
||||||
// (ushort)IIConfig.SnapshotSettings.Count,
|
// // (ushort)IIConfig.SnapshotSettings.Count,
|
||||||
// (ushort)IIConfig.BlowSettings.Count,
|
// // (ushort)IIConfig.BlowSettings.Count,
|
||||||
// 0);
|
// // 0);
|
||||||
// rtn = CMCDLL_NET_Sorting.MCF_Set_Config_Camera_Net();
|
// // rtn = CMCDLL_NET_Sorting.MCF_Set_Config_Camera_Net();
|
||||||
//为防止转盘第二个盘不触发拍照 设置一键取反功能
|
// //为防止转盘第二个盘不触发拍照 设置一键取反功能
|
||||||
}
|
//}
|
||||||
// 3.配置相机设置
|
// 3.配置相机设置
|
||||||
|
|
||||||
ConfigCamera();
|
ConfigCamera();
|
||||||
|
|
||||||
// 4.配置气阀
|
// 4.配置气阀
|
||||||
ConfigBlow();
|
// ConfigBlow();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -334,54 +349,33 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
|
|
||||||
for (ushort card = 0; card < cardCount; card++)
|
for (ushort card = 0; card < cardCount; card++)
|
||||||
{
|
{
|
||||||
//IIConfig.SortingInputSettings.ForEach(sortingInputSetting =>
|
//5.开启筛选
|
||||||
|
rtn = CMCDLL_NET.MCF_Sorting_Start_Net(0, card);
|
||||||
|
if (rtn != (short)0)
|
||||||
|
{
|
||||||
|
// LogAsync(DateTime.Now, LogLevel.Warning, $"卡{station}开启筛选异常,ret:{rtn}");
|
||||||
|
}
|
||||||
|
//if (cardCount < 2)
|
||||||
//{
|
//{
|
||||||
// var camStart = 0;
|
// // 最小值 1 2 2
|
||||||
// if (sortingInputSetting.EnableBindCamera)
|
// var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(
|
||||||
// {
|
// (ushort)SortingInputSetting.BitInputNumber, // 1
|
||||||
// camStart = sortingInputSetting.CameraStartNumber;
|
// SortingInputSetting.CameraStartNumber, // 7,
|
||||||
// }
|
// SortingInputSetting.BlowStartNumber, // 2,
|
||||||
|
|
||||||
// var blowStart = 0;
|
|
||||||
// if (sortingInputSetting.EnableBindBlow)
|
|
||||||
// {
|
|
||||||
// blowStart = sortingInputSetting.BlowStartNumber;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var b = (ushort)sortingInputSetting.BitInputNumber;
|
|
||||||
// //var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(b,
|
|
||||||
// // (ushort)camStart,
|
|
||||||
// // (ushort)blowStart,
|
|
||||||
// // card);
|
|
||||||
|
|
||||||
// var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(1,
|
|
||||||
// 1,
|
|
||||||
// 2,
|
|
||||||
// card);
|
// card);
|
||||||
|
|
||||||
//});
|
//}
|
||||||
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net();
|
|
||||||
if (cardCount < 2)
|
|
||||||
{
|
|
||||||
// 最小值 1 2 2
|
|
||||||
var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(
|
|
||||||
(ushort)SortingInputSetting.BitInputNumber, // 1
|
|
||||||
SortingInputSetting.CameraStartNumber, // 7,
|
|
||||||
SortingInputSetting.BlowStartNumber, // 2,
|
|
||||||
card);
|
|
||||||
|
|
||||||
}
|
//for (ushort station = 0; station < cardCount; station++)
|
||||||
|
//{
|
||||||
for (ushort station = 0; station < cardCount; station++)
|
// // 5.开启筛选
|
||||||
{
|
// //开启自动筛选功能
|
||||||
// 5.开启筛选
|
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Start_Net(0, station);
|
||||||
//开启自动筛选功能
|
// if (rtn != (short)FuncRet.Function_Success)
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Start_Net(0, station);
|
// {
|
||||||
if (rtn != (short)FuncRet.Function_Success)
|
// //LogAsync(DateTime.Now, LogLevel.Warning, $"卡{card}开启筛选异常,ret:{rtn}");
|
||||||
{
|
// }
|
||||||
//LogAsync(DateTime.Now, LogLevel.Warning, $"卡{card}开启筛选异常,ret:{rtn}");
|
//}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,9 +402,12 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
|
|
||||||
public override void Stop()
|
public override void Stop()
|
||||||
{
|
{
|
||||||
|
isconnected = false;
|
||||||
//base.Stop();
|
//base.Stop();
|
||||||
AllMoveStop();
|
AxisStop();
|
||||||
AllAxisOff();
|
int ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(0, (ushort)ServoLogic.Servo_Open, 0);
|
||||||
|
|
||||||
|
// AllAxisOff();
|
||||||
|
|
||||||
for (ushort station = 0; station < BoardCount; station++)
|
for (ushort station = 0; station < BoardCount; station++)
|
||||||
{
|
{
|
||||||
@ -623,7 +620,7 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
// 初始化
|
// 初始化
|
||||||
for (ushort station = 0; station < BoardCount; station++)
|
for (ushort station = 0; station < BoardCount; station++)
|
||||||
{
|
{
|
||||||
ret = CMCDLL_NET_Sorting.MCF_Sorting_Init_Net(station);
|
ret = CMCDLL_NET.MCF_Sorting_Init_Net(station);
|
||||||
stations.Add(station);
|
stations.Add(station);
|
||||||
cardTypes.Add(2);
|
cardTypes.Add(2);
|
||||||
}
|
}
|
||||||
@ -645,8 +642,8 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
MCF_Screen_Set_Trigger1();
|
//MCF_Screen_Set_Trigger1();
|
||||||
MCF_Screen_Set_Trigger1(1);
|
// MCF_Screen_Set_Trigger1(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,7 +846,14 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
return ret == (short)FuncRet.Function_Success;
|
return ret == (short)FuncRet.Function_Success;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//方案2:不使用外部文本框输入参数,直接写入参数
|
||||||
|
|
||||||
|
public void JOGRun(double MaxV,double MaxA)
|
||||||
|
{
|
||||||
|
int ret = CMCDLL_NET.MCF_Set_Pulse_Mode_Net(0, (ushort)PulseMode.Pulse_Dir_H, 0);
|
||||||
|
ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(0, (ushort)ServoLogic.Servo_Close, 0);
|
||||||
|
ret=CMCDLL_NET.MCF_JOG_Net(0, MaxV, MaxA, 0);
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 点位到点位运动
|
/// 点位到点位运动
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1381,13 +1385,38 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void AxisStop()
|
||||||
|
{
|
||||||
|
short rtn;
|
||||||
|
ushort StationNumber = 0;
|
||||||
|
for (ushort a = 0; a < 4; a++)
|
||||||
|
{
|
||||||
|
rtn = CMCDLL_NET.MCF_Set_Axis_Stop_Profile_Net(a, 10000, 100000, 1, StationNumber);//设置轴S型停止曲线参数
|
||||||
|
rtn = CMCDLL_NET.MCF_Axis_Stop_Net(a, 1, StationNumber);//设置轴为平滑停止模式
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool CArdReset()
|
||||||
|
{
|
||||||
|
|
||||||
|
// ConvertFromAxis(startAxisIndex, out ushort station, out ushort axis);
|
||||||
|
|
||||||
|
var ret = CMCDLL_NET.MCF_Set_Position_Net(0, 0, 0);
|
||||||
|
var ret2 = CMCDLL_NET.MCF_Set_Encoder_Net(0, 0, 0);
|
||||||
|
|
||||||
|
return ret2 == 0 ? true : false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 某个轴运动停止
|
/// 某个轴运动停止
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="axisNum">axisNo</param>
|
/// <param name="axisNum">axisNo</param>
|
||||||
/// <param name="option">0表示平滑停止,1表示紧急停止</param>
|
/// <param name="option">0表示平滑停止,1表示紧急停止</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<bool> MoveStop(int axisNum, int option)
|
public async Task<bool> MoveStop(int axisNum, int option)
|
||||||
{
|
{
|
||||||
return await _taskFactory.StartNew(() =>
|
return await _taskFactory.StartNew(() =>
|
||||||
{
|
{
|
||||||
@ -1814,7 +1843,7 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Trig_Camera_Delay_Count_Net(i,
|
var rtn = CMCDLL_NET.MCF_Sorting_Set_Trig_Camera_Delay_Count_Net(i,
|
||||||
camSetting.CameraDelayCountMS, camSetting.StationNumber);
|
camSetting.CameraDelayCountMS, camSetting.StationNumber);
|
||||||
|
|
||||||
|
|
||||||
@ -1849,7 +1878,7 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Camera_Net(
|
rtn = CMCDLL_NET.MCF_Sorting_Set_Camera_Net(
|
||||||
i, // CCD0
|
i, // CCD0
|
||||||
CameraPositionReal,
|
CameraPositionReal,
|
||||||
RotationDirectionReal,
|
RotationDirectionReal,
|
||||||
@ -1959,23 +1988,31 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
switch (blowSetting.BlowType)
|
switch (blowSetting.BlowType)
|
||||||
{
|
{
|
||||||
case BlowType.OK:
|
case BlowType.OK:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_OK_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_OK_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
case BlowType.NG:
|
case BlowType.NG:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_NG_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_NG_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
case BlowType.Blow1:
|
case BlowType.Blow1:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(1, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_1_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
///第一路绑定OK NG 吹起口1
|
///第一路绑定OK NG 吹起口1
|
||||||
case BlowType.Blow2:
|
case BlowType.Blow2:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(2, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_2_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
case BlowType.Blow3:
|
case BlowType.Blow3:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(3, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_3_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
case BlowType.Blow4:
|
case BlowType.Blow4:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(4, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_4_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
|
break;
|
||||||
|
case BlowType.Blow5:
|
||||||
|
CMCDLL_NET.MCF_Sorting_Set_Blow_5_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
|
break;
|
||||||
|
case BlowType.Blow6:
|
||||||
|
CMCDLL_NET.MCF_Sorting_Set_Blow_6_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
//case BlowType.OK:
|
//case BlowType.OK:
|
||||||
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_OK_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber);
|
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_OK_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber);
|
||||||
@ -2002,8 +2039,7 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
//case BlowType.Blow6:
|
//case BlowType.Blow6:
|
||||||
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_6_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber);
|
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_6_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber);
|
||||||
// break;
|
// break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
|
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
|
||||||
|
@ -324,6 +324,29 @@ namespace DH.Devices.Vision
|
|||||||
[Description("是否加入检测工位")]
|
[Description("是否加入检测工位")]
|
||||||
public bool IsAddStation { get; set; } = true;
|
public bool IsAddStation { get; set; } = true;
|
||||||
|
|
||||||
|
[Category("1.预处理(视觉算子)")]
|
||||||
|
[DisplayName("预处理-算法文件路径")]
|
||||||
|
// [Description("预处理算法文件路径配置")][Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
|
||||||
|
public string HalconAlgorithemPath_Pre { get; set; }
|
||||||
|
|
||||||
|
// [Category("1.预处理(视觉算子)")]
|
||||||
|
//[DisplayName("预处理-输出结果的SPEC标准")]
|
||||||
|
//[Description("预处理输出结果的SPEC标准配置")]
|
||||||
|
|
||||||
|
// public List<IndexedSpec> OutputSpec_Pre { get; set; } = new List<IndexedSpec>();
|
||||||
|
|
||||||
|
[Category("1.预处理(视觉算子)")]
|
||||||
|
[DisplayName("预处理-参数列表")]
|
||||||
|
[Description("预处理-参数列表")]
|
||||||
|
|
||||||
|
public List<PreTreatParam> PreTreatParams { get; set; } = new List<PreTreatParam>();
|
||||||
|
|
||||||
|
[Category("1.预处理(视觉算子)")]
|
||||||
|
[DisplayName("预处理-输出参数列表")]
|
||||||
|
[Description("预处理-输出参数列表")]
|
||||||
|
|
||||||
|
public List<PreTreatParam> OUTPreTreatParams { get; set; } = new List<PreTreatParam>();
|
||||||
|
|
||||||
[Category("2.中检测(深度学习)")]
|
[Category("2.中检测(深度学习)")]
|
||||||
[DisplayName("中检测-模型类型")]
|
[DisplayName("中检测-模型类型")]
|
||||||
[Description("模型类型:ImageClassification-图片分类;ObjectDetection:目标检测;Segmentation-图像分割")]
|
[Description("模型类型:ImageClassification-图片分类;ObjectDetection:目标检测;Segmentation-图像分割")]
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using OpenCvSharp;
|
using OpenCvSharp;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
@ -85,6 +86,30 @@ namespace DH.Devices.Vision
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public class PreTreatParam
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数名称
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
[Category("预处理参数")]
|
||||||
|
[DisplayName("参数名称")]
|
||||||
|
[Description("参数名称")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数值
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
[Category("预处理参数")]
|
||||||
|
[DisplayName("参数值")]
|
||||||
|
[Description("参数值")]
|
||||||
|
public string Value { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public static class MLGPUEngine
|
public static class MLGPUEngine
|
||||||
{
|
{
|
||||||
|
35
DH.Devices.Vision/SimboVisionModel.cs
Normal file
35
DH.Devices.Vision/SimboVisionModel.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DH.Devices.Vision
|
||||||
|
{
|
||||||
|
//工站 模型检测引擎
|
||||||
|
public class SimboStationMLEngineSet
|
||||||
|
{
|
||||||
|
public bool IsUseGPU { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// GPU设备号
|
||||||
|
/// </summary>
|
||||||
|
public int GPUNo { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// CPU线程号
|
||||||
|
/// </summary>
|
||||||
|
public int CPUNo { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 检测配置ID
|
||||||
|
/// </summary>
|
||||||
|
public string DetectionId { get; set; }
|
||||||
|
|
||||||
|
public string DetectionName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 深度学习模型
|
||||||
|
/// </summary>
|
||||||
|
public SimboVisionMLBase StationMLEngine { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,18 @@
|
|||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Views\CamConfigFrm.cs" />
|
||||||
|
<Compile Include="Views\CamConfigFrm.Designer.cs" />
|
||||||
|
<Compile Include="Views\UserConfigFrm.cs" />
|
||||||
|
<Compile Include="Views\UserConfigFrm.Designer.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Views\CamConfigFrm.resx" />
|
||||||
|
<EmbeddedResource Include="Views\UserConfigFrm.resx" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AntdUI" Version="1.8.9" />
|
<PackageReference Include="AntdUI" Version="1.8.9" />
|
||||||
<PackageReference Include="System.IO.Ports" Version="9.0.2" />
|
<PackageReference Include="System.IO.Ports" Version="9.0.2" />
|
||||||
@ -19,6 +31,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\DH.Devices.Camera\DH.Devices.Camera.csproj" />
|
<ProjectReference Include="..\DH.Devices.Camera\DH.Devices.Camera.csproj" />
|
||||||
|
<ProjectReference Include="..\DH.Devices.Motion\DH.Devices.Motion.csproj" />
|
||||||
<ProjectReference Include="..\DH.Devices.PLC\DH.Devices.PLC.csproj" />
|
<ProjectReference Include="..\DH.Devices.PLC\DH.Devices.PLC.csproj" />
|
||||||
<ProjectReference Include="..\DH.Devices.Vision\DH.Devices.Vision.csproj" />
|
<ProjectReference Include="..\DH.Devices.Vision\DH.Devices.Vision.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -27,6 +40,12 @@
|
|||||||
<Reference Include="DVPCameraCS64">
|
<Reference Include="DVPCameraCS64">
|
||||||
<HintPath>..\x64\Debug\DVPCameraCS64.dll</HintPath>
|
<HintPath>..\x64\Debug\DVPCameraCS64.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="halcondotnet">
|
||||||
|
<HintPath>..\x64\Debug\halcondotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="hdevenginedotnet">
|
||||||
|
<HintPath>..\x64\Debug\hdevenginedotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
39
DHSoftware/MainWindow.Designer.cs
generated
39
DHSoftware/MainWindow.Designer.cs
generated
@ -41,6 +41,7 @@
|
|||||||
button_color = new AntdUI.Button();
|
button_color = new AntdUI.Button();
|
||||||
buttonSZ = new AntdUI.Button();
|
buttonSZ = new AntdUI.Button();
|
||||||
pageHeader1 = new AntdUI.PageHeader();
|
pageHeader1 = new AntdUI.PageHeader();
|
||||||
|
label1 = new Label();
|
||||||
divider2 = new AntdUI.Divider();
|
divider2 = new AntdUI.Divider();
|
||||||
panelmain = new AntdUI.Panel();
|
panelmain = new AntdUI.Panel();
|
||||||
panel2 = new AntdUI.Panel();
|
panel2 = new AntdUI.Panel();
|
||||||
@ -56,11 +57,9 @@
|
|||||||
panel3 = new AntdUI.Panel();
|
panel3 = new AntdUI.Panel();
|
||||||
tabs2 = new AntdUI.Tabs();
|
tabs2 = new AntdUI.Tabs();
|
||||||
tabPage2 = new AntdUI.TabPage();
|
tabPage2 = new AntdUI.TabPage();
|
||||||
pictureBox1 = new PictureBox();
|
|
||||||
divider1 = new AntdUI.Divider();
|
divider1 = new AntdUI.Divider();
|
||||||
panel1 = new AntdUI.Panel();
|
panel1 = new AntdUI.Panel();
|
||||||
segmented1 = new AntdUI.Segmented();
|
segmented1 = new AntdUI.Segmented();
|
||||||
label1 = new Label();
|
|
||||||
titlebar.SuspendLayout();
|
titlebar.SuspendLayout();
|
||||||
pageHeader1.SuspendLayout();
|
pageHeader1.SuspendLayout();
|
||||||
panelmain.SuspendLayout();
|
panelmain.SuspendLayout();
|
||||||
@ -73,8 +72,6 @@
|
|||||||
tabPage3.SuspendLayout();
|
tabPage3.SuspendLayout();
|
||||||
panel3.SuspendLayout();
|
panel3.SuspendLayout();
|
||||||
tabs2.SuspendLayout();
|
tabs2.SuspendLayout();
|
||||||
tabPage2.SuspendLayout();
|
|
||||||
((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();
|
|
||||||
panel1.SuspendLayout();
|
panel1.SuspendLayout();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
@ -139,6 +136,15 @@
|
|||||||
pageHeader1.TabIndex = 7;
|
pageHeader1.TabIndex = 7;
|
||||||
pageHeader1.Text = "UPH";
|
pageHeader1.Text = "UPH";
|
||||||
//
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(61, 10);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(64, 21);
|
||||||
|
label1.TabIndex = 1;
|
||||||
|
label1.Text = "100000";
|
||||||
|
//
|
||||||
// divider2
|
// divider2
|
||||||
//
|
//
|
||||||
divider2.Dock = DockStyle.Top;
|
divider2.Dock = DockStyle.Top;
|
||||||
@ -285,22 +291,11 @@
|
|||||||
//
|
//
|
||||||
// tabPage2
|
// tabPage2
|
||||||
//
|
//
|
||||||
tabPage2.Controls.Add(pictureBox1);
|
|
||||||
tabPage2.Location = new Point(3, 28);
|
tabPage2.Location = new Point(3, 28);
|
||||||
tabPage2.Name = "tabPage2";
|
tabPage2.Name = "tabPage2";
|
||||||
tabPage2.Size = new Size(347, 469);
|
tabPage2.Size = new Size(347, 469);
|
||||||
tabPage2.TabIndex = 0;
|
tabPage2.TabIndex = 0;
|
||||||
tabPage2.Text = "统计";
|
tabPage2.Text = "配置";
|
||||||
//
|
|
||||||
// pictureBox1
|
|
||||||
//
|
|
||||||
pictureBox1.Dock = DockStyle.Fill;
|
|
||||||
pictureBox1.Location = new Point(0, 0);
|
|
||||||
pictureBox1.Name = "pictureBox1";
|
|
||||||
pictureBox1.Size = new Size(347, 469);
|
|
||||||
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
|
|
||||||
pictureBox1.TabIndex = 0;
|
|
||||||
pictureBox1.TabStop = false;
|
|
||||||
//
|
//
|
||||||
// divider1
|
// divider1
|
||||||
//
|
//
|
||||||
@ -401,15 +396,6 @@
|
|||||||
segmented1.Text = "segmented1";
|
segmented1.Text = "segmented1";
|
||||||
segmented1.SelectIndexChanged += segmented1_SelectIndexChanged;
|
segmented1.SelectIndexChanged += segmented1_SelectIndexChanged;
|
||||||
//
|
//
|
||||||
// label1
|
|
||||||
//
|
|
||||||
label1.AutoSize = true;
|
|
||||||
label1.Location = new Point(61, 10);
|
|
||||||
label1.Name = "label1";
|
|
||||||
label1.Size = new Size(64, 21);
|
|
||||||
label1.TabIndex = 1;
|
|
||||||
label1.Text = "100000";
|
|
||||||
//
|
|
||||||
// MainWindow
|
// MainWindow
|
||||||
//
|
//
|
||||||
ClientSize = new Size(1024, 648);
|
ClientSize = new Size(1024, 648);
|
||||||
@ -438,8 +424,6 @@
|
|||||||
tabPage3.ResumeLayout(false);
|
tabPage3.ResumeLayout(false);
|
||||||
panel3.ResumeLayout(false);
|
panel3.ResumeLayout(false);
|
||||||
tabs2.ResumeLayout(false);
|
tabs2.ResumeLayout(false);
|
||||||
tabPage2.ResumeLayout(false);
|
|
||||||
((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();
|
|
||||||
panel1.ResumeLayout(false);
|
panel1.ResumeLayout(false);
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
}
|
}
|
||||||
@ -468,7 +452,6 @@
|
|||||||
private AntdUI.TabPage tabPage2;
|
private AntdUI.TabPage tabPage2;
|
||||||
private AntdUI.Divider divider1;
|
private AntdUI.Divider divider1;
|
||||||
private RichTextBox richTextBox1;
|
private RichTextBox richTextBox1;
|
||||||
private PictureBox pictureBox1;
|
|
||||||
private Label label1;
|
private Label label1;
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
|
|
||||||
Version 2.0
|
Version 2.0
|
||||||
|
|
||||||
@ -48,7 +48,7 @@
|
|||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
44
DHSoftware/Views/CamConfigFrm.Designer.cs
generated
Normal file
44
DHSoftware/Views/CamConfigFrm.Designer.cs
generated
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
namespace DHSoftware.Views
|
||||||
|
{
|
||||||
|
partial class CamConfigFrm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有正在使用的资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// CamConfigFrm
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
Name = "CamConfigFrm";
|
||||||
|
Size = new Size(869, 521);
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
20
DHSoftware/Views/CamConfigFrm.cs
Normal file
20
DHSoftware/Views/CamConfigFrm.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace DHSoftware.Views
|
||||||
|
{
|
||||||
|
public partial class CamConfigFrm : UserControl
|
||||||
|
{
|
||||||
|
public CamConfigFrm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
DHSoftware/Views/CamConfigFrm.resx
Normal file
120
DHSoftware/Views/CamConfigFrm.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
44
DHSoftware/Views/UserConfigFrm.Designer.cs
generated
Normal file
44
DHSoftware/Views/UserConfigFrm.Designer.cs
generated
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
namespace DHSoftware.Views
|
||||||
|
{
|
||||||
|
partial class UserConfigFrm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有正在使用的资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// UserConfigFrm
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
Name = "UserConfigFrm";
|
||||||
|
Size = new Size(749, 536);
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
20
DHSoftware/Views/UserConfigFrm.cs
Normal file
20
DHSoftware/Views/UserConfigFrm.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace DHSoftware.Views
|
||||||
|
{
|
||||||
|
public partial class UserConfigFrm : UserControl
|
||||||
|
{
|
||||||
|
public UserConfigFrm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
DHSoftware/Views/UserConfigFrm.resx
Normal file
120
DHSoftware/Views/UserConfigFrm.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
@ -78,16 +78,16 @@ namespace DHSoftware
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void InferenceOne(Action preAction = null, Action postAction = null)
|
public void InferenceOne()
|
||||||
{
|
{
|
||||||
//lock (_inferenceLock)
|
//lock (_inferenceLock)
|
||||||
//{
|
//{
|
||||||
// Interlocked.Decrement(ref InferenceLeft);
|
// Interlocked.Decrement(ref InferenceLeft);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
preAction?.Invoke();
|
|
||||||
_countdownEvent.Signal();
|
_countdownEvent.Signal();
|
||||||
postAction?.Invoke();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool InferenceFinished()
|
public bool InferenceFinished()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user