/// <summary> /// 三次样条曲线插值(使用数据点数量,直接返回数组) /// </summary> /// <param name="specDatas">第一行为X数据,后面几行为Y数据</param> /// <param name="specRows">数据的行数</param> /// <param name="specCols">数据的列数</param> /// <param name="firstX">起始波数</param> /// <param name="lastX">结束波数</param> /// <param name="dataCount">数据点数量</param> /// <param name="returnArray">直接返回数组</param> /// <returns>返回处理后的数据, 第一行是X轴,其余行为Y轴</returns> public static double[] SplineCubicInterpolation(double[] specDatas, int specRows, int specCols, double firstX, double lastX, int dataCount, bool returnArray) { try { if (specDatas == null || specRows < 2 || specCols < 2 || dataCount < 1) { throw new Exception("Invalid parameters"); } //如果数据格式相同,不需要处理 if (CommonMethod.IsSameXDatas(specDatas[0], specDatas[specCols - 1], firstX, lastX, dataCount) && dataCount == specCols) { return(specDatas); } IntPtr retptr = IntPtr.Zero; if (CommonMethod.Is64BitVersion()) { retptr = PPInterpolationUseDataCount64(specDatas, specRows, specCols, firstX, lastX, dataCount); } else { retptr = PPInterpolationUseDataCount32(specDatas, specRows, specCols, firstX, lastX, dataCount); } if (retptr == IntPtr.Zero) { throw new Exception(CommonMethod.GetDLLErrorMessage()); } double[] retdatas = new double[dataCount * specRows]; Marshal.Copy(retptr, retdatas, 0, retdatas.Length); Marshal.FreeCoTaskMem(retptr); return(retdatas); } catch (Exception ex) { ErrorString = ex.Message; return(null); } }
/// <summary> /// 是否有预处理算法授权 /// </summary> public static bool HasAuthority() { try { if (CommonMethod.Is64BitVersion()) { return(PPHasAuthority64()); } else { return(PPHasAuthority32()); } } catch (Exception ex) { ErrorString = ex.Message; return(false); } }
/// <summary> /// 根据主机光谱创建辅机的校准系数(数据不包含X轴) /// </summary> /// <param name="algorithmType">校准算法</param> /// <param name="masterData">主机数据(一条光谱一行Y轴数据)</param> /// <param name="slaveData">辅机数据(一条光谱一行Y轴数据)</param> /// <param name="windowSize">校准窗口大小</param> /// <param name="tolerance">校准偏差(PLS)</param> /// <param name="firstX">起始波数</param> /// <param name="lastX">结束波数</param> /// <param name="withXDatas">True=masterData和slaveData第一行包含X轴数据</param> /// <returns>校准系数</returns> public static byte[] GetCoefficient(enumAlgorithmType algorithmType, IList <double[]> masterData, IList <double[]> slaveData, int windowSize, double tolerance, double firstX, double lastX, bool withXDatas = false) { if (masterData == null || slaveData == null || masterData.Count < 2 || masterData.Count != slaveData.Count || masterData[0].Length != slaveData[0].Length || windowSize < 1 || masterData[0].Length < windowSize + 1) { ErrorString = "Invalid parameters"; return(null); } double[] allmaster = CommonMethod.CombineSpectrumDatas(masterData); double[] allslave = CommonMethod.CombineSpectrumDatas(slaveData); if (allmaster == null || allslave == null) { ErrorString = "Invalid parameters"; return(null); } return(GetCoefficient(algorithmType, allmaster, allslave, masterData.Count, masterData[0].Length, windowSize, tolerance, firstX, lastX, withXDatas)); }
/// <summary> /// 使用光谱校正系数,校正光谱(不包含X轴数据) /// </summary> /// <param name="coefData">光谱校正系数(BYTE)</param> /// <param name="slaveData">光谱数据</param> /// <returns>校正后的光谱Y轴数据</returns> public static List <double[]> ApplyCoefficient(byte[] coefData, IList <double[]> slaveData) { if (coefData == null || slaveData == null || slaveData.Count == 0) { ErrorString = "Invalid parameters"; return(null); } if (!IsValidCoef(coefData, slaveData[0].Length)) { ErrorString = "Invalid parameters"; return(null); } double[] allslave = CommonMethod.CombineSpectrumDatas(slaveData); if (allslave == null) { ErrorString = "Invalid parameters"; return(null); } double[] retdata = ApplyCoefficient(coefData, allslave, slaveData.Count, slaveData[0].Length, false); if (retdata == null || retdata.Length != allslave.Length) { return(null); } //拷贝每条光谱 //每条光谱的大小为slaveData[0].Length,总共slaveData.Count条 List <double[]> retSpecs = new List <double[]>(); for (int i = 0; i < slaveData.Count; i++) { double[] curdata = new double[slaveData[0].Length]; Array.Copy(retdata, i * curdata.Length, curdata, 0, curdata.Length); retSpecs.Add(curdata); } return(retSpecs); }
/// <summary> /// 使用光谱校正系数,校正光谱 /// </summary> /// <param name="coefData">光谱校正系数(BYTE)</param> /// <param name="slaveData">光谱数据</param> /// <param name="specRows">光谱的数量</param> /// <param name="specCols">每条光谱数据数量</param> /// <param name="withXDatas">是否包含X轴数据</param> /// <returns>校正后的光谱,与slaveData大小相同</returns> public static double[] ApplyCoefficient(byte[] coefData, double[] slaveData, int specRows, int specCols, bool withXDatas) { try { if (coefData == null || slaveData == null || specRows < 1) { throw new Exception("Invalid parameters"); } if (!IsValidCoef(coefData, specCols)) { throw new Exception("Invalid parameters"); } IntPtr retptr = IntPtr.Zero; if (CommonMethod.Is64BitVersion()) { retptr = SDApplyCoefficient64(coefData, slaveData, specRows, specCols, withXDatas); } else { retptr = SDApplyCoefficient32(coefData, slaveData, specRows, specCols, withXDatas); } if (retptr == IntPtr.Zero) { ErrorString = GetErrorMessage(); return(null); } return(CommonMethod.CopyDataArrayFromIntptrAndFree <double>(ref retptr, specCols * specRows)); } catch (Exception ex) { ErrorString = ex.Message; return(null); } }
/// <summary> /// 光谱基线校正 /// </summary> /// <param name="xyDataList">第一项是X,后面是Y</param> /// <param name="method">基线校正方法.</param> /// <returns></returns> public static List <double[]> BaselineCorrect(List <double[]> xyDataList, BaseLineMethod method) { if (xyDataList.Count < 2) { ErrorString = "Invalid parameters"; return(null); } var xyDatas = CommonMethod.CombineSpectrumDatas(xyDataList); if (xyDatas == null) { ErrorString = CommonMethod.ErrorString; return(null); } if (BaselineCorrect(xyDatas, xyDataList.Count, xyDataList[0].Length, method) == false) { return(null); } return(CommonMethod.SplitSpectrumDatas(xyDatas, xyDataList.Count)); }
/// <summary> /// 根据主机光谱创建辅机的校准系数 /// </summary> /// <param name="algorithmType">校准算法</param> /// <param name="masterData">主机数据(一条光谱一行Y轴数据)</param> /// <param name="slaveData">辅机数据(一条光谱一行Y轴数据)</param> /// <param name="specRows">光谱的行数</param> /// <param name="specCols">每条光谱的数据点数量</param> /// <param name="windowSize">校准窗口大小(PDS), RANK(SST)</param> /// <param name="tolerance">校准偏差(PLS)</param> /// <param name="firstX">起始波数</param> /// <param name="lastX">结束波数</param> /// <param name="withXDatas">是否包含X轴数据</param> /// <returns>校准系数</returns> public static byte[] GetCoefficient(enumAlgorithmType algorithmType, double[] masterData, double[] slaveData, int specRows, int specCols, int windowSize, double tolerance, double firstX, double lastX, bool withXDatas) { if (masterData == null || slaveData == null || specRows < 2 || specCols < windowSize + 1 || windowSize < 1 || masterData.Length != specRows * specCols || masterData.Length != slaveData.Length) { ErrorString = "Invalid Parameters"; return(null); } try { IntPtr retptr = IntPtr.Zero; int datasize = 0; switch (algorithmType) { case enumAlgorithmType.PDS: if (CommonMethod.Is64BitVersion()) { retptr = PDSCoefficient64(masterData, slaveData, specRows, specCols, windowSize, firstX, lastX, withXDatas, ref datasize); } else { retptr = PDSCoefficient32(masterData, slaveData, specRows, specCols, windowSize, firstX, lastX, withXDatas, ref datasize); } break; case enumAlgorithmType.PLS: if (CommonMethod.Is64BitVersion()) { retptr = PLSCoefficient64(masterData, slaveData, specRows, specCols, windowSize, tolerance, firstX, lastX, withXDatas, ref datasize); } else { retptr = PLSCoefficient32(masterData, slaveData, specRows, specCols, windowSize, tolerance, firstX, lastX, withXDatas, ref datasize); } break; case enumAlgorithmType.SST: if (CommonMethod.Is64BitVersion()) { retptr = SSTCoefficient64(masterData, slaveData, specRows, specCols, windowSize, firstX, lastX, withXDatas, ref datasize); } else { retptr = SSTCoefficient32(masterData, slaveData, specRows, specCols, windowSize, firstX, lastX, withXDatas, ref datasize); } break; default: break; } if (retptr == IntPtr.Zero) { ErrorString = GetErrorMessage(); return(null); } return(CommonMethod.CopyDataArrayFromIntptrAndFree <byte>(ref retptr, datasize)); } catch (Exception ex) { ErrorString = ex.Message; return(null); } }
/// <summary> /// AdvancedIdentify定性分析(光谱的数据点数量必须相同, X轴也必须相同) /// </summary> /// <param name="apiList">API原始光谱插值后,一列X轴,一列Y轴</param> /// <param name="inferList">干扰组分原光谱插值后,一列X轴,多列Y轴</param> /// <param name="sampleList">待分析物原始光谱插值后,一列X轴,一列Y轴</param> /// <param name="coefMethod">相关方法,0为标准,1为增强</param> /// <param name="baseline">基线校正方法</param> /// <param name="derivatives">导数平滑方法(有基线校正,忽略导数平滑)</param> /// <param name="smoothPoints">平滑窗口大小(5-99)</param> /// <param name="polyDegree">导数的阶数,2,3,4</param> /// <param name="firstX">起始计算X轴,-1表示使用API光谱的firstX</param> /// <param name="lastX">结束计算X轴,-1表示使用API光谱的lastX</param> /// <returns></returns> public static double Identify(List <double[]> apiList, List <double[]> inferList, List <double[]> sampleList, CoefficientMethod coefMethod, BaseLineMethod baseline = BaseLineMethod.None, DerivativeMethod derivatives = DerivativeMethod.None, int smoothPoints = 7, int polyDegree = 2, double firstX = double.MinValue, double lastX = double.MaxValue) { if (apiList.Count != 2 || inferList.Count < 2 || sampleList.Count != 2) { ErrorString = "Invalid parameters"; return(0); } if (smoothPoints > 99 || smoothPoints < 2 || polyDegree < 2 || polyDegree > 4) { ErrorString = "Invalid parameters"; return(0); } //需要截取一部分光谱区间 if (firstX != double.MinValue && lastX != double.MaxValue) { apiList = CommonMethod.GetRangeData(apiList, firstX, lastX); inferList = CommonMethod.GetRangeData(inferList, firstX, lastX); sampleList = CommonMethod.GetRangeData(sampleList, firstX, lastX); } firstX = apiList[0][0]; lastX = apiList[0][apiList[0].Length - 1]; int dataCount = apiList[0].Length; //格式不相同,全部兼容到api光谱 if (!CommonMethod.IsSameXDatas(inferList[0], firstX, lastX, dataCount)) { inferList = Ai.Hong.Algorithm.PreProcessor.SplineCubicInterpolation(inferList, firstX, lastX, dataCount); } if (!CommonMethod.IsSameXDatas(sampleList[0], firstX, lastX, dataCount)) { sampleList = Ai.Hong.Algorithm.PreProcessor.SplineCubicInterpolation(sampleList, firstX, lastX, dataCount); } //限定2种计算系数的方法,1=无权重, 2=强度 coefMethod = coefMethod != CoefficientMethod.Normal ? CoefficientMethod.Weight : coefMethod; //拷贝为数组,好在Ai.Hong.Algorithm中处理 var srcApiDatas = Ai.Hong.Algorithm.CommonMethod.CombineSpectrumDatas(apiList); var apiDatas = Ai.Hong.Algorithm.CommonMethod.CombineSpectrumDatas(apiList); var inferDatas = Ai.Hong.Algorithm.CommonMethod.CombineSpectrumDatas(inferList); var sampleDatas = Ai.Hong.Algorithm.CommonMethod.CombineSpectrumDatas(sampleList); if (apiDatas == null || inferDatas == null || sampleDatas == null) { ErrorString = CommonMethod.ErrorString; return(0); } //需要基线校正 if (baseline != BaseLineMethod.None) { BaselineCorrect(apiDatas, apiList.Count, dataCount, baseline); BaselineCorrect(inferDatas, inferList.Count, dataCount, baseline); BaselineCorrect(sampleDatas, sampleList.Count, dataCount, baseline); } else if (derivatives != DerivativeMethod.None) //导数平滑 { coefMethod = coefMethod == CoefficientMethod.Normal ? coefMethod : CoefficientMethod.SquareWeight; //纪南的程序里面,导数后,增强方法计算系数的方式不一样(使用强度平方) PreProcessor.SGSmoothAndDerivative(apiDatas, apiList.Count, dataCount, smoothPoints, polyDegree, (int)derivatives); PreProcessor.SGSmoothAndDerivative(inferDatas, inferList.Count, dataCount, smoothPoints, polyDegree, (int)derivatives); PreProcessor.SGSmoothAndDerivative(sampleDatas, sampleList.Count, dataCount, smoothPoints, polyDegree, (int)derivatives); //纪南的导数没有除以X轴步长 double stepx = apiDatas[1] - apiDatas[0]; for (int i = dataCount; i < apiDatas.Length; i++) { apiDatas[i] *= stepx; } stepx = inferDatas[1] - inferDatas[0]; for (int i = dataCount; i < inferDatas.Length; i++) { inferDatas[i] *= stepx; } stepx = sampleDatas[1] - sampleDatas[0]; for (int i = dataCount; i < sampleDatas.Length; i++) { sampleDatas[i] *= stepx; } } return(Identify(srcApiDatas, apiDatas, inferDatas, inferList.Count, sampleDatas, coefMethod)); }