想用3D扫描后的图片,但是系统自带的导出方法很麻烦,所以考虑通过sdk导出
首先需要设置点云亮度
这里是导出图片的关键代码
case GoDataMessageType.SurfaceIntensity:
{
Debug.WriteLine("SurfaceIntensity ");
GoSurfaceIntensityMsg surfaceMsg = (GoSurfaceIntensityMsg)dataObj;
long width = surfaceMsg.Width;
long length = surfaceMsg.Length;
long bufferSize = width * length;
IntPtr bufferPointeri = surfaceMsg.Data;//Console.WriteLine("Surface Intensity received:");
//Console.WriteLine(" Buffer width: {0}", width);
//Console.WriteLine(" Buffer length: {0}", length);
byte[] ranges = new byte[bufferSize];Marshal.Copy(bufferPointeri, ranges, 0, ranges.Length);
Mat mat1 = new Mat((int)length, (int)width, MatType.CV_8UC1, bufferPointeri);
//Mat mat = Cv2.ImDecode(ranges, ImreadModes.Grayscale);
long UID = YitIdHelper.NextId();
string GlueImageDir = LogsUtil.GetLogDir(LogsUtil.GlueImage);
ImageFile = await FileHelper.SaveVisionImage1(mat1, GlueImageDir, $"Glue3Dimage_{gm.TireBarcode}_{UID}.png");
}
break;
using Camera3D.Models.Glue;
using Camera3D.Utils;
using FluentFTP;
using Google.Protobuf.WellKnownTypes;
using JHCamera3D.Helper.Python;
using JHCamera3D.Utils;//using Intel.RealSense;
using LinkAsiaSmart.MyTask;
using Lmi3d.GoSdk;
using Lmi3d.GoSdk.Messages;
using OpenCvSharp;
using System.Collections;
using System.Drawing.Imaging;
using System.Threading;
using System.Windows.Forms;
using Yitter.IdGenerator;
using static Camera3D.Enum.LMI.ReceiveProfile;
using static Emgu.CV.WeChatQRCode;
using static Slapper.AutoMapper;namespace Camera3D.Helper.TCP
{/// <summary>/// /// </summary>public class Camera3DGlue{public delegate void OnDataType(KObject data);public static Camera3DGlue? Instance;public static bool isSaveDataToMySql = true;public static bool isGoLoad = false;public static bool isStart = false;public static bool isCanStatus = false;private static double TireInsideLength = 0;private static double EncoderResolution = 0;GoDataSet dataSet;static GoSystem system;static GoSensor sensor;static GoSurfaceGeneration surfacelength;public static Camera3DGlue GetInstance(){if (Instance == null){Instance = new Camera3DGlue();}return Instance;}public bool GoLoad()//加载Gocator{string ip = SystemParams.Camera3D.LMI3DGlueCameraIP; // "192.168.1.10";uint SensorID = uint.Parse(SystemParams.Camera3D.LMI3DGlueCameraSensorID); // "192.168.1.10";KApiLib.Construct();GoSdkLib.Construct();system = new GoSystem();dataSet = new GoDataSet();try{sensor = system.FindSensorById(SensorID);//指定传感器的ID连接 if (sensor.State == GoState.Running){sensor.Stop();sensor.Disconnect();};sensor.Connect();//double encoder = sensor.Transform.EncoderResolution;EncoderResolution = sensor.Transform.EncoderResolution;TireInsideLength = sensor.Setup.GetSurfaceGeneration().FixedLengthLength;system.EnableData(true);//数据通道使能system.SetDataHandler(onData);//异步接受数据isGoLoad = true;}catch (Exception ex){return false;}return true;}public static void Start(){try{if (sensor == null){return;}sensor.Stop();surfacelength = sensor.Setup.GetSurfaceGeneration(); sensor.Start();isStart = true;isCanStatus = true;}catch (Exception ex){Log.Logger.Error($" 异常 {ex.Message}");}}public static void Stop(){try{sensor.Stop();isCanStatus = false;}catch (Exception ex){Log.Logger.Error($"Sensor Stop 异常 {ex.Message}");}}public static GoState GetStatus(){GoState state = GoState.Offline;// new GoState();// state = GoState.Offline;if (isCanStatus){try{state = sensor.State.Value;}catch (Exception ex){Log.Logger.Error($" 异常 {ex.Message}");}}return state;}public static async void onData(KObject data){int mb = 1024 * 1024;Process currentProcess = Process.GetCurrentProcess();long workingSet = currentProcess.WorkingSet64;Log.Logger.Debug($" 占用内存{workingSet / mb}MB");Random rdm = new Random(Guid.NewGuid().GetHashCode());GlueModel gm = new GlueModel();gm.DateTime = DateUtil.CurrentDate.ToString();gm.TireBarcode = PLCTag.GetTagValue(TagNameDesc.GlueTireBarcode, TagValueType.String); // Work.PLC.Glue.GetGlueTireBarcode();string PLYName = $"Glue_{gm.TireBarcode}_{YitIdHelper.NextId()}";string ImageFile = "";GlueCompensationModel gcm = new GlueCompensationModel();float GlueTireInnerCircumference = float.Parse(PLCTag.GetTagValue(TagNameDesc.GlueTireInnerCircumference, TagValueType.Float)); // Work.PLC.TagValue.GetGlueTireInnerCircumference();Log.Logger.Debug($"接受到 3D 数据 ");try{DataContext context = new DataContext(); GoDataSet dataSet = (GoDataSet)data;for (UInt32 i = 0; i < dataSet.Count; i++){GoDataMsg dataObj = (GoDataMsg)dataSet.Get(i);// Debug.WriteLine($"GoDataMsg.MessageType:{dataObj.MessageType}");Log.Logger.Debug($" GoDataMsg.MessageType : {dataObj.MessageType} ");switch (dataObj.MessageType){case GoDataMessageType.Stamp:{GoStampMsg stampMsg = (GoStampMsg)dataObj;for (UInt32 j = 0; j < stampMsg.Count; j++){GoStamp stamp = stampMsg.Get(j);//Debug.WriteLine("Frame Index = {0}", stamp.FrameIndex);//Debug.WriteLine("Time Stamp = {0}", stamp.Timestamp);//Debug.WriteLine("Encoder Value = {0}", stamp.Encoder);// Debug.WriteLine($"{i} -{j} Index = {stamp.FrameIndex} time = {stamp.Timestamp} value = {stamp.Encoder}");//Debug.WriteLine($" {stampMsg.Count} ");// LsData.Add(stamp.Encoder.ToString());}//}break;case GoDataMessageType.UniformSurface:{try{GoUniformSurfaceMsg surfaceMsg = (GoUniformSurfaceMsg)dataObj;long width = surfaceMsg.Width; //被测物体宽度long length = surfaceMsg.Length; //3D相机走过的长度long bufferSize = (width * length);IntPtr bufferPointer = surfaceMsg.Data;//获取缓存的宽高long surfaceBufferWidth = surfaceMsg.Width;long surfaceBufferLength = surfaceMsg.Length;float[] x = new float[surfaceBufferLength * surfaceBufferWidth];float[] y = new float[surfaceBufferLength * surfaceBufferWidth];float[] z = new float[surfaceBufferLength * surfaceBufferWidth];// byte[] intensity = new byte[surfaceBufferLength * surfaceBufferWidth];SurfacePoint[] surfaceBuffer = new SurfacePoint[surfaceBufferLength * surfaceBufferWidth];List<SurfacePoint> ListSurface = new List<SurfacePoint>();short[] ranges = new short[bufferSize];Marshal.Copy(bufferPointer, ranges, 0, ranges.Length);// Marshal.Copy(bufferPointer, intensity, 0, ranges.Length);//string rangesStr = string.Join(",", ranges);Log.Logger.Debug($"Surface Width = {width} length = {length} bufferSize = {bufferSize} ");double xResolution = (double)surfaceMsg.XResolution / 1000000;double yResolution = (double)surfaceMsg.YResolution / 1000000;double zResolution = (double)surfaceMsg.ZResolution / 1000000;// YDotPitch = yResolution;context.xResolution = (float)surfaceMsg.XResolution / 1000000;context.yResolution = (float)surfaceMsg.YResolution / 1000000;context.zResolution = (float)surfaceMsg.ZResolution / 1000000;context.xOffset = (float)surfaceMsg.XOffset / 1000;context.yOffset = (float)surfaceMsg.YOffset / 1000;context.zOffset = (float)surfaceMsg.ZOffset / 1000;long surfacePointCount = surfaceMsg.Width * surfaceMsg.Length;for (int j = 0; j < length; j++){for (int k = 0; k < width; k++){y[width * j + k] = (float)(k * context.xResolution + context.xOffset);x[width * j + k] = (float)(j * context.yResolution + context.yOffset);short tmp = ranges[width * j + k];z[width * j + k] = tmp == -32768 ? -32768 : (float)(tmp * context.zResolution + context.zOffset);// intensity[width * j + k]= context.//if (tmp == -32768)//{// z[width * j + k] = -32768;//}//else//{// z[width * j + k] = (float)(tmp * context.zResolution + context.zOffset);//}surfaceBuffer[width * j + k].x = x[width * j + k];surfaceBuffer[width * j + k].y = y[width * j + k];surfaceBuffer[width * j + k].z = z[width * j + k];}}//Mat mat = Cv2.ImDecode(intensity, ImreadModes.Color);//long UID = YitIdHelper.NextId();//FileHelper.SaveVisionImage1(mat, $"Glue3Dimage_{UID}.png");Log.Logger.Debug($"接收到相机点云数量 = {surfacePointCount} ");ListSurface = surfaceBuffer.Where(a => a.z >= -10000).ToList();//PointCloudUtil.SavePointCloudToPLY(No, x, y, z);string PLYFile = await PointCloudUtil.SavePointCloudToPLY(PLYName, ListSurface.ToArray(), LogsUtil.GluePLY);//PointCloudUtil.SavePointCloudToPLY(No, x, y, z);DateTime startTime = DateTime.Now;while (!File.Exists(PLYFile)){if (DateTime.Now - startTime > TimeSpan.FromSeconds(10)){break;}await Task.Delay(200);}if (File.Exists(PLYFile)){ProcessPLYGlueStrip(PLYFile, gcm);}else{Log.Logger.Error($" 未找到ply文件 {PLYFile}");}x = null;y = null;z = null;ranges = null;surfaceBuffer = null;ListSurface.Clear();ListSurface = null;bufferPointer = IntPtr.Zero;}catch (Exception e){Log.Logger.Error($" GoDataMessageType.Surface 数据处理异常 = {e.Message} {e.StackTrace} ");}}break;case GoDataMessageType.SurfacePointCloud:{GoSurfacePointCloudMsg surfaceMsg = (GoSurfacePointCloudMsg)dataObj;context.xResolution = (double)surfaceMsg.XResolution / 1000000;context.yResolution = (double)surfaceMsg.YResolution / 1000000;context.zResolution = (double)surfaceMsg.ZResolution / 1000000;context.xOffset = (double)surfaceMsg.XOffset / 1000;context.yOffset = (double)surfaceMsg.YOffset / 1000;context.zOffset = (double)surfaceMsg.ZOffset / 1000;long surfacePointCount = surfaceMsg.Width * surfaceMsg.Length;Console.WriteLine("Surface Point Cloud received:");Console.WriteLine(" Buffer width: {0}", surfaceMsg.Width);Console.WriteLine(" Buffer length: {0}", surfaceMsg.Length);GoPoints[] points = new GoPoints[surfacePointCount];SurfacePoint[] surfaceBuffer = new SurfacePoint[surfacePointCount];int structSize = Marshal.SizeOf(typeof(GoPoints));IntPtr pointsPtr = surfaceMsg.Data;for (UInt32 array = 0; array < surfacePointCount; ++array){IntPtr incPtr = new IntPtr(pointsPtr.ToInt64() + array * structSize);points[array] = (GoPoints)Marshal.PtrToStructure(incPtr, typeof(GoPoints));}for (UInt32 arrayIndex = 0; arrayIndex < surfacePointCount; ++arrayIndex){if (points[arrayIndex].x != -32768){surfaceBuffer[arrayIndex].x = context.xOffset + context.xResolution * points[arrayIndex].x;surfaceBuffer[arrayIndex].y = context.yOffset + context.yResolution * points[arrayIndex].y;surfaceBuffer[arrayIndex].z = context.zOffset + context.zResolution * points[arrayIndex].z;}else{surfaceBuffer[arrayIndex].x = -32768;surfaceBuffer[arrayIndex].y = -32768;surfaceBuffer[arrayIndex].z = -32768;}}}break;case GoDataMessageType.SurfaceIntensity:{Debug.WriteLine("SurfaceIntensity ");GoSurfaceIntensityMsg surfaceMsg = (GoSurfaceIntensityMsg)dataObj;long width = surfaceMsg.Width;long length = surfaceMsg.Length;long bufferSize = width * length;IntPtr bufferPointeri = surfaceMsg.Data;//Console.WriteLine("Surface Intensity received:");//Console.WriteLine(" Buffer width: {0}", width);//Console.WriteLine(" Buffer length: {0}", length);byte[] ranges = new byte[bufferSize];Marshal.Copy(bufferPointeri, ranges, 0, ranges.Length);Mat mat1 = new Mat((int)length, (int)width, MatType.CV_8UC1, bufferPointeri);//Mat mat = Cv2.ImDecode(ranges, ImreadModes.Grayscale);long UID = YitIdHelper.NextId();string GlueImageDir = LogsUtil.GetLogDir(LogsUtil.GlueImage);ImageFile = await FileHelper.SaveVisionImage1(mat1, GlueImageDir, $"Glue3Dimage_{gm.TireBarcode}_{UID}.png");}break;}} Log.Logger.Debug($"完成3D相机的数据"); Download3DImage(ImageFile);}catch (Exception ex){Log.Logger.Error($"Camera3D Error {ex.Message}");}GlobalConst.Common.SharedLock = false;workingSet = currentProcess.WorkingSet64;Log.Logger.Debug($"接收3D相机数据后 占用内存{workingSet / mb}MB");}public float GetLength(){return (float)TireInsideLength;}public string SetLength(double length){string result = "";try{Stop();surfacelength = sensor.Setup.GetSurfaceGeneration();//surfacelength.FixedLengthTriggerExternalInputIndex = length;surfacelength.FixedLengthLength = length;Log.Logger.Debug($"设置 3D相机触发轮胎内周长 PLC = [{length}] OK");Start();result = "OK";TireInsideLength = length;}catch (Exception ex){result = "ERROR";Log.Logger.Error($"设置 3D相机触发长度异常 {ex.Message}");}return result;}public string SetEncoderResolution(double value){string result = "";if (value <= 0){return result;}try{Stop();// sensor.Setup.EncoderSpacing = value;sensor.Transform.EncoderResolution = value;Log.Logger.Debug($"设置 3D相机分辨率OK {value}");Start();result = "OK";}catch (Exception ex){result = "ERROR";Log.Logger.Error($"设置 3D相机分辨率异常 value={value} msg={ex.Message}");}return result;}public string GetEncoder(){string result = "";try{if (isCanStatus){if (sensor.State.Value == GoState.Running){result = sensor.Encoder().ToString();}}}catch (Exception ex){Log.Logger.Error($"读取 3D相机编码器数值异常 value = {result} {sensor.State} msg = {ex.Message}");}return result;} public static string Download3DImage(string ImageFile){string result = "";Task.Run(async () =>{ try{EncoderResolution = sensor.Transform.EncoderResolution;TireInsideLength = sensor.Setup.GetSurfaceGeneration().FixedLengthLength;result = "OK";string JPGImageFile = await ConvertToJPG(ImageFile);SignalRClient.GetInstance().SendMsg(GlobalConst.SignalRUser.Glue.Camera3DGlueImage, JPGImageFile); }catch (Exception ex){Log.Logger.Error($" 3D相机 图片出现异常 {ex.Message}");result = "Error";}});return result;}public static async Task<string> ConvertToJPG(string ImageFile){DateTime startTime = DateTime.Now;while (!File.Exists(ImageFile)){if (DateTime.Now - startTime > TimeSpan.FromSeconds(10)){break;}await Task.Delay(200);}Log.Logger.Debug($"PNG转JPG文件 [{ImageFile}]");string extension = Path.GetExtension(ImageFile);Log.Logger.Debug($"PNG转JPG文件 [{extension}]");string JpgImageFile = ImageFile.Replace(extension, ".jpg");//string result = "";//int x = 0;await Task.Run(async () =>{try{using (Image image = Image.FromFile(ImageFile)){image.Save(JpgImageFile, ImageFormat.Jpeg);}}catch (Exception ex){Log.Logger.Error($"PNG转JPG异常 {ex.Message}");// result = "Error";}});return JpgImageFile;}public static async Task<string> ProcessPLYGlueStrip(string PLYFile, GlueCompensationModel gcm){string result = "";string No = "Glue" + DateUtil.CurrentDateID;string ScriptFile = AppSettingsHelper.Configuration["PythonScript:GlueScriptFile"];Log.Logger.Debug($" Open3D 测量 脚本 {ScriptFile}");string PlyResultDir = LogsUtil.GetLogDir(LogsUtil.GlueResultPLY);string str = RunPythonHelper.ExecPythonTireGlue(ScriptFile, PLYFile, PlyResultDir);Log.Logger.Debug($" Open3D 计算结果 {str}");string[] JsonStrResult = str.Split("~~");try{if (JsonStrResult[2].Trim().Length > 1){Log.Logger.Error($" errMsg = {JsonStrResult[2]}");}else{GluePlyResultModel gprm = JsonConvert.DeserializeObject<GluePlyResultModel>(JsonStrResult[1]);gprm.Barcode = PLCTag.GetTagValue(TagNameDesc.GlueTireBarcode, TagValueType.String); gprm.DateTime = DateUtil.CurrentDate.ToString();gprm = GetCompensationResult(gprm, gcm);string jsonStr = JsonConvert.SerializeObject(gprm);SignalRClient.GetInstance().SendMsg(GlobalConst.SignalRUser.Glue.Glue3DResult, jsonStr);}}catch (Exception ex){Log.Logger.Error($"处理 Open3D 计算结果异常 {ex.Message}");} return result;}}
}