using System.Runtime.InteropServices; using Vinno.Infrastructure; using System; using Vinno.DataTypes; using Vinno.DataManager.Utilities; using System.Collections.Generic; using Vinno.Enums; using System.Linq; using Vinno.Infrastructure.DataTypes; namespace WingAIDiagnosisService.URMManage { public class URMMeasureAlg { [DllImport("ImageProcessAlgWrapLib.dll")] private static extern IntPtr PIA_CreateURMMeasure(); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe DPoint* PIA_CalURMCurvature(IntPtr _handPtr, IntPtr SrcImg, int width, int height, DPoint* Points, int Pointnum, ref double curvature, ref int outPointsNum); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe double PIA_CalURMDen(IntPtr _handPtr, IntPtr SrcImg, int width, int height, URMRoiMeasureParam roiparam); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe double PIA_CalURMFractalDim(IntPtr _handPtr, IntPtr SrcImg, int width, int height, URMRoiMeasureParam roiparam); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe double PIA_CalURMVel(IntPtr _handPtr, IntPtr SrcImg, int width, int height, URMRoiMeasureParam roiparam); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe void PIA_ReleaseURMCurvaturePoints(DPoint* pointsptr); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe bool PIA_CalDenMeasureResults(IntPtr _handPtr, IntPtr SrcImg, int width, int height, URMRoiMeasureParam roiparam, double piexlScaler, ref URMDenMeasureResult result); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe bool PIA_CalVelMeasureResults(IntPtr _handPtr, IntPtr SrcImg, int width, int height, URMRoiMeasureParam roiparam, double piexlScaler, ref URMVelMeasureResult result); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe DPoint* PIA_CalVessMeasureResults(IntPtr _handPtr, IntPtr SrcImg, int width, int height, DPoint* Points, int Pointnum, double piexlScaler, ref URMVessMeasureResult result, DPoint* OutPoints, int SamplingPoints); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern double PIA_CalPerfusion(IntPtr handle, IntPtr DenImg, IntPtr VelImg, int width, int height, URMRoiMeasureParam roiparam, ref int rectx, ref int recty, ref int rectwidth, ref int rectheight); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe double PIA_GetPerfusionColorImg(IntPtr handle, IntPtr PerfusionImgPtr, IntPtr colormapptr); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe bool PIA_CalHistogarm(IntPtr handle, IntPtr SrcImg, int width, int height, URMRoiMeasureParam roiparam, DPoint* OutPointsList, int OutPointscount); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern unsafe DPoint* PIA_GetShellOuterPoints(IntPtr _handPtr, int width, int height, DPoint* PointsList, int Pointscount, ref int outerPointCount, double shellwidth, double piexlScaler); [DllImport("ImageProcessAlgWrapLib.dll")] private static extern void PIA_URMMeasure_Release(IntPtr handPtr); private IntPtr _handle; public NativeArray _URMDenMeasureImg; public NativeArray _URMVelMeasureImg; public double _denMax, _denMin; public double _velMax, _velMin; private URMProcess owner; public URMMeasureAlg(URMProcess tf) { _handle = PIA_CreateURMMeasure(); _URMDenMeasureImg = new NativeArray(0); _URMVelMeasureImg = new NativeArray(0); owner = tf; } private unsafe void ReleaseSRCurvaturePoints(DPoint* pointsptr) { PIA_ReleaseURMCurvaturePoints(pointsptr); } public void Relase() { PIA_URMMeasure_Release(_handle); _URMDenMeasureImg.Dispose(); _URMVelMeasureImg.Dispose(); } public URMMeasureDataOutput CalURMMeasureData(URMMeasureDataInput inputparam, int width, int height, double colorMapMax, double colorMapMin) { var result = new URMMeasureDataOutput(); var srcPoint = inputparam.SrcDPoints; if (srcPoint.Count < 1) return result; List piexlPoints = new List(); for (int i = 0; i < srcPoint.Count; i++) { piexlPoints.Add(new DPoint(srcPoint[i].X * width, srcPoint[i].Y * height)); } DPoint[] Points = piexlPoints.ToArray(); owner.CreateURMMeasuerImg(URMType.Den, _URMDenMeasureImg.Start, ref _denMax,ref _denMin); owner.CreateURMMeasuerImg(URMType.Vel, _URMVelMeasureImg.Start, ref _velMax, ref _velMin); double resultData = 0; double velScaler = (_velMax - _velMin) / 255; double denScaler = _denMax / 255.0; double piexlScaler = inputparam.phywidth / width; URMRoiMeasureParam roiparam = new URMRoiMeasureParam(); unsafe { fixed (DPoint* pointsptr = Points) { roiparam.PointsList = pointsptr; roiparam.Pointscount = Points.Length; roiparam.RoiType = inputparam.RoiType; if (roiparam.RoiType == URMROIType.URMShell) { int outershellpointcount = 0; var outpointptr = PIA_GetShellOuterPoints(_handle, width, height, roiparam.PointsList, roiparam.Pointscount, ref outershellpointcount, inputparam.ShellWidth, piexlScaler); for (int i = 0; i < outershellpointcount; i++) { result.OuterExterPoints.Add(new DPoint(outpointptr[i].X, outpointptr[i].Y));//归一化的值 } } switch (inputparam.urmMeasureType) { case URMMeasureType.URMFracetalDim: resultData = PIA_CalURMFractalDim(_handle, _URMDenMeasureImg.Start, width, height, roiparam); result.ResultData = resultData; break; case URMMeasureType.URMVel: resultData = PIA_CalURMVel(_handle, _URMVelMeasureImg.Start, width, height, roiparam); result.ResultData = resultData * velScaler + _velMin; break; case URMMeasureType.URMDen: resultData = PIA_CalURMDen(_handle, _URMDenMeasureImg.Start, width, height, roiparam); result.ResultData = resultData; break; case URMMeasureType.URMCurvature: double curvature = 0; int outpointcount = 0; var outpointptr = PIA_CalURMCurvature(_handle, _URMDenMeasureImg.Start, width, height, pointsptr, Points.Length, ref curvature, ref outpointcount); for (int i = 0; i < outpointcount; i++) { result.ResultDPoints.Add(new DPoint(outpointptr[i].X / width, outpointptr[i].Y / height)); } ReleaseSRCurvaturePoints(outpointptr); result.ResultData = curvature; break; case URMMeasureType.URMTraceCurvature: //弯曲度等于直线距离÷曲线距离 //直线距离就是起点跟终点的距离 //曲线距离就是每两个的距离和 比如有4个点 直线距离就是1点跟4点的距离 弯曲距离就是1和2的距离+2和3的距离 + 3和4的距离 double traceCurvature = 0; double Skelength = 0; //所有点的距离和 for (int i = 0; i < Points.Length; i++) { if (i > 0) { Skelength += Math.Sqrt(Math.Pow((Points[i].X - Points[i - 1].X), 2) + Math.Pow(Points[i].Y - Points[i - 1].Y, 2)); } } double linelength = Math.Sqrt(Math.Pow((Points[0].X - Points.Last().X), 2) + Math.Pow(Points[0].Y - Points.Last().Y, 2)); //起点和终点的距离 Logger.WriteLineInfo("URMCurvature Start Trace" + Points[0].X + " " + Points[0].Y); Logger.WriteLineInfo("URMCurvature End Trace" + Points.Last().X + " " + Points.Last().Y); Logger.WriteLineInfo("URMCurvature linelength Trace" + linelength); Logger.WriteLineInfo("URMCurvature Skelength Trace" + Skelength); traceCurvature = Math.Abs(Skelength / linelength); if (traceCurvature < 1.0) traceCurvature = 1.0; result.ResultData = traceCurvature; break; case URMMeasureType.URMDenMeasure: var denmesureresult = new URMDenMeasureResult(); PIA_CalDenMeasureResults(_handle, _URMDenMeasureImg.Start, width, height, roiparam, piexlScaler, ref denmesureresult); denmesureresult.MaxDensity *= denScaler; denmesureresult.MinDensity *= denScaler; denmesureresult.MeanDensity *= denScaler; denmesureresult.VarianceDensity *= (denScaler * denScaler); if (roiparam.RoiType == URMROIType.URMShell) { denmesureresult.InMaxDensity *= denScaler; denmesureresult.InMinDensity *= denScaler; denmesureresult.InMeanDensity *= denScaler; denmesureresult.InVarianceDensity *= (denScaler * denScaler); denmesureresult.OutMaxDensity *= denScaler; denmesureresult.OutMinDensity *= denScaler; denmesureresult.OutMeanDensity *= denScaler; denmesureresult.OutVarianceDensity *= (denScaler * denScaler); } result.DenMeasureResult = denmesureresult; break; case URMMeasureType.URMVelMeasure: var velmesureresult = new URMVelMeasureResult(); PIA_CalVelMeasureResults(_handle, _URMVelMeasureImg.Start, width, height, roiparam, piexlScaler, ref velmesureresult); velmesureresult.MaxVel = (velmesureresult.MaxVel * velScaler + _velMin); velmesureresult.MinVel = (velmesureresult.MinVel * velScaler + _velMin); ; velmesureresult.MeanVel = (velmesureresult.MeanVel * velScaler + _velMin); velmesureresult.VarianceVel *= (velScaler * velScaler); if (roiparam.RoiType == URMROIType.URMShell) { velmesureresult.InMaxVel = (velmesureresult.InMaxVel * velScaler + _velMin); velmesureresult.InMinVel = (velmesureresult.InMinVel * velScaler + _velMin); velmesureresult.InMeanVel = (velmesureresult.InMeanVel * velScaler + _velMin); velmesureresult.InVarianceVel *= (velScaler * velScaler); velmesureresult.OutMaxVel = (velmesureresult.OutMaxVel * velScaler + _velMin); velmesureresult.OutMinVel = (velmesureresult.OutMinVel * velScaler + _velMin); velmesureresult.OutMeanVel = (velmesureresult.OutMeanVel * velScaler + _velMin); velmesureresult.OutVarianceVel *= (velScaler * velScaler); } result.VelMeasureResult = velmesureresult; break; case URMMeasureType.URMVesselMeasure: var vessmesureresult = new URMVessMeasureResult(); DPoint[] outPoints = new DPoint[inputparam.SamplingPoints]; fixed (DPoint* vessPointptr = outPoints) { var outlocpointptr = PIA_CalVessMeasureResults(_handle, _URMDenMeasureImg.Start, width, height, pointsptr, Points.Length, piexlScaler, ref vessmesureresult, vessPointptr, inputparam.SamplingPoints); for (int i = 0; i < vessmesureresult.vesselCount; i++) { result.OuterExterPoints.Add(new DPoint(outlocpointptr[i].X, outlocpointptr[i].Y));//归一化的值 } ReleaseSRCurvaturePoints(outlocpointptr); } var vessoutdpoints = new List(outPoints); result.ResultDPoints = vessoutdpoints; result.VessMeasureResult = vessmesureresult; break; case URMMeasureType.URMLocationVel: var curpoint = inputparam.SrcDPoints[0]; var col = (int)curpoint.X; var row = (int)curpoint.Y; if (col >= 0 && col < width && row >= 0 && row < height) { var curptr = _URMVelMeasureImg.Start + (row * width + col); byte[] curvel = new byte[1]; Marshal.Copy(curptr, curvel, 0, 1); if (curvel[0] == 0) result.ResultData = 0; else { result.ResultData = (double)curvel[0] * velScaler + _velMin; } } break; case URMMeasureType.URMPerfusion: var perfusioncolormap = owner.GetURMColorMap("SRColorMap:PerfusionMap"); int rectx = 0, recty = 0, rectwidth = 0, rectheight = 0; var perfusion = PIA_CalPerfusion(_handle, _URMDenMeasureImg.Start, _URMVelMeasureImg.Start, width, height, roiparam, ref rectx, ref recty, ref rectwidth, ref rectheight); if (rectwidth == 0 || rectheight == 0) { result.ResultFlag = false; return result; } result.PerfusionPiexlRect = new IntRect(rectx, recty, rectwidth, rectheight); result.PerfusionScaleDRect = new DRect((double)rectx / width, (double)recty / height, (double)rectwidth / width, (double)rectheight / height); result.PerfusionImgData.Resize(rectwidth * rectheight * 4); PIA_GetPerfusionColorImg(_handle, result.PerfusionImgData.Start, perfusioncolormap.Address); result.ResultData = perfusion * _velMax; break; case URMMeasureType.URMHist: DPoint[] outHistPoints = new DPoint[inputparam.SamplingPoints]; var MeasureArray = owner._urmType == URMType.Den ? _URMDenMeasureImg : _URMVelMeasureImg; fixed (DPoint* outHistPointsptr = outHistPoints) { PIA_CalHistogarm(_handle, MeasureArray.Start, width, height, roiparam, outHistPointsptr, inputparam.SamplingPoints); } for (int i = 0; i < outHistPoints.Length; i++) { outHistPoints[i].X = outHistPoints[i].X / 256 * (Math.Abs(colorMapMax - colorMapMin)); } var histoutdpoints = new List(outHistPoints); result.ResultDPoints = histoutdpoints; break; case URMMeasureType.URMDenVelMeasure: var denresult = new URMDenMeasureResult(); PIA_CalDenMeasureResults(_handle, _URMDenMeasureImg.Start, width, height, roiparam, piexlScaler, ref denresult); denresult.MaxDensity *= denScaler; denresult.MinDensity *= denScaler; denresult.MeanDensity *= denScaler; denresult.VarianceDensity *= (denScaler * denScaler); if (roiparam.RoiType == URMROIType.URMShell) { denresult.InMaxDensity *= denScaler; denresult.InMinDensity *= denScaler; denresult.InMeanDensity *= denScaler; denresult.InVarianceDensity *= (denScaler * denScaler); denresult.OutMaxDensity *= denScaler; denresult.OutMinDensity *= denScaler; denresult.OutMeanDensity *= denScaler; denresult.OutVarianceDensity *= (denScaler * denScaler); } result.DenMeasureResult = denresult; var velresult = new URMVelMeasureResult(); PIA_CalVelMeasureResults(_handle, _URMVelMeasureImg.Start, width, height, roiparam, piexlScaler, ref velresult); velresult.MaxVel = (velresult.MaxVel * velScaler + _velMin); velresult.MinVel = (velresult.MinVel * velScaler + _velMin); velresult.MeanVel = (velresult.MeanVel * velScaler + _velMin); velresult.VarianceVel *= (velScaler * velScaler); if (roiparam.RoiType == URMROIType.URMShell) { velresult.InMaxVel = (velresult.InMaxVel * velScaler + _velMin); velresult.InMinVel = (velresult.InMinVel * velScaler + _velMin); velresult.InMeanVel = (velresult.InMeanVel * velScaler + _velMin); velresult.InVarianceVel *= (velScaler * velScaler); velresult.OutMaxVel = (velresult.OutMaxVel * velScaler + _velMin); velresult.OutMinVel = (velresult.OutMinVel * velScaler + _velMin); velresult.OutMeanVel = (velresult.OutMeanVel * velScaler + _velMin); velresult.OutVarianceVel *= (velScaler * velScaler); } result.VelMeasureResult = velresult; break; } } return result; } } } }