6.95
This commit is contained in:
@ -8,6 +8,11 @@ pub fn interpolate_spline(x: Vec<f64>, y: Vec<f64>, step: f64) ->Vec<(f64, f64)>
|
|||||||
spectraltools::interpolate_spline(x, y, step).unwrap()
|
spectraltools::interpolate_spline(x, y, step).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn interpolate_spline_smooth(x: Vec<f64>, y: Vec<f64>, step: f64) ->Vec<(f64, f64)>{
|
||||||
|
spectraltools::interpolate_spline_smooth(x, y, step).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn interpolate_spline_at_points(x: Vec<f64>, y: Vec<f64>, x_target: Vec<f64>) -> Vec<f64>{
|
pub fn interpolate_spline_at_points(x: Vec<f64>, y: Vec<f64>, x_target: Vec<f64>) -> Vec<f64>{
|
||||||
spectraltools::interpolate_spline_at_points(x, y, x_target).unwrap()
|
spectraltools::interpolate_spline_at_points(x, y, x_target).unwrap()
|
||||||
|
|||||||
@ -39,6 +39,40 @@ pub fn interpolate_spline<T: Copy + Into<f64>,>(x_t: Vec<T>, y_t: Vec<T>, step:
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn interpolate_spline_smooth<T: Copy + Into<f64>>(x_t: Vec<T>, y_t: Vec<T>, step: f64) -> Result<Vec<(f64, f64)>, Box<dyn Error>> {
|
||||||
|
let x: Vec<f64> = x_t.iter().map(|&x| x.into()).collect();
|
||||||
|
let y: Vec<f64> = y_t.iter().map(|&y| y.into()).collect();
|
||||||
|
|
||||||
|
if x.len() != y.len() {
|
||||||
|
return Err("x and y must have the same length".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 Catmull-Rom 样条插值(平滑曲线)
|
||||||
|
let keys: Vec<Key<f64, f64>> = x.iter()
|
||||||
|
.zip(y.iter())
|
||||||
|
.map(|(&x, &y)| Key::new(x, y, Interpolation::CatmullRom))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let spline = Spline::from_vec(keys);
|
||||||
|
|
||||||
|
// 计算 x 的最大值和最小值
|
||||||
|
let &start = x.iter().min_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
|
||||||
|
let &end = x.iter().max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
|
||||||
|
|
||||||
|
// 插值到间隔为 step 的点
|
||||||
|
let mut result = Vec::new();
|
||||||
|
let mut t = start;
|
||||||
|
|
||||||
|
while t <= end {
|
||||||
|
if let Some(value) = spline.clamped_sample(t) {
|
||||||
|
result.push((t, value));
|
||||||
|
}
|
||||||
|
t += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn interpolate_spline_at_points<T: Copy + Into<f64>>(x_t: Vec<T>, y_t: Vec<T>, x_target: Vec<f64>) -> Result<Vec<f64>, Box<dyn Error>> {
|
pub fn interpolate_spline_at_points<T: Copy + Into<f64>>(x_t: Vec<T>, y_t: Vec<T>, x_target: Vec<f64>) -> Result<Vec<f64>, Box<dyn Error>> {
|
||||||
let x: Vec<f64> = x_t.iter().map(|&x| x.into()).collect();
|
let x: Vec<f64> = x_t.iter().map(|&x| x.into()).collect();
|
||||||
let y: Vec<f64> = y_t.iter().map(|&y| y.into()).collect();
|
let y: Vec<f64> = y_t.iter().map(|&y| y.into()).collect();
|
||||||
@ -181,4 +215,42 @@ fn test_find_peek(){
|
|||||||
for p in peaks {
|
for p in peaks {
|
||||||
println!("{} {}", p.0, p.1);
|
println!("{} {}", p.0, p.1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_compute_weave_coeff_with_data(){
|
||||||
|
let pixels = vec![79.0, 128.0, 146.0, 157.0, 201.0, 240.0, 261.0, 334.0, 362.0, 436.0];
|
||||||
|
let wavelengths = vec![965.779, 892.869, 866.794, 850.887, 785.482, 727.294, 696.543, 587.092, 546.074, 435.833];
|
||||||
|
|
||||||
|
let result = compute_weave_coeff(pixels.clone(), wavelengths.clone());
|
||||||
|
|
||||||
|
let a0 = result[3]; // 三次项
|
||||||
|
let a1 = result[2]; // 二次项
|
||||||
|
let a2 = result[1]; // 一次项
|
||||||
|
let a3 = result[0]; // 常数项
|
||||||
|
|
||||||
|
println!("=== compute_weave_coeff 原始返回 ===");
|
||||||
|
println!("[{:.15e}, {:.15e}, {:.15e}, {:.15e}]", result[0], result[1], result[2], result[3]);
|
||||||
|
|
||||||
|
println!();
|
||||||
|
println!("=== 前端 bochangxishu ===");
|
||||||
|
println!("a0 (³项) = {:.15e}", a0);
|
||||||
|
println!("a1 (²项) = {:.15e}", a1);
|
||||||
|
println!("a2 (¹项) = {:.15e}", a2);
|
||||||
|
println!("a3 (常数) = {:.15e}", a3);
|
||||||
|
|
||||||
|
println!();
|
||||||
|
println!("=== 拟合验证 ===");
|
||||||
|
for i in 0..pixels.len() {
|
||||||
|
let p = pixels[i];
|
||||||
|
let pred = result[0] + result[1]*p + result[2]*p.powi(2) + result[3]*p.powi(3);
|
||||||
|
println!("像素 {:3.0}: 输入={:.3}nm, 拟合={:.3}nm, 误差={:+.3}nm", p, wavelengths[i], pred, pred-wavelengths[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
println!("=== 前端公式: weave = a0*p³ + a1*p² + a2*p + a3 ===");
|
||||||
|
for &p in &[0.0_f64, 79.0, 128.0, 146.0, 157.0, 201.0, 240.0, 261.0, 334.0, 362.0, 436.0, 2047.0] {
|
||||||
|
let pred = a0*p.powi(3) + a1*p.powi(2) + a2*p + a3;
|
||||||
|
println!("像素 {:4.0}: {:.3}nm", p, pred);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -11,6 +11,7 @@ mod comman1;
|
|||||||
mod myformatiris;
|
mod myformatiris;
|
||||||
use comman1::*;
|
use comman1::*;
|
||||||
use algorithm::interpolate_spline;
|
use algorithm::interpolate_spline;
|
||||||
|
use algorithm::interpolate_spline_smooth;
|
||||||
use algorithm::sg_smooth;
|
use algorithm::sg_smooth;
|
||||||
use mydefine::*;
|
use mydefine::*;
|
||||||
use iris_spectral::spectralbase::Senortype;
|
use iris_spectral::spectralbase::Senortype;
|
||||||
@ -245,6 +246,7 @@ fn main() {
|
|||||||
readformport,
|
readformport,
|
||||||
sendtoport,
|
sendtoport,
|
||||||
interpolate_spline,
|
interpolate_spline,
|
||||||
|
interpolate_spline_smooth,
|
||||||
sg_smooth,
|
sg_smooth,
|
||||||
savecalibratefile,
|
savecalibratefile,
|
||||||
savecalibratefileIRIS,
|
savecalibratefileIRIS,
|
||||||
|
|||||||
@ -463,6 +463,7 @@ export default {
|
|||||||
let coeffweave3 = this.Devinfo.bochangxishu.a2;
|
let coeffweave3 = this.Devinfo.bochangxishu.a2;
|
||||||
let coeffweave4 = this.Devinfo.bochangxishu.a3;
|
let coeffweave4 = this.Devinfo.bochangxishu.a3;
|
||||||
await SensorMethod.Set_Gain(this.sensor_gain_up);
|
await SensorMethod.Set_Gain(this.sensor_gain_up);
|
||||||
|
await SensorMethod.Get_Dark_Data(dire, this.shutter_time_up, Number(this.caijicishu[0]));
|
||||||
var data = await SensorMethod.Get_Date_on_Derction(dire, this.shutter_time_up, true, Number(this.caijicishu[0]))
|
var data = await SensorMethod.Get_Date_on_Derction(dire, this.shutter_time_up, true, Number(this.caijicishu[0]))
|
||||||
let lastvalue = this.DataUP.value_lable;
|
let lastvalue = this.DataUP.value_lable;
|
||||||
this.DataUP = data;
|
this.DataUP = data;
|
||||||
@ -487,6 +488,7 @@ export default {
|
|||||||
let coeffweave3 = this.Devinfo.bochangxishu2.a2;
|
let coeffweave3 = this.Devinfo.bochangxishu2.a2;
|
||||||
let coeffweave4 = this.Devinfo.bochangxishu2.a3;
|
let coeffweave4 = this.Devinfo.bochangxishu2.a3;
|
||||||
await SensorMethod.Set_Gain(this.sensor_gain_down);
|
await SensorMethod.Set_Gain(this.sensor_gain_down);
|
||||||
|
await SensorMethod.Get_Dark_Data(dire, this.shutter_time_up, Number(this.caijicishu[0]));
|
||||||
var data = await SensorMethod.Get_Date_on_Derction(dire, this.shutter_time_down, true, Number(this.caijicishu[1]))
|
var data = await SensorMethod.Get_Date_on_Derction(dire, this.shutter_time_down, true, Number(this.caijicishu[1]))
|
||||||
let lastvalue = this.DataDown.value_lable;
|
let lastvalue = this.DataDown.value_lable;
|
||||||
this.DataDown = data;
|
this.DataDown = data;
|
||||||
|
|||||||
@ -274,7 +274,7 @@ export default {
|
|||||||
if (specindex == 0) {
|
if (specindex == 0) {
|
||||||
let originalData = this.Data.data;
|
let originalData = this.Data.data;
|
||||||
// Step 1: 亚像素插值 (0.05像素间隔,20倍数据量)
|
// Step 1: 亚像素插值 (0.05像素间隔,20倍数据量)
|
||||||
let resampled = await invoke("interpolate_spline", {
|
let resampled = await invoke("interpolate_spline_smooth", {
|
||||||
x: Array.from({length: originalData.length}, (_, i) => i),
|
x: Array.from({length: originalData.length}, (_, i) => i),
|
||||||
y: originalData.map(v => Number(v)),
|
y: originalData.map(v => Number(v)),
|
||||||
step: 0.05
|
step: 0.05
|
||||||
@ -349,7 +349,7 @@ export default {
|
|||||||
else if (specindex == 1) {
|
else if (specindex == 1) {
|
||||||
let originalDataDown = this.DataDown.data;
|
let originalDataDown = this.DataDown.data;
|
||||||
// Step 1: 亚像素插值 (0.05像素间隔,20倍数据量)
|
// Step 1: 亚像素插值 (0.05像素间隔,20倍数据量)
|
||||||
let resampledDown = await invoke("interpolate_spline", {
|
let resampledDown = await invoke("interpolate_spline_smooth", {
|
||||||
x: Array.from({length: originalDataDown.length}, (_, i) => i),
|
x: Array.from({length: originalDataDown.length}, (_, i) => i),
|
||||||
y: originalDataDown.map(v => Number(v)),
|
y: originalDataDown.map(v => Number(v)),
|
||||||
step: 0.05
|
step: 0.05
|
||||||
@ -605,6 +605,8 @@ export default {
|
|||||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth);
|
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth);
|
||||||
chart_up.setOption(this.option);
|
chart_up.setOption(this.option);
|
||||||
|
|
||||||
|
await this.savePeakResultToCSV(0, orgdata);
|
||||||
|
|
||||||
} else if (spectralnumber == 1) {
|
} else if (spectralnumber == 1) {
|
||||||
this.Devinfo.bochangxishu2.a0 = result[3];
|
this.Devinfo.bochangxishu2.a0 = result[3];
|
||||||
this.Devinfo.bochangxishu2.a1 = result[2];
|
this.Devinfo.bochangxishu2.a1 = result[2];
|
||||||
@ -626,6 +628,8 @@ export default {
|
|||||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth_down);
|
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth_down);
|
||||||
chart_up.setOption(this.optiondown);
|
chart_up.setOption(this.optiondown);
|
||||||
|
|
||||||
|
await this.savePeakResultToCSV(1, orgdata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@ -670,7 +674,55 @@ export default {
|
|||||||
|
|
||||||
await fs.writeTextFile(savePath, JSON.stringify(data, null, 2));
|
await fs.writeTextFile(savePath, JSON.stringify(data, null, 2));
|
||||||
},
|
},
|
||||||
|
async savePeakResultToCSV(spectralnumber, orgdata) {
|
||||||
|
if (!orgdata || orgdata.length === 0) return;
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const pad = n => String(n).padStart(2, '0');
|
||||||
|
const dateStr = `${now.getFullYear()}${pad(now.getMonth()+1)}${pad(now.getDate())}_${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
|
||||||
|
const serial = this.Devinfo?.serialnumber || this.Devinfo?.SerilNumber || "Unknown";
|
||||||
|
const isDual = this.Devinfo?.fiber_type === "Dual";
|
||||||
|
const sensorLabel = spectralnumber === 0 ? "UP" : "DOWN";
|
||||||
|
|
||||||
|
let fileSuffix = "";
|
||||||
|
if (isDual) {
|
||||||
|
fileSuffix = `_${sensorLabel}`;
|
||||||
|
}
|
||||||
|
const defaultName = `${serial}${fileSuffix}_${dateStr}.csv`;
|
||||||
|
|
||||||
|
const savePath = await dialog.save({
|
||||||
|
defaultPath: defaultName,
|
||||||
|
filters: [{ name: "CSV文件", extensions: ["csv"] }]
|
||||||
|
});
|
||||||
|
if (!savePath) return;
|
||||||
|
|
||||||
|
const coeff = spectralnumber === 0
|
||||||
|
? [this.Devinfo.bochangxishu.a0, this.Devinfo.bochangxishu.a1, this.Devinfo.bochangxishu.a2, this.Devinfo.bochangxishu.a3]
|
||||||
|
: [this.Devinfo.bochangxishu2.a0, this.Devinfo.bochangxishu2.a1, this.Devinfo.bochangxishu2.a2, this.Devinfo.bochangxishu2.a3];
|
||||||
|
|
||||||
|
let lines = [];
|
||||||
|
lines.push(`# 设备序号: ${serial}`);
|
||||||
|
lines.push(`# 传感器: ${sensorLabel}`);
|
||||||
|
lines.push(`# 时间: ${now.toISOString()}`);
|
||||||
|
for (let i = 0; i < 4; i++) {
|
||||||
|
lines.push(`# a${i}: ${coeff[i]}`);
|
||||||
|
}
|
||||||
|
lines.push("像素,参考波长,拟合波长,误差");
|
||||||
|
|
||||||
|
orgdata.forEach(el => {
|
||||||
|
if (el[3] === true) {
|
||||||
|
let pix = el[2];
|
||||||
|
let refWl = el[4];
|
||||||
|
let fitWl = coeff[0]*pix*pix*pix + coeff[1]*pix*pix + coeff[2]*pix + coeff[3];
|
||||||
|
let err = fitWl - refWl;
|
||||||
|
let errStr = err >= 0 ? "+" + err.toFixed(3) : err.toFixed(3);
|
||||||
|
lines.push(`${pix},${refWl},${fitWl.toFixed(3)},${errStr}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await fs.writeTextFile(savePath, lines.join("\n"));
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 光谱峰自动匹配函数
|
* 光谱峰自动匹配函数
|
||||||
* @param {number[]} detectedPeaks - 检测到的峰位置数组(单位:像素或通道号)
|
* @param {number[]} detectedPeaks - 检测到的峰位置数组(单位:像素或通道号)
|
||||||
|
|||||||
Reference in New Issue
Block a user