当前位置: 首页 > news >正文

相机通用类之LMI激光三角相机(3D),软触发硬触发(飞拍),并输出halcon格式对象

//在此之前可以先浏览我编写的通用上位机类,更方便理解
https://blog.csdn.net/m0_51559565/article/details/134403745

最近完成一个关于LMI激光三角(3D相机)采图的demo,记录并说明用法。
先上代码。

using Lmi3d.GoSdk;
using Lmi3d.Zen;
using System;
using System.Collections.Generic;
using HalconDotNet;
using Lmi3d.GoSdk.Messages;
using System.Runtime.InteropServices;
using System.IO;
using WeldingInspection.MyCamer;namespace WeldingInspection
{internal class LMISDK: MyBaseCamera{GoSensor MyLMICamer = null;//创建LMI相机传感器对象GoSystem goSystem = new GoSystem();//创建LMI系统信息List<string> LMICamerName = new List<string>();//获取相机序列号HObject Himage3D=new HObject();public LMISDK(){//KApiLib.Construct();激活API库//GoSdkLib.Construct();}/// <summary>/// 查找相机,并输出序列号/// </summary>/// <returns></returns>public override List<string> FindCamer(){long size = goSystem.SensorCount;for (int i = 0; i < size; i++){GoAddressInfo addressInfo = goSystem.GetSensor(i).Address();LMICamerName.Add(goSystem.GetSensor(i).Id.ToString());}foreach (var item in LMICamerName){Console.WriteLine("当前连接相机有:" + item);}return LMICamerName;}/// <summary>/// 根据序列号开启相机/// </summary>/// <param name="CamerName"></param>/// <returns></returns>public override bool OpenCamer(string CamerName){uint LMIName;if (!uint.TryParse(CamerName,out LMIName)){return false;}if (LMICamerName.Count == 0 && MyLMICamer == null){return false;}//关闭设备CloseCamer();//通过ID找到Gocator SensorMyLMICamer = new GoSystem().FindSensorById(LMIName);MyLMICamer.Connect();//连接成功if (MyLMICamer.IsConnected()){MyLMICamer.EnableData(true);//开启允许相机采集//MyLMICamer.SetDataHandler(onData);//注册回调函数,生成未标定的16位深度图//MyLMICamer.SetDataHandler(onData_GenTL);//注册回调函数获得GenTL图MyLMICamer.SetDataHandler(onData_Calib);//注册回调函数,生成具有标定数据的,16位深度图}else{Console.WriteLine("开启LMI相机失败");MyLMICamer = null;return false;}return true;}/// <summary>/// 关闭相机/// </summary>/// <returns></returns>public override bool CloseCamer(){try{if (MyLMICamer != null){//停止采集MyLMICamer.Stop();return true;}return false;}catch (Exception ex){Console.WriteLine("相机停止采集异常", ex);return false;}}/// <summary>/// 相机重连/// </summary>/// <param name="CamerName"></param>/// <returns></returns>public override bool ReconnectCamer(string CamerName){uint LMIName;if (!uint.TryParse(CamerName, out LMIName)){return false;}if (LMICamerName.Count == 0 && MyLMICamer == null){return false;}//关闭设备CloseCamer();//通过ID找到Gocator SensorMyLMICamer = new GoSystem().FindSensorById(LMIName);MyLMICamer.Connect();//连接成功if (MyLMICamer.IsConnected()){MyLMICamer.EnableData(true);//开启允许相机采集//MyLMICamer.SetDataHandler(onData);//注册回调函数,生成未标定的16位深度图//MyLMICamer.SetDataHandler(onData_GenTL);//注册回调函数获得GenTL图,可以用于表面缺陷检测MyLMICamer.SetDataHandler(onData_Calib);//注册回调函数,生成具有标定数据的,16位深度图}else{Console.WriteLine("开启LMI相机失败");MyLMICamer = null;return false;}return true;}/// <summary>/// 软触发一次/// </summary>/// <returns></returns>public override bool OneGrap(){try{if (MyLMICamer.State == GoState.Running){MyLMICamer.Stop();MyLMICamer.Start();}else{MyLMICamer.Start();}return true;}catch (Exception){return false;}}/// <summary>/// 设置硬触发/// </summary>/// <returns></returns>public override bool EncoderGrap(){MyLMICamer.Setup.TriggerSource = GoTrigger.Encoder;MyLMICamer.Flush();return true;}/// <summary>/// 将配置文件上传到相机中/// </summary>/// <param name="Address">文件所在绝对路径</param>/// <param name="FileName">文件名称</param>/// <returns></returns>public bool UpLoad_Camer_file(string Address,string FileName){try{MyLMICamer.Stop();MyLMICamer.UploadFile(Address, FileName);MyLMICamer.Flush();return true;}catch (Exception){return false;}}/// <summary>/// 输出高度信息以毫米(mm)为单位,带标定结果/// </summary>/// <param name="data"></param>public void onData_Calib(KObject data){//x图HObject GenTL16BitRGBRedImage = new HObject();//y图HObject GenTL16BitRGBGreenImage = new HObject();//z图HObject GenTL16BitRGBBlueImage = new HObject();try{GoDataSet dataSet = (GoDataSet)data;for (uint i = 0; i < dataSet.Count; i++){GoDataMsg dataObj = (GoDataMsg)dataSet.Get(i);switch (dataObj.MessageType){case GoDataMessageType.UniformSurface:{GoUniformSurfaceMsg surfaceMsg = (GoUniformSurfaceMsg)dataObj;//获取缓存的宽高surfaceBufferWidth = surfaceMsg.Width;surfaceBufferLength = surfaceMsg.Length;double xResolution = (double)surfaceMsg.XResolution / 1000000;double yResolution = (double)surfaceMsg.YResolution / 1000000;double zResolution = (double)surfaceMsg.ZResolution / 1000000;Console.WriteLine("3d标定数据:X方向:"+xResolution+"Y方向:"+yResolution);//double xOffset = (double)surfaceMsg.XOffset / 1000;//double yOffset = (double)surfaceMsg.YOffset / 1000;double zOffset = (double)surfaceMsg.ZOffset / 1000;IntPtr bufferPointeri = surfaceMsg.Data;//short[] x = new short[surfaceBufferLength * surfaceBufferWidth];//short[] y = new short[surfaceBufferLength * surfaceBufferWidth];short[] z = new short[surfaceBufferLength * surfaceBufferWidth];//声明存放surface的Buffer//short[] surfaceBuffer = new short[surfaceBufferWidth * surfaceBufferLength];//将传感器给的值拷贝到我们声明的数组中Marshal.Copy(bufferPointeri, z, 0, Convert.ToInt32(surfaceBufferWidth * surfaceBufferLength));//for (short row = 0; row < surfaceBufferLength; row++)//{//    for (short col = 0; col < surfaceMsg.Width; col++)//    {//        x[row * surfaceMsg.Width + col] = col;//        y[row * surfaceMsg.Width + col] = row;//    }//}//将传感器数据存储至生命的内存空间中// Marshal.Copy(bufferPointeri, surfaceBuffer, 0, surfaceBuffer.Length);unsafe{fixed (short* p = z)HOperatorSet.GenImage1(out GenTL16BitRGBBlueImage, "int2", surfaceBufferWidth, surfaceBufferLength, new IntPtr(p));//fixed (short* p = x)//    HOperatorSet.GenImage1(out GenTL16BitRGBRedImage, "int2", surfaceBufferWidth, surfaceBufferLength, new IntPtr(p));//fixed (short* p = y)//    HOperatorSet.GenImage1(out GenTL16BitRGBGreenImage, "int2", surfaceBufferWidth, surfaceBufferLength, new IntPtr(p));}//以下注释部分可生成三通道图像//HOperatorSet.ConvertImageType(GenTL16BitRGBRedImage, out GenTL16BitRGBRedImage, "real");//HOperatorSet.ScaleImage(GenTL16BitRGBRedImage, out GenTL16BitRGBRedImage, xResolution, xOffset);//HOperatorSet.WriteImage(GenTL16BitRGBRedImage, new HTuple("tiff"), new HTuple(0), "E:\\UpperComputer\\LMI\\LMIHalconImage\\x.tiff");//HOperatorSet.ConvertImageType(GenTL16BitRGBGreenImage, out GenTL16BitRGBGreenImage, "real");//HOperatorSet.ScaleImage(GenTL16BitRGBGreenImage, out GenTL16BitRGBGreenImage, yResolution, yOffset);//HOperatorSet.ScaleImage(GenTL16BitRGBGreenImage, out GenTL16BitRGBGreenImage, -1, 0);//HOperatorSet.WriteImage(GenTL16BitRGBGreenImage, new HTuple("tiff"), new HTuple(0), "E:\\UpperComputer\\LMI\\LMIHalconImage\\y.tiff");HOperatorSet.ConvertImageType(GenTL16BitRGBBlueImage, out GenTL16BitRGBBlueImage, "real");HOperatorSet.ScaleImage(GenTL16BitRGBBlueImage, out Himage3D, zResolution, zOffset);//映射标定数据//HOperatorSet.WriteImage(Himage3D, new HTuple("tiff"), new HTuple(0), "E:\\UpperComputer\\LMI\\LMIHalconImage\\z.tiff");//HOperatorSet.Compose3(GenTL16BitRGBRedImage, GenTL16BitRGBGreenImage, GenTL16BitRGBBlueImage,out HObject Halcon3DImage);//HOperatorSet.WriteImage(Halcon3DImage, new HTuple("tiff"), new HTuple(0), "E:\\UpperComputer\\LMI\\LMIHalconImage\\3d.tiff");GetImage(Himage3D);}break;}}//生成3d模型//HOperatorSet.XyzToObjectModel3d(GenTL16BitRGBRedImage, GenTL16BitRGBGreenImage, GenTL16BitRGBBlueImage, out hv_ObjectModel3D);//HOperatorSet.WriteObjectModel3d(hv_ObjectModel3D, "ply", "E:\\UpperComputer\\LMI\\LMIHalconImage\\xyz.ply", new HTuple(), new HTuple());GenTL16BitRGBRedImage.Dispose();GenTL16BitRGBRedImage = null;GenTL16BitRGBGreenImage.Dispose();GenTL16BitRGBGreenImage = null;GenTL16BitRGBBlueImage.Dispose();GenTL16BitRGBBlueImage = null;MyLMICamer.Stop();}catch{GenTL16BitRGBRedImage.Dispose();GenTL16BitRGBRedImage = null;GenTL16BitRGBGreenImage.Dispose();GenTL16BitRGBGreenImage = null;GenTL16BitRGBBlueImage.Dispose();GenTL16BitRGBBlueImage = null;MyLMICamer.Stop();}Console.WriteLine(Environment.NewLine);}/// <summary>/// 设置曝光时间/// </summary>/// <param name="ExposureTime"></param>/// <returns></returns>public override bool SetExposureTime(int ExposureTime){try{if (MyLMICamer.State == GoState.Running){MyLMICamer.Stop();}MyLMICamer.Setup.SetExposure(MyLMICamer.Role, ExposureTime);MyLMICamer.Flush();return true;}catch (Exception){return false;}}#region // 生成不带标定数据的高度信息图/// <summary>/// 输出高度信息以纳米为单位。需要乘以分辨率/// </summary>/// <param name="data"></param>public void onData(KObject data){//高度图HObject GenTL16BitRGBRedImage = new HObject();//亮度图HObject GenTL16BitRGBGreenImage = new HObject();try{if (!Directory.Exists("E:\\UpperComputer")){Directory.CreateDirectory("E:\\UpperComputer");}GoDataSet dataSet = (GoDataSet)data;for (uint i = 0; i < dataSet.Count; i++){GoDataMsg dataObj = (GoDataMsg)dataSet.Get(i);Console.WriteLine(dataObj.MessageType);switch (dataObj.MessageType){case GoDataMessageType.UniformSurface:{GoUniformSurfaceMsg surfaceMsg = (GoUniformSurfaceMsg)dataObj;IntPtr bufferPointeri = surfaceMsg.Data;//声明存放surface的Buffershort[] surfaceBuffer = new short[surfaceMsg.Width * surfaceMsg.Length];//将传感器数据存储至生命的内存空间中Marshal.Copy(bufferPointeri, surfaceBuffer, 0, surfaceBuffer.Length);unsafe{fixed (short* p = surfaceBuffer)HOperatorSet.GenImage1(out GenTL16BitRGBRedImage, "int2", surfaceMsg.Width, surfaceMsg.Length, new IntPtr(p));}HOperatorSet.WriteImage(GenTL16BitRGBRedImage, "tiff", 0, "E:\\UpperComputer\\" + "height" + DateTime.Now.ToString("yyyymmdd-hhmmssfff") + ".tif");}break;case GoDataMessageType.SurfaceIntensity:{GoSurfaceIntensityMsg surfaceIntensityMsg = (GoSurfaceIntensityMsg)dataObj;IntPtr bufferPointeri = surfaceIntensityMsg.Data;//声明存放surface的Bufferbyte[] surfaceBuffer = new byte[surfaceIntensityMsg.Width * surfaceIntensityMsg.Length];//将传感器数据存储至声明的内存空间中Marshal.Copy(bufferPointeri, surfaceBuffer, 0, surfaceBuffer.Length);GenTL16BitRGBGreenImage.Dispose();unsafe{fixed (byte* p = surfaceBuffer){HOperatorSet.GenImage1(out GenTL16BitRGBGreenImage, "byte", surfaceIntensityMsg.Width, surfaceIntensityMsg.Length, new IntPtr(p));}}HOperatorSet.WriteImage(GenTL16BitRGBGreenImage, "tiff", 0, "E:\\UpperComputer\\" + "Intensity" + DateTime.Now.ToString("yyyymmdd-hhmmssfff") + ".tif");}break;}}//GenTL16BitRGBRedImage = null;//GenTL16BitRGBGreenImage = null;GenTL16BitRGBGreenImage.Dispose();GenTL16BitRGBRedImage.Dispose();MyLMICamer.Stop();}catch{//MyLMICamer.Stop();GenTL16BitRGBRedImage.Dispose();//GenTL16BitRGBRedImage = null;GenTL16BitRGBGreenImage.Dispose();//GenTL16BitRGBGreenImage = null;}Console.WriteLine(Environment.NewLine);}#endregion#region // 生成GenTL彩色图格式,并转化为halcon模型/// <summary>/// 输入genTL格式高度图,转化为3d模型。genTL为彩色高度图像/// </summary>/// <param name="ho_Gentl"></param>/// <param name="Save3D"></param>/// <param name="SaveAddress"></param>/// <returns></returns>public HTuple Himage_To_3D(HObject ho_Gentl, bool Save3D, string SaveAddress){HTuple hv_ObjectModel3D = new HTuple();hv_ObjectModel3D.Dispose();Gentl_to_object_model_3d(ho_Gentl, out hv_ObjectModel3D, Save3D, SaveAddress);return hv_ObjectModel3D;}static long frameCount = 0, timeStamp = 0, encoderValue = 0, encoderIndex = 0, digitalStates = 0;static long surfaceBufferWidth = 0, surfaceBufferLength = 0;static long surfaceXResolution = 0, surfaceYResolution = 0, surfaceZResolution = 0;static long surfaceXOffset = 0, surfaceYOffset = 0, surfaceZOffset = 0;static long intensityEnable = 0;/// <summary>/// 回调函数,输出GenTL格式彩色深度图/// </summary>/// <param name="data"></param>public void onData_GenTL(KObject data){//高度图HObject GenTL16BitRGBRedImage = new HObject();//亮度图HObject GenTL16BitRGBGreenImage = new HObject();//Stamp图HObject GenTL16BitRGBBlueImage = new HObject();//GenTLImageHObject GenTLImage = new HObject();try{GoDataSet dataSet = (GoDataSet)data;for (uint i = 0; i < dataSet.Count; i++){GoDataMsg dataObj = (GoDataMsg)dataSet.Get(i);switch (dataObj.MessageType){case GoDataMessageType.Stamp:{GoStampMsg stampMsg = (GoStampMsg)dataObj;for (int j = 0; j < stampMsg.Count; j++){//获取缓存的宽高GoStamp goStamp = stampMsg.Get(j);frameCount = (long)goStamp.FrameIndex;timeStamp = (long)goStamp.Timestamp;encoderValue = goStamp.Encoder;encoderIndex = goStamp.EncoderAtZ;digitalStates = (long)goStamp.Status;}}break;case GoDataMessageType.UniformSurface:{GoUniformSurfaceMsg surfaceMsg = (GoUniformSurfaceMsg)dataObj;//获取缓存的宽高surfaceBufferWidth = surfaceMsg.Width;surfaceBufferLength = surfaceMsg.Length;//获取缓存的分辨率 nmsurfaceXResolution = surfaceMsg.XResolution;surfaceYResolution = surfaceMsg.YResolution;surfaceZResolution = surfaceMsg.ZResolution;#region Offset (um) 转换为 NM *1000surfaceXOffset = surfaceMsg.XOffset * 1000;surfaceYOffset = surfaceMsg.YOffset * 1000;//注意由于halcon体系中用GenTL采集图像默认使用uint2来存储高度数据//而Gocator体系中采集的图像默认使用int2来存储高度数据//所以从Gocator SDK读出的zOffset 适用于Gocator SDK采集的“int2”类型的数据//而我们由于在算法开发过程中使用halcon GenTL采集数据,并且配置了众多处理参数,从而导出的算法代码中的参数//通常都是基于uint2类型数据的,这里我们将Gocator SDK读出的 zOffset做一个转换,使其适配于halcon的uint2体系surfaceZOffset = (long)((surfaceMsg.ZOffset +(short.MinValue * (surfaceMsg.ZResolution * 1e-3))) * 1000);#endregionIntPtr bufferPointeri = surfaceMsg.Data;//声明存放surface的Buffershort[] surfaceBuffer = new short[surfaceBufferWidth * surfaceBufferLength];//将传感器数据存储至生命的内存空间中Marshal.Copy(bufferPointeri, surfaceBuffer, 0, surfaceBuffer.Length);unsafe{fixed (short* p = surfaceBuffer)HOperatorSet.GenImage1(out GenTL16BitRGBRedImage, "int2", surfaceBufferWidth, surfaceBufferLength, new IntPtr(p));}HOperatorSet.ConvertImageType(GenTL16BitRGBRedImage, out GenTL16BitRGBRedImage, "real");HOperatorSet.ScaleImage(GenTL16BitRGBRedImage, out GenTL16BitRGBRedImage, 1, 32768);HOperatorSet.ConvertImageType(GenTL16BitRGBRedImage, out GenTL16BitRGBRedImage, "uint2");}break;case GoDataMessageType.SurfaceIntensity:{GoSurfaceIntensityMsg surfaceIntensityMsg = (GoSurfaceIntensityMsg)dataObj;IntPtr bufferPointeri = surfaceIntensityMsg.Data;//声明存放surface的Bufferbyte[] surfaceBuffer = new byte[surfaceBufferWidth * surfaceBufferLength];//将传感器数据存储至声明的内存空间中Marshal.Copy(bufferPointeri, surfaceBuffer, 0, surfaceBuffer.Length);intensityEnable = 1;GenTL16BitRGBGreenImage.Dispose();unsafe{fixed (byte* p = surfaceBuffer){HOperatorSet.GenImage1(out GenTL16BitRGBGreenImage, "byte", surfaceBufferWidth, surfaceBufferLength, new IntPtr(p));}}#region 将byte图像转换为uint2图像//如果严格按照GenTL协议组织数据的话应该将GenTL16BitRGBGreenImage(Intensity)转换成Uint2类型,转换代码如下//但是由于在运行时软件中显示亮度图时,很多显示器无法很好的支持16bit亮度图的显示,会出现显示细节丢失的情况,从而显示效果很差,//索性这里保留GenTL16BitRGBGreenImage的Byte类型//注意下面的代码为halcon中的流程在VS中实现需要一些中间HObje来保存每一步处理生成的图像,建议在halcon中编写写明的过程,然后导出为C#代码,参考导出代码编写//HOperatorSet.ConvertImageType(GenTL16BitRGBGreenImage, out GenTL16BitRGBGreenImage, "uint2");//HOperatorSet.ScaleImage(GenTL16BitRGBGreenImage, out GenTL16BitRGBGreenImage, 256, 0);#endregion}break;}}//生成BlueImageGenTL16BitRGBBlueImage.Dispose();GenGenTL16BitRGBBlueImage(frameCount, timeStamp, encoderValue, encoderIndex, digitalStates,surfaceBufferWidth, surfaceBufferLength, surfaceXOffset, surfaceXResolution, surfaceYOffset, surfaceYResolution,surfaceZOffset, surfaceZResolution, intensityEnable, out GenTL16BitRGBBlueImage);//将 高度图 亮度图 Stamp图组合成GenTL图像HOperatorSet.Compose3(GenTL16BitRGBRedImage, GenTL16BitRGBGreenImage, GenTL16BitRGBBlueImage, out GenTLImage);HOperatorSet.WriteImage(GenTLImage, new HTuple("tiff"), new HTuple(0), new HTuple("E:\\UpperComputer\\LMI\\LMIHalconImage\\" + frameCount.ToString()));Himage_To_3D(GenTLImage, true, "E:\\UpperComputer\\LMI\\LMIHalconImage\\2");GenTL16BitRGBRedImage = null;GenTL16BitRGBGreenImage = null;GenTL16BitRGBBlueImage = null;GenTLImage = null;MyLMICamer.Stop();Console.WriteLine("采集结束");}catch{GenTL16BitRGBRedImage.Dispose();GenTL16BitRGBRedImage = null;GenTL16BitRGBGreenImage.Dispose();GenTL16BitRGBGreenImage = null;GenTL16BitRGBBlueImage.Dispose();GenTL16BitRGBBlueImage = null;GenTLImage.Dispose();GenTLImage = null;MyLMICamer.Stop();}Console.WriteLine(Environment.NewLine);}public static void Gentl_to_object_model_3d(HObject ho_Gentl, out HTuple hv_ObjectModel3D, bool Save3D, string SaveAddress){// Local iconic variables HObject ho_HeightMap, ho_Intensity, ho_ImageOpening;HObject ho_Regions, ho_ImageReduced, ho_ImageConverted;HObject ho_HeightMapMM, ho_ImageSurface, ho_ImageSurface1;HObject ho_X, ho_Y, ho_MultiChannelImage;// Local control variables HTuple hv_frameCount = null, hv_timestamp = null;HTuple hv_encoderPosition = null, hv_encoderIndex = null;HTuple hv_inputs = null, hv_xOffset = null, hv_xResolution = null;HTuple hv_yOffset = null, hv_yResolution = null, hv_zOffset = null;HTuple hv_zResolution = null, hv_width = null, hv_height = null;HTuple hv_HasIntensity = null, hv_Width = null, hv_Height = null;// Initialize local and output iconic variables HOperatorSet.GenEmptyObj(out ho_HeightMap);HOperatorSet.GenEmptyObj(out ho_Intensity);HOperatorSet.GenEmptyObj(out ho_ImageOpening);HOperatorSet.GenEmptyObj(out ho_Regions);HOperatorSet.GenEmptyObj(out ho_ImageReduced);HOperatorSet.GenEmptyObj(out ho_ImageConverted);HOperatorSet.GenEmptyObj(out ho_HeightMapMM);HOperatorSet.GenEmptyObj(out ho_ImageSurface);HOperatorSet.GenEmptyObj(out ho_ImageSurface1);HOperatorSet.GenEmptyObj(out ho_X);HOperatorSet.GenEmptyObj(out ho_Y);HOperatorSet.GenEmptyObj(out ho_MultiChannelImage);ho_HeightMap.Dispose(); ho_Intensity.Dispose();Go2GenTL_ParseData(ho_Gentl, out ho_HeightMap, out ho_Intensity, out hv_frameCount,out hv_timestamp, out hv_encoderPosition, out hv_encoderIndex, out hv_inputs,out hv_xOffset, out hv_xResolution, out hv_yOffset, out hv_yResolution, out hv_zOffset,out hv_zResolution, out hv_width, out hv_height, out hv_HasIntensity);if (HDevWindowStack.IsOpen()){HOperatorSet.DispObj(ho_HeightMap, HDevWindowStack.GetActive());}ho_ImageOpening.Dispose();HOperatorSet.GrayOpeningShape(ho_HeightMap, out ho_ImageOpening, 7, 7, "octagon");ho_Regions.Dispose();HOperatorSet.Threshold(ho_ImageOpening, out ho_Regions, 1, 65535);ho_ImageReduced.Dispose();HOperatorSet.ReduceDomain(ho_ImageOpening, ho_Regions, out ho_ImageReduced);ho_ImageConverted.Dispose();HOperatorSet.ConvertImageType(ho_ImageReduced, out ho_ImageConverted, "real");ho_HeightMapMM.Dispose();HOperatorSet.ScaleImage(ho_ImageConverted, out ho_HeightMapMM, hv_zResolution,hv_zOffset);HOperatorSet.GetImageSize(ho_Gentl, out hv_Width, out hv_Height);//生成xy坐标的图像映射,乘以分辨率就是xy的相对值ho_ImageSurface.Dispose();HOperatorSet.GenImageSurfaceFirstOrder(out ho_ImageSurface, "real", 1, 0, 0,0, 0, hv_Width, hv_Height);ho_ImageSurface1.Dispose();HOperatorSet.GenImageSurfaceFirstOrder(out ho_ImageSurface1, "real", 0, 1, 0,0, 0, hv_Width, hv_Height);//Create X image with correct scaling (in [m])//scale_image (ImageSurface, X, xResolution * 1e-3, xOffset * 1e-3)//scale_image (ImageSurface1, Y, yResolution * 1e-3, yOffset * 1e-3)ho_X.Dispose();HOperatorSet.GenImageSurfaceFirstOrder(out ho_X, "real", 0, hv_xResolution, hv_xOffset,0, 0, hv_Width, hv_Height);//Create Y image with correct scaling (in [m])ho_Y.Dispose();HOperatorSet.GenImageSurfaceFirstOrder(out ho_Y, "real", -hv_yResolution, 0,-hv_yOffset, 0, 0, hv_Width, hv_Height);//scale_image (Z, Z, zResolution * -1e-6, (StandOff + zOffsetTransform_signed) * 1e-6 - zOffset * 1e-9)ho_MultiChannelImage.Dispose();HOperatorSet.Compose3(ho_X, ho_Y, ho_HeightMapMM, out ho_MultiChannelImage);HOperatorSet.XyzToObjectModel3d(ho_X, ho_Y, ho_HeightMapMM, out hv_ObjectModel3D);if (Save3D){HOperatorSet.WriteObjectModel3d(hv_ObjectModel3D, "ply", SaveAddress,new HTuple(), new HTuple());}}public static void Go2GenTL_ParseData(HObject ho_Image, out HObject ho_HeightMap, out HObject ho_Intensity,out HTuple hv_FrameCount, out HTuple hv_Timestamp, out HTuple hv_EncoderPosition,out HTuple hv_EncoderIndex, out HTuple hv_Inputs, out HTuple hv_xOffset, out HTuple hv_xResolution,out HTuple hv_yOffset, out HTuple hv_yResolution, out HTuple hv_zOffset, out HTuple hv_zResolution,out HTuple hv_Width, out HTuple hv_Length, out HTuple hv_HasIntensity){// Local iconic variables HObject ho_Stamps = null;// Local control variables HTuple hv_channelCount = null, hv_monoImageWidth = new HTuple();HTuple hv_monoImageHeight = new HTuple(), hv_IntensityPosition = new HTuple();// Initialize local and output iconic variables HOperatorSet.GenEmptyObj(out ho_HeightMap);HOperatorSet.GenEmptyObj(out ho_Intensity);HOperatorSet.GenEmptyObj(out ho_Stamps);hv_FrameCount = new HTuple();hv_Timestamp = new HTuple();hv_EncoderPosition = new HTuple();hv_EncoderIndex = new HTuple();hv_Inputs = new HTuple();hv_xOffset = new HTuple();hv_xResolution = new HTuple();hv_yOffset = new HTuple();hv_yResolution = new HTuple();hv_zOffset = new HTuple();hv_zResolution = new HTuple();hv_Width = new HTuple();hv_Length = new HTuple();hv_HasIntensity = new HTuple();HOperatorSet.CountChannels(ho_Image, out hv_channelCount);//if ((int)(new HTuple(hv_channelCount.TupleEqual(1))) != 0){//HOperatorSet.GetImageSize(ho_Image, out hv_monoImageWidth, out hv_monoImageHeight);ho_Stamps.Dispose();HOperatorSet.CropRectangle1(ho_Image, out ho_Stamps, hv_monoImageHeight - 1,0, hv_monoImageHeight - 1, hv_monoImageWidth);//Go2GenTLStamp(ho_Stamps, 1, out hv_FrameCount);Go2GenTLStamp(ho_Stamps, 2, out hv_Timestamp);Go2GenTLStamp(ho_Stamps, 3, out hv_EncoderPosition);Go2GenTLStamp(ho_Stamps, 4, out hv_EncoderIndex);Go2GenTLStamp(ho_Stamps, 5, out hv_Inputs);Go2GenTLStamp(ho_Stamps, 6, out hv_xOffset);Go2GenTLStamp(ho_Stamps, 7, out hv_xResolution);Go2GenTLStamp(ho_Stamps, 8, out hv_yOffset);Go2GenTLStamp(ho_Stamps, 9, out hv_yResolution);Go2GenTLStamp(ho_Stamps, 10, out hv_zOffset);Go2GenTLStamp(ho_Stamps, 11, out hv_zResolution);Go2GenTLStamp(ho_Stamps, 12, out hv_Width);Go2GenTLStamp(ho_Stamps, 13, out hv_Length);Go2GenTLStamp(ho_Stamps, 14, out hv_HasIntensity);//ho_HeightMap.Dispose();HOperatorSet.CropRectangle1(ho_Image, out ho_HeightMap, 0, 0, hv_Length - 1,hv_Width);if ((int)(new HTuple(hv_HasIntensity.TupleEqual(1))) != 0){hv_IntensityPosition = (hv_monoImageHeight - 1) / 2;ho_Intensity.Dispose();HOperatorSet.CropRectangle1(ho_Image, out ho_Intensity, hv_IntensityPosition,0, (hv_IntensityPosition + hv_Length) - 1, hv_Width);}else{ho_Intensity.Dispose();HOperatorSet.GenImageConst(out ho_Intensity, "byte", hv_Width, hv_Length);}//}else if ((int)(new HTuple(hv_channelCount.TupleEqual(3))) != 0){//将三通道图像转换为三个图像ho_HeightMap.Dispose(); ho_Intensity.Dispose(); ho_Stamps.Dispose();HOperatorSet.Decompose3(ho_Image, out ho_HeightMap, out ho_Intensity, out ho_Stamps);//Go2GenTLStamp(ho_Stamps, 1, out hv_FrameCount);Go2GenTLStamp(ho_Stamps, 2, out hv_Timestamp);Go2GenTLStamp(ho_Stamps, 3, out hv_EncoderPosition);Go2GenTLStamp(ho_Stamps, 4, out hv_EncoderIndex);Go2GenTLStamp(ho_Stamps, 5, out hv_Inputs);Go2GenTLStamp(ho_Stamps, 6, out hv_xOffset);Go2GenTLStamp(ho_Stamps, 7, out hv_xResolution);Go2GenTLStamp(ho_Stamps, 8, out hv_yOffset);Go2GenTLStamp(ho_Stamps, 9, out hv_yResolution);Go2GenTLStamp(ho_Stamps, 10, out hv_zOffset);Go2GenTLStamp(ho_Stamps, 11, out hv_zResolution);Go2GenTLStamp(ho_Stamps, 12, out hv_Width);Go2GenTLStamp(ho_Stamps, 13, out hv_Length);Go2GenTLStamp(ho_Stamps, 14, out hv_HasIntensity);}////* Change Offset and resolution back to floating point and described in mmhv_xOffset = hv_xOffset / 1000000.0;hv_yOffset = hv_yOffset / 1000000.0;hv_zOffset = hv_zOffset / 1000000.0;hv_xResolution = hv_xResolution / 1000000.0;hv_yResolution = hv_yResolution / 1000000.0;hv_zResolution = hv_zResolution / 1000000.0;//ho_Stamps.Dispose();return;}public static void Go2GenTLStamp(HObject ho_Stamps, HTuple hv_Index, out HTuple hv_Value){// Local iconic variables // Local control variables HTuple hv_test_value = null, hv_is64bit = new HTuple();HTuple hv_tempvalue0 = null, hv_tempvalue1 = null, hv_tempvalue2 = null;HTuple hv_tempvalue3 = null;// Initialize local and output iconic variables hv_Value = new HTuple();//Check if we are on a 64-bit machinehv_test_value = 0xFFFFFFFF;if ((int)(new HTuple(hv_test_value.TupleGreater(0))) != 0){hv_is64bit = 1;}else{hv_is64bit = 0;}//HOperatorSet.GetGrayval(ho_Stamps, 0, hv_Index * 4, out hv_tempvalue0);HOperatorSet.GetGrayval(ho_Stamps, 0, (hv_Index * 4) + 1, out hv_tempvalue1);HOperatorSet.GetGrayval(ho_Stamps, 0, (hv_Index * 4) + 2, out hv_tempvalue2);HOperatorSet.GetGrayval(ho_Stamps, 0, (hv_Index * 4) + 3, out hv_tempvalue3);////The actual stamp from the Gocator is 64-bit. tempvalue0 is the most significant 16-bit (i.e. the top bit is the sign bit)//The code below assumes we only need the bottom 32-bit information. User need to update this conversion function if they want to//return 64-bit value.//if ((int)(new HTuple(hv_is64bit.TupleEqual(1))) != 0){HOperatorSet.TupleLsh(hv_tempvalue0, 48, out hv_tempvalue0);HOperatorSet.TupleLsh(hv_tempvalue1, 32, out hv_tempvalue1);HOperatorSet.TupleLsh(hv_tempvalue2, 16, out hv_tempvalue2);HOperatorSet.TupleLsh(hv_tempvalue3, 0, out hv_tempvalue3);hv_Value = ((hv_tempvalue0 + hv_tempvalue1) + hv_tempvalue2) + hv_tempvalue3;}else{HOperatorSet.TupleLsh(hv_tempvalue2, 16, out hv_tempvalue2);HOperatorSet.TupleLsh(hv_tempvalue3, 0, out hv_tempvalue3);hv_Value = hv_tempvalue2 + hv_tempvalue3;}return;}/// <summary>/// GenTL16BitRGBBlueImage生成/// </summary>/// <param name="frameCount"></param>/// <param name="timeStamp"></param>/// <param name="encoderValue"></param>/// <param name="encoderIndex"></param>/// <param name="digitalStates"></param>/// <param name="surfaceBufferWidth"></param>/// <param name="surfaceBufferLength"></param>/// <param name="surfaceXOffset"></param>/// <param name="surfaceXResolution"></param>/// <param name="surfaceYOffset"></param>/// <param name="surfaceYResolution"></param>/// <param name="surfaceZOffset"></param>/// <param name="surfaceZResolution"></param>/// <param name="intensityEnable"></param>/// <param name="GenTL16BitRGBBlueImage"></param>private static void GenGenTL16BitRGBBlueImage(long frameCount, long timeStamp, long encoderValue, long encoderIndex, long digitalStates,long surfaceBufferWidth, long surfaceBufferLength,long surfaceXOffset, long surfaceXResolution,long surfaceYOffset, long surfaceYResolution,long surfaceZOffset, long surfaceZResolution,long intensityEnable,out HObject GenTL16BitRGBBlueImage){try{#region 初始BlueImage缓存//BlueImage缓存ushort[] blueChannel = new ushort[surfaceBufferWidth * surfaceBufferLength];//临时变量ushort temp0 = 0, temp1 = 0, temp2 = 0, temp3 = 0;//VersionblueChannel[0] = 0;blueChannel[1] = 0;blueChannel[2] = 0;blueChannel[3] = 0;//Frame CountLong2UShort(frameCount, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[4] = temp0;blueChannel[5] = temp1;blueChannel[6] = temp2;blueChannel[7] = temp3;//TimeStampLong2UShort(timeStamp, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[8] = temp0;blueChannel[9] = temp1;blueChannel[10] = temp2;blueChannel[11] = temp3;//Encoder value(ticks)Long2UShort(encoderValue, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[12] = temp0;blueChannel[13] = temp1;blueChannel[14] = temp2;blueChannel[15] = temp3;//Encoder index (ticks)Long2UShort(encoderIndex, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[16] = temp0;blueChannel[17] = temp1;blueChannel[18] = temp2;blueChannel[19] = temp3;//Digital input statesLong2UShort(digitalStates, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[20] = temp0;blueChannel[21] = temp1;blueChannel[22] = temp2;blueChannel[23] = temp3;//X offset (nm)Long2UShort(surfaceXOffset, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[24] = temp0;blueChannel[25] = temp1;blueChannel[26] = temp2;blueChannel[27] = temp3;//X resolution(nm)Long2UShort(surfaceXResolution, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[28] = temp0;blueChannel[29] = temp1;blueChannel[30] = temp2;blueChannel[31] = temp3;//Y offset (nm)Long2UShort(surfaceYOffset, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[32] = temp0;blueChannel[33] = temp1;blueChannel[34] = temp2;blueChannel[35] = temp3;//Y resolution (nm)Long2UShort(surfaceYResolution, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[36] = temp0;blueChannel[37] = temp1;blueChannel[38] = temp2;blueChannel[39] = temp3;//Z offset (nm)Long2UShort(surfaceZOffset, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[40] = temp0;blueChannel[41] = temp1;blueChannel[42] = temp2;blueChannel[43] = temp3;//Z resolution (nm)Long2UShort(surfaceZResolution, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[44] = temp0;blueChannel[45] = temp1;blueChannel[46] = temp2;blueChannel[47] = temp3;//Height map Width (in pixels)Long2UShort(surfaceBufferWidth, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[48] = temp0;blueChannel[49] = temp1;blueChannel[50] = temp2;blueChannel[51] = temp3;//Height map length (in pixels)Long2UShort(surfaceBufferLength, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[52] = temp0;blueChannel[53] = temp1;blueChannel[54] = temp2;blueChannel[55] = temp3;//Specify if intensity is enabled or notLong2UShort(intensityEnable, ref temp0, ref temp1, ref temp2, ref temp3);blueChannel[56] = temp0;blueChannel[57] = temp1;blueChannel[58] = temp2;blueChannel[59] = temp3;#endregion#region 创建GenTL16BitRGBBlueImageunsafe{fixed (ushort* p = blueChannel)HOperatorSet.GenImage1(out GenTL16BitRGBBlueImage, "uint2", surfaceBufferWidth, surfaceBufferLength, new IntPtr(p));}#endregion}catch (Exception ex){throw ex;}}/// <summary>/// Long类型ToUint2类型转换器/// </summary>/// <param name="value"></param>/// <param name="valueL0"></param>/// <param name="valueL1"></param>/// <param name="valueL2"></param>/// <param name="valueL3"></param>private static void Long2UShort(long value, ref ushort valueL0, ref ushort valueL1, ref ushort valueL2, ref ushort valueL3){valueL0 = (ushort)(value >> 48);valueL1 = (ushort)(value >> 32);valueL2 = (ushort)(value >> 16);valueL3 = (ushort)(value >> 0);}#endregion}
}

LMI相机的运行逻辑并不难,一个主要是如何配置LMI相机,另一个是如何转换格式图像。代码中提供了3种转换方式,分别有:GenTL格式,带标定数据的halcon类型,不带标定数据的halcon类型。
如何配置LMI相机后面会再开一份博客进行讲解。
其中需要注意的事情又:
第一:LMI的相机SDK与VS的版本(。net版本)有部分冲突,再使用.net4.72和VS2022时发现,最新版LMISDK无法运行,暂时可以使用旧版SDK。
第二:LMI相机加速器,只能使用相机相对应版本的加速器进行加速,相机SDK中并没有内置加速器。

相关文章:

相机通用类之LMI激光三角相机(3D),软触发硬触发(飞拍),并输出halcon格式对象

//在此之前可以先浏览我编写的通用上位机类&#xff0c;更方便理解 https://blog.csdn.net/m0_51559565/article/details/134403745最近完成一个关于LMI激光三角&#xff08;3D相机&#xff09;采图的demo&#xff0c;记录并说明用法。 先上代码。 using Lmi3d.GoSdk; using L…...

android studio基本使用

as如果一直index&#xff0c;就把缓存目录全部删除 记录下as日常使用。 调试工具 c动态库调试 ndk会带一些调试工具&#xff0c;例如 C:\Users\luopu\AppData\Local\Android\Sdk\ndk\20.0.5594570\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin\aarch…...

安装包管理工具-Yarn

一、介绍与安装 1.1 介绍 Yarn是一款功能包管理工具&#xff0c;与npm(npm:Node.js 的包管理器 npm,是目前最流行的Node.js 的包管理器。)类似。有着FAST(快速的), RELIABLE( RELIABLE 可信赖的), AND SECURE DEPENDENCY MANAGEMENT(安全依赖关系管理)的特点。 Yarn官网 1.2…...

SOLIDWORKS功能布局实用技巧之保存实体技术

在SOLIDWORKS软件中&#xff0c;有一些命令可以将一个或多个实体保存为独立的零件文件。然而&#xff0c;每个命令都具有不同的特性&#xff0c;有些命令的选项可以让您在保存多个零件时直接生成装配体文件。让我们来深入了解这些功能布局技巧&#xff0c;特别是实体保存技术。…...

Android11 将logcat日志定位到uart串口输出

软件平台&#xff1a;Android11 硬件平台&#xff1a;QCS6125 需求&#xff1a;如题&#xff0c;串口需要输出logcat的系统全量日志&#xff0c;我这里边是把logcat日志定向到了/dev/kmsg从而使logcat跟kmsg一样通过串口输出。 改动如下&#xff1a; diff --git a/rootdir/…...

SpringSecurity6从入门到上天系列第六篇:解决这个问题为什么在引入SpringSecurity之后所有的请求都需要先做登录认证才可以进行访问呢

文章目录 问题引入 1&#xff1a;问题阐述 2&#xff1a;问题分析 一&#xff1a;从SpringBoot的自动装配 1&#xff1a;SpringBootApplication介绍 2&#xff1a;自动装配的核心方法 3&#xff1a;核心方法的调用路径 4&#xff1a;SpringSecurity核心配置 5&#xf…...

Mac M3 芯片安装 Nginx

Mac M3 芯片安装 Nginx 一、使用 brew 安装 未安装 brew 的可以参考 【Mac 安装 Homebrew】 或者 【Mac M2/M3 芯片环境配置以及常用软件安装-前端】 二、查看 nginx 信息 通过命令行查看 brew info nginx可以看到 nginx 还未在本地安装&#xff0c;显示 Not installed …...

浏览器怎么更新?4个高效设置方法!

“我在使用浏览器时&#xff0c;有时候会提示说浏览器版本太低&#xff0c;需要更新后才能使用。有什么方法可以更新浏览器呢&#xff1f;快给我支支招吧&#xff01;” 在快速发展的科技时代&#xff0c;浏览器更新是确保网络安全和性能优化的关键步骤。如果浏览器的版本太低&…...

settings.json配置

settings.json配置 {"editor.tabSize": 2,"git.ignoreWindowsGit27Warning": true,"workbench.editor.untitled.hint": "hidden","security.workspace.trust.untrustedFiles": "open","[vue]": {"…...

Mysql中的JDBC编程

JDBC编程 1.JDBC的数据库编程2.JDBC工作原理3.JDBC使用3.1JDBC开发案例3.2JDBC使用步骤总结 4.JDBC API4.1数据库连接Connection4.2 Statement对象4.3 ResultSet对象4.4 释放 5.Java代码操作数据库 1.JDBC的数据库编程 JDBC&#xff0c;即Java Database Connectivity&#xff0…...

媒体行业的3D建模:在影视中创造特效纹理

在线工具推荐&#xff1a; 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 在本文中&#xff0c;我们将探讨 3D 建模在媒体行业中的作用&#xff0c;特别是它在影视特效创作…...

Kafka从安装使用到集成Springboot详细教程

“不积跬步&#xff0c;无以至千里。” 1. 引言 在当今高度互联的技术领域&#xff0c;消息队列成为分布式系统中不可或缺的一部分。Apache Kafka作为一个高性能、持久化、分布式的消息队列系统&#xff0c;备受开发者推崇。这篇文章将从安装到集成Spring的全方位介绍Kafka的使…...

【giszz笔记】产品设计标准流程【4】

&#xff08;续上回&#xff09; 我们继续把扩展考虑UX环节的产品打造标准流程&#xff0c;来进行梳理。 一千个人心中有一千个哈姆雷特&#xff0c;本文将日常大家耳熟能详&#xff0c;但是又未必人人心中成体系的产品打造标准流程&#xff0c;进行总结。 考虑了两种项目&a…...

图论16-拓扑排序

文章目录 1 拓扑排序2 拓扑排序的普通实现2.1 算法实现 - 度数为0入队列2.2 拓扑排序中的环检测 3 深度优先遍历的后续遍历3.1 使用环检测类先判断是否有环3.2 调用无向图的深度优先后续遍历方法&#xff0c;进行DFS 1 拓扑排序 对一个有向无环图G进行拓扑排序&#xff0c;是将…...

SecureCRT 9.4.2最新终端SSH工具

SecureCRT是一款终端SSH工具&#xff0c;它提供了类似于Telnet和SSH等协议的远程访问功能。SecureCRT软件特色包括&#xff1a; 支持SSH&#xff08;SSH1和SSH2&#xff09;的终端仿真程序&#xff0c;能在Windows下登录UNIX或Linux服务器主机。SecureCRT支持SSH&#xff0c;同…...

基于python+django的美食餐厅点餐订餐网站

运行环境 开发语言&#xff1a;Python python框架&#xff1a;django 软件版本&#xff1a;python3.7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;PyCharm/vscode 前端框架:vue.js 项目介绍 本论文主要论述了如何使用python语言开发…...

Moka人事:实现无代码开发的API连接,打通电商平台与用户运营系统

无代码开发的API连接&#xff1a;Moka人事的核心优势 Moka人事&#xff0c;是北京希瑞亚斯科技有限公司于2015年推出的一款数据驱动的智能化HR SaaS产品。这款产品的主要优势在于其无需进行API开发即可实现系统的连接和集成&#xff0c;这不仅大大提升了企业的工作效率&#x…...

【Spring】超详细讲解AOP(面向切面编程)

文章目录 1. 前言2. 什么是AOP3. AOP快速入门4. AOP的核心概念5. 切点表达式6. 切点函数7. 通知8. 总结 1. 前言 本文围绕AOP进行讲解,AOP可以做什么,涉及到了哪些注解,以及各个注解运行的时机,以及Around相较于其它注解有什么不同,并且如果要执行目标方法需要怎么做 2. 什么…...

界面组件DevExpress Reporting v23.1亮点 - 全新升级报表查看器

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表 界面组件DevExpress Reporting v23.1已经发布一段…...

电容容量换算电池容量,以及RTC持续时间计算

依据 公式1&#xff1a;QI*t 公式2&#xff1a;QC*U 其中&#xff1a; Q&#xff1a; 电荷量 &#xff08;库仑&#xff09; I&#xff1a; 电流 &#xff08;安培&#xff09; t&#xff1a; 时间 &#xff08;秒&#xff09; C&#xff1a; 电容量 &#xff08;法拉&#xf…...

【BIM入门实战】高程点无法放置的解决方法

文章目录 一、问题提出二、解决办法1. 检查模型图形样式2. 高程点可以放置的图元一、问题提出 在平面图中添加高程点时有时会遇到无法在楼板等平面构件上放置高程点,应如何设置才能使高程点正常放置? 如下图所示,楼板上无法放置高程点: 二、解决办法 1. 检查模型图形样式…...

CRM系统对科技企业有哪些帮助

随着国家政策的倾斜和5G等相关基础技术的发展&#xff0c;中国人工智能产业在各方的共同推动下进入爆发式增长阶段&#xff0c;市场发展潜力巨大。CRM客户管理系统作为当下最热门的企业应用&#xff0c;同样市场前景广阔。那么&#xff0c;CRM系统对科技企业有哪些帮助&#xf…...

用excel计算一个矩阵的转置矩阵

假设我们的原矩阵是一个3*3的矩阵&#xff1a; 125346789 现在求它的转置矩阵&#xff1a; 鼠标点到一个空白的地方&#xff0c;用来存放结果&#xff1a; 插入-》函数&#xff1a; 选择TRANSPOSE&#xff0c;这个就是求转置矩阵的函数&#xff1a; 点击“继续”&#xff1a…...

WPF 中的 ControlTemplate 和 DataTemplate 有什么区别

在WPF中&#xff0c;ControlTemplate和DataTemplate都是模板&#xff0c;它们都可以用来定义一段可重复使用的XAML标记。然而&#xff0c;它们的用途和应用场景有很大的不同。 ControlTemplate&#xff1a; ControlTemplate是用来定义控件的外观和视觉行为的。每个WPF控件都有…...

3D重建相关

目录 <font colorblue>整个3D重建的过程是怎样的<font colorblue>体素、网格、点云之间的关系是什么<font colorblue>点云中的颜色怎么处理成最终3D模型上的颜色<font colorblue>点云还原的3D模型的颜色怎么处理&#xff0c;点云有颜色数据&#xff1f…...

字符串数组排序(Java/JavaScript代码版)

Java public static void main(String[] args) throws Exception {String[] arr new String[] {"abc","xyz","efg"};// 默认按自然升序排Arrays.sort(arr);System.out.println(Arrays.toString(arr)); }降序排 降序排&#xff0c;可传入第二个…...

调用电商集成平台 聚水潭 api接口示例

先上工具类 package com.zuodou.utlis;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;import javax.xml.crypto.Data; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import j…...

深入Rust:探索所有权和借用机制

大家好&#xff01;我是lincyang。 今天&#xff0c;我们将一起深入探索Rust语言中的一个核心概念&#xff1a;所有权和借用机制。 这些特性是Rust区别于其他语言的重要特点&#xff0c;它们在内存管理和并发编程中扮演着关键角色。 一、Rust所有权机制 1. 什么是所有权&#x…...

Python之冒泡排序(AI自动写文章项目测试)

全自动AI生成文章测试&#xff0c;如有不合理地方&#xff0c;请见谅。 一、冒泡排序简介 1.1 冒泡排序概述 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;通过不断交换相邻元素的位置&#xff0c;将最大&#xff08;或最小&#xff09;的元…...

spring cloud微服务中多线程下,子线程通过feign调用其它服务,请求头token等丢失

在线程池中&#xff0c;子线程调用其他服务&#xff0c;请求头丢失&#xff0c;token为空的情况 看了很多篇文章的处理方法和在自己亲测的情况下做出说明&#xff1a; 第一种&#xff1a; 这种方式只支持在主线程情况下&#xff0c;能够处理&#xff0c;在多线程情况下&#…...