using HalconDotNet; using LB_SmartVisionCommon; using LB_VisionControls; using LB_VisionProcesses.Alogrithms.Halcon; using OpenCvSharp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static OpenCvSharp.ML.DTrees; namespace LB_VisionProcesses.Alogrithms { public class PointsCloudConvertTool : TAlgorithm { public enum ImageType { DeepImage, PointsCloud } public PointsCloudConvertTool() { strProcessClass = "LB_VisionProcesses.Alogrithms.PointsCloudConvertTool"; strProcessName = "点云转换工具"; Params.Inputs.Add("输入格式", "DeepImage"); Params.Inputs.Add("输出格式", "PointsCloud"); Params.Inputs.Add("是否后处理", false); } /// /// 算子逻辑 /// public override void TAlgorithmMain() { #region 初始化变量 #endregion try { if (InputImage == null) { Msg = "输入图片为空"; Result = false; AsyncLogHelper.Error(Msg); return; } #region 算子逻辑 Record = new ObjectRecord(); bool bConvert = Convert.ToBoolean(Params.Inputs["是否后处理"]); if (!Enum.TryParse(ProcessParams.ConvertToString(Params.Inputs["输入格式"]), out ImageType eInputImageType)) { Msg = "输入格式不存在"; Result = false; AsyncLogHelper.Error(Msg); return; } if (!Enum.TryParse(ProcessParams.ConvertToString(Params.Inputs["输出格式"]), out ImageType eOutputImageType)) { Msg = "输出格式不存在"; Result = false; AsyncLogHelper.Error(Msg); return; } switch (eInputImageType) { case ImageType.DeepImage: { if (InputImage is HObject hImage) { switch (eOutputImageType) { case ImageType.DeepImage: { OutputImage = hImage.CopyObj(1, -1); break; } case ImageType.PointsCloud: { TAlgorithm.DeepImage2PointsCloud(hImage, out HTuple pointsCloud, 1); OutputImage = pointsCloud; break; } default: { Msg = "不支持的输出格式"; Result = false; AsyncLogHelper.Error(Msg); return; } } } else { Msg = $"输入图片格式为{InputImage.GetType()},不是HObject深度图格式"; Result = false; AsyncLogHelper.Error(Msg); return; } break; } case ImageType.PointsCloud: { if (InputImage is HTuple hPointsCloud) { switch (eOutputImageType) { case ImageType.DeepImage: { TAlgorithm.PointsCloud2DeepImage(hPointsCloud, out HObject deepImage); OutputImage = deepImage; break; } case ImageType.PointsCloud: { OutputImage = hPointsCloud.Clone(); break; } default: { Msg = "不支持的输出格式"; Result = false; AsyncLogHelper.Error(Msg); return; } } } else { Msg = $"输入图片格式为{InputImage.GetType()},不是HTuple点云图格式"; Result = false; AsyncLogHelper.Error(Msg); return; } break; } default: { Msg = "不支持的输入格式"; Result = false; AsyncLogHelper.Error(Msg); return; } } /* bool bConvert = Convert.ToBoolean(Params.Inputs["是否后处理"]); if (!Enum.TryParse(ProcessParams.ConvertToString(Params.Inputs["输入格式"]), out ImageType eInputImageType)) { Msg = "输入格式不存在"; Result = false; return; } if (!Enum.TryParse(ProcessParams.ConvertToString(Params.Inputs["输出格式"]), out ImageType eOutputImageType)) { Msg = "输出格式不存在"; Result = false; return; } if (!Enum.TryParse(ProcessParams.ConvertToString(Params.Inputs["后处理格式"]), out PixelType ePixelType)) { Msg = "后处理格式不存在"; Result = false; return; } switch (eInputImageType) { case ImageType.Bitmap: if (InputImage is Bitmap bmp) { switch (eOutputImageType) { case ImageType.Bitmap: OutputImage = bmp.Clone(); break; case ImageType.HObject: TAlgorithm.Bitmap2HObject(bmp, out HObject bHObject); OutputImage = bHObject; break; case ImageType.Mat: OutputImage = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp); break; default: Msg = "不支持的输出格式"; Result = false; return; } } else { Msg = $"输入图片格式为{InputImage.GetType()},不是Bitmap格式"; Result = false; return; } break; case ImageType.HObject: if (InputImage is HObject hObject) { switch (eOutputImageType) { case ImageType.Bitmap: TAlgorithm.HObject2Bitmap(hObject, out Bitmap hBitmap); OutputImage = hBitmap; break; case ImageType.HObject: OutputImage = hObject.CopyObj(1, -1); break; case ImageType.Mat: TAlgorithm.HObject2Mat(hObject, out Mat hMat); OutputImage = hMat; break; default: Msg = "不支持的输出格式"; Result = false; return; } } else { Msg = $"输入图片格式为{InputImage.GetType()},不是HObject格式"; Result = false; return; } break; case ImageType.Mat: if (InputImage is Mat mat) { switch (eOutputImageType) { case ImageType.Bitmap: OutputImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat); break; case ImageType.HObject: TAlgorithm.Mat2HObject(mat, out HObject mHObject); OutputImage = mHObject; break; case ImageType.Mat: OutputImage = mat.Clone(); break; default: Msg = "不支持的输出格式"; Result = false; return; } } else { Msg = $"输入图片格式为{InputImage.GetType()},不是Mat格式"; Result = false; return; } break; default: Msg = "不支持的输入格式"; Result = false; return; } */ #endregion #region 裁剪区域 //object DomainImage = null; //if (!ReduceDomainImage(OutputImage, ref DomainImage)) //{ // Msg = "裁剪区域失败"; // Result = false; // return; //} #endregion #region 结果后处理 /* if (bConvert && ePixelType != PixelType.None) { double k = Convert.ToDouble(Params.Inputs["斜率"]); double b = Convert.ToDouble(Params.Inputs["截距"]); switch (eOutputImageType) { case ImageType.Bitmap: switch (ePixelType) { case PixelType.Gray: TAlgorithm.Bitmap2HObject((Bitmap)DomainImage, out HObject hObjectGray); // 转换为灰度图像 HOperatorSet.Rgb1ToGray(hObjectGray, out HObject grayImage); DomainImage = grayImage; TAlgorithm.HObject2Bitmap(grayImage, out Bitmap grayBitmap); DomainImage = grayBitmap; break; case PixelType.ChannelR: TAlgorithm.Bitmap2HObject((Bitmap)DomainImage, out HObject hObjectR); HOperatorSet.CountChannels(hObjectR, out HTuple hv_ChannelR); if (hv_ChannelR.I == 3) { // 提取红色通道 HOperatorSet.Decompose3(hObjectR, out HObject channelR, out _, out _); TAlgorithm.HObject2Bitmap(channelR, out Bitmap rBitmap); DomainImage = rBitmap; } break; case PixelType.ChannelG: TAlgorithm.Bitmap2HObject((Bitmap)DomainImage, out HObject hObjectG); HOperatorSet.CountChannels(hObjectG, out HTuple hv_ChannelG); if (hv_ChannelG.I == 3) { // 提取绿色通道 HOperatorSet.Decompose3(hObjectG, out _, out HObject channelG, out _); TAlgorithm.HObject2Bitmap(channelG, out Bitmap gBitmap); DomainImage = gBitmap; } break; case PixelType.ChannelB: TAlgorithm.Bitmap2HObject((Bitmap)DomainImage, out HObject hObjectB); HOperatorSet.CountChannels(hObjectB, out HTuple hv_ChannelB); if (hv_ChannelB.I == 3) { // 提取蓝色通道 HOperatorSet.Decompose3(hObjectB, out _, out _, out HObject channelB); TAlgorithm.HObject2Bitmap(channelB, out Bitmap bBitmap); DomainImage = bBitmap; } break; case PixelType.ChannelH: TAlgorithm.Bitmap2HObject((Bitmap)DomainImage, out HObject hObjectH); HOperatorSet.CountChannels(hObjectH, out HTuple hv_ChannelH); if (hv_ChannelH.I == 3) { // 转换为HSV颜色空间并提取H通道 HOperatorSet.Decompose3(hObjectH, out HObject hr, out HObject hg, out HObject hb); HOperatorSet.TransFromRgb(hr, hg, hb, out HObject channelH, out _, out _, "hsv"); TAlgorithm.HObject2Bitmap(channelH, out Bitmap hBitmap); DomainImage = hBitmap; } break; case PixelType.ChannelS: TAlgorithm.Bitmap2HObject((Bitmap)DomainImage, out HObject hObjectS); HOperatorSet.CountChannels(hObjectS, out HTuple hv_ChannelS); if (hv_ChannelS.I == 3) { // 转换为HSV颜色空间并提取S通道 HOperatorSet.Decompose3(hObjectS, out HObject hr, out HObject hg, out HObject hb); HOperatorSet.TransFromRgb(hr, hg, hb, out _, out HObject channelS, out _, "hsv"); TAlgorithm.HObject2Bitmap(channelS, out Bitmap sBitmap); DomainImage = sBitmap; } break; case PixelType.ChannelV: TAlgorithm.Bitmap2HObject((Bitmap)DomainImage, out HObject hObjectV); HOperatorSet.CountChannels(hObjectV, out HTuple hv_ChannelV); if (hv_ChannelV.I == 3) { // 转换为HSV颜色空间并提取V通道 HOperatorSet.Decompose3(hObjectV, out HObject hr, out HObject hg, out HObject hb); HOperatorSet.TransFromRgb(hr, hg, hb, out _, out _, out HObject channelV, "hsv"); TAlgorithm.HObject2Bitmap(channelV, out Bitmap vBitmap); DomainImage = vBitmap; } break; default: Msg = "不支持的后处理格式"; Result = false; return; } break; case ImageType.HObject: switch (ePixelType) { case PixelType.Gray: if (DomainImage is HObject hObjectGray) { // 转换为灰度图像 HOperatorSet.Rgb1ToGray(hObjectGray, out HObject grayImage); HOperatorSet.ScaleImage(grayImage, out grayImage, k, b); DomainImage = grayImage; } break; case PixelType.ChannelR: if (DomainImage is HObject hObjectR) { HOperatorSet.CountChannels(hObjectR, out HTuple hv_ChannelR); if (hv_ChannelR.I == 3) { // 提取红色通道 HOperatorSet.Decompose3(hObjectR, out HObject channelR, out _, out _); HOperatorSet.ScaleImage(channelR, out channelR, k, b); DomainImage = channelR; } } break; case PixelType.ChannelG: if (DomainImage is HObject hObjectG) { HOperatorSet.CountChannels(hObjectG, out HTuple hv_ChannelG); if (hv_ChannelG.I == 3) { // 提取绿色通道 HOperatorSet.Decompose3(hObjectG, out _, out HObject channelG, out _); HOperatorSet.ScaleImage(channelG, out channelG, k, b); DomainImage = channelG; } } break; case PixelType.ChannelB: if (DomainImage is HObject hObjectB) { HOperatorSet.CountChannels(hObjectB, out HTuple hv_ChannelB); if (hv_ChannelB.I == 3) { // 提取蓝色通道 HOperatorSet.Decompose3(hObjectB, out _, out _, out HObject channelB); HOperatorSet.ScaleImage(channelB, out channelB, k, b); DomainImage = channelB; } } break; case PixelType.ChannelH: if (DomainImage is HObject hObjectH) { HOperatorSet.CountChannels(hObjectH, out HTuple hv_ChannelH); if (hv_ChannelH.I == 3) { // 转换为HSV颜色空间并提取H通道 HOperatorSet.Decompose3(hObjectH, out HObject hr, out HObject hg, out HObject hb); HOperatorSet.TransFromRgb(hr, hg, hb, out HObject channelH, out _, out _, "hsv"); HOperatorSet.ScaleImage(channelH, out channelH, k, b); DomainImage = channelH; } } break; case PixelType.ChannelS: if (DomainImage is HObject hObjectS) { HOperatorSet.CountChannels(hObjectS, out HTuple hv_ChannelS); if (hv_ChannelS.I == 3) { // 转换为HSV颜色空间并提取S通道 HOperatorSet.Decompose3(hObjectS, out HObject hr, out HObject hg, out HObject hb); HOperatorSet.TransFromRgb(hr, hg, hb, out _, out HObject channelS, out _, "hsv"); HOperatorSet.ScaleImage(channelS, out channelS, k, b); DomainImage = channelS; } } break; case PixelType.ChannelV: if (DomainImage is HObject hObjectV && hObjectV.CountObj() > 0) { HOperatorSet.CountChannels(hObjectV, out HTuple hv_ChannelV); if (hv_ChannelV.I == 3) { // 转换为HSV颜色空间并提取V通道 HOperatorSet.Decompose3(hObjectV, out HObject hr, out HObject hg, out HObject hb); HOperatorSet.TransFromRgb(hr, hg, hb, out _, out _, out HObject channelV, "hsv"); HOperatorSet.ScaleImage(channelV, out channelV, k, b); DomainImage = channelV; } } break; default: Msg = "不支持的后处理格式"; Result = false; return; } break; case ImageType.Mat: Mat mat = new Mat(); switch (ePixelType) { case PixelType.Gray: // 转换为灰度图像 if (DomainImage is Mat matGray) Cv2.CvtColor(matGray, mat, ColorConversionCodes.BGR2GRAY); break; case PixelType.ChannelR: if (DomainImage is Mat matR) { // 提取红色通道 if (matR.Channels() == 3) mat = matR.Split()[2]; } break; case PixelType.ChannelG: if (DomainImage is Mat matG) { // 提取绿色通道 if (matG.Channels() == 3) mat = matG.Split()[1]; } break; case PixelType.ChannelB: if (DomainImage is Mat matB) { // 提取蓝色通道 if (matB.Channels() == 3) mat = matB.Split()[0]; } break; case PixelType.ChannelH: if (DomainImage is Mat matHH) { // 提取H通道 if (matHH.Channels() == 3) { Mat matH = new Mat(); Cv2.CvtColor(matHH, matH, ColorConversionCodes.BGR2HSV); mat = matH.Split()[0]; } } break; case PixelType.ChannelS: if (DomainImage is Mat matSS) { // 提取S通道 if (matSS.Channels() == 3) { Mat matS = new Mat(); Cv2.CvtColor(matSS, matS, ColorConversionCodes.BGR2HSV); mat = matS.Split()[1]; } } break; case PixelType.ChannelV: if (DomainImage is Mat matVV) { // 提取V通道 if (matVV.Channels() == 3) { Mat matV = new Mat(); Cv2.CvtColor(matVV, matV, ColorConversionCodes.BGR2HSV); mat = matV.Split()[2]; } } break; default: Msg = "不支持的后处理格式"; Result = false; return; } DomainImage = mat; break; default: Msg = "不支持的输出格式"; Result = false; return; } } else if (!bConvert) { DomainImage = OutputImage; } */ #endregion #region 生成OutputImage给后续处理 try { //OutputImage = DomainImage; Params.Outputs.Add("ConvertImage", OutputImage); } catch (Exception ex) { Msg = "生成OutputImage失败,原因是:" + ex.ToString(); Result = false; AsyncLogHelper.Error(Msg); return; } #endregion if (Msg == "运行超时") { Result = false; return; } Msg = "运行成功"; Result = true; return; } catch (Exception ex) { Msg = "运行失败,原因是:" + ex.ToString().TrimEnd(); OutputImage = null; Result = false; AsyncLogHelper.Error(Msg); return; } finally { if (!Result) { Params.Outputs.Add("ConvertImage", null); } bCompleted = true; #region 内存释放 #endregion } } } }