Commit f72079a0 authored by Andrey Filippov's avatar Andrey Filippov

Implemented two non-linearities for the 3d3 convolution: add winner and

distributing for the power of coarse velocities
parent b724a8ca
package com.elphel.imagej.cuas.rt; package com.elphel.imagej.cuas.rt;
import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays;
import com.elphel.imagej.cameras.CLTParameters; import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.cameras.EyesisCorrectionParameters.CorrectionParameters; import com.elphel.imagej.cameras.EyesisCorrectionParameters.CorrectionParameters;
...@@ -17,10 +15,16 @@ import ij.ImagePlus; ...@@ -17,10 +15,16 @@ import ij.ImagePlus;
import ij.ImageStack; import ij.ImageStack;
public class CuasDetectRT { public class CuasDetectRT {
public static String SUFFIX_FPIXELS_TIFF = "-CUAS-MERGED-CUAS.tiff"; public static final String SUFFIX_FPIXELS_TIFF = "-CUAS-MERGED-CUAS.tiff";
public static String SUFFIX_LOG = "-LoG"; public static final String SUFFIX_LOG = "-LoG";
public static String SUFFIX_CONV2D = "-CONV2D"; public static final String SUFFIX_CONV2D = "-CONV2D";
public static String SUFFIX_CONV3D3 = "-CONV3D3"; public static final String SUFFIX_CONV3D3 = "-CONV3D3";
public static final String [] CONV3D3_MODES = {"plain", "winner", "power"};
public static final int CONV3D3_MODE_PLAIN = 0;
public static final int CONV3D3_MODE_WINNER = 1;
public static final int CONV3D3_MODE_POWER = 2;
public static final int MAXDECIMALS = 4;
CuasRanging cuasRanging; CuasRanging cuasRanging;
UasLogReader uasLogReader; UasLogReader uasLogReader;
CLTParameters clt_parameters; CLTParameters clt_parameters;
...@@ -89,6 +93,24 @@ public class CuasDetectRT { ...@@ -89,6 +93,24 @@ public class CuasDetectRT {
return; return;
} }
public static String d2s(double d, int maxDecimalsPlaces) {
String fmt = String.format("%%.%df", maxDecimalsPlaces);
String s = String.format(fmt, d);
s = s.trim();
while (s.endsWith("0")) {
s = s.substring(0,s.length()-1);
}
if (s.endsWith(".")) {
s = s.substring(0,s.length()-1);
}
return s;
}
public static String d2s(double d) {
return d2s(d, MAXDECIMALS);
}
public int getWidth() { public int getWidth() {
return width; return width;
} }
...@@ -163,7 +185,7 @@ public class CuasDetectRT { ...@@ -163,7 +185,7 @@ public class CuasDetectRT {
boolean save_3d3_pixels = debugLevel> -4; boolean save_3d3_pixels = debugLevel> -4;
if (save_LoG) { if (save_LoG) {
String title_log = getBaseName()+SUFFIX_LOG+"-PSF"+cuasRTUtils.getPsfRadius()+"-KR"+cuasRTUtils.getKernel2dRadius(); String title_log = getBaseName()+SUFFIX_LOG+"-PSF"+d2s(cuasRTUtils.getPsfRadius())+"-KR"+d2s(cuasRTUtils.getKernel2dRadius());
ImagePlus imp_log = cuasRTUtils.showKernel2d(title_log); ImagePlus imp_log = cuasRTUtils.showKernel2d(title_log);
QuadCLTCPU.saveImagePlusInDirectory(imp_log,getModelDirectory()); QuadCLTCPU.saveImagePlusInDirectory(imp_log,getModelDirectory());
} }
...@@ -171,7 +193,16 @@ public class CuasDetectRT { ...@@ -171,7 +193,16 @@ public class CuasDetectRT {
double [][] dpixels_log = new double [dpixels.length][dpixels[0].length]; double [][] dpixels_log = new double [dpixels.length][dpixels[0].length];
double [] kernel2d = cuasRTUtils.getKernel2d(); double [] kernel2d = cuasRTUtils.getKernel2d();
double alpha0 = 1.0 - clt_parameters.imp.curt_rleak0; double alpha0 = 1.0 - clt_parameters.imp.curt_rleak0;
for (int nseq = 0; nseq < dpixels_log.length; nseq++) { double alpha_pyr = 1.0 - clt_parameters.imp.curt_rleak_pyr;
int curt_3d3_mode = clt_parameters.imp.curt_3d3_mode;
double curt_3d3_frac = clt_parameters.imp.curt_3d3_frac;
double curt_3d3_thrsh = clt_parameters.imp.curt_3d3_thrsh;
double curt_3d3_power = clt_parameters.imp.curt_3d3_power;
double w3d3_now = clt_parameters.imp.curt_3d3_wnow;
double w3d3_prev = clt_parameters.imp.curt_3d3_wprev;
double alpha1 = 1.0 - clt_parameters.imp.curt_rleak1;
for (int nseq = 0; nseq < dpixels_log.length; nseq++) {
cuasRTUtils.convolve2DLReLU( cuasRTUtils.convolve2DLReLU(
dpixels[nseq], // final double [] data, dpixels[nseq], // final double [] data,
kernel2d, // final double [] kernel, // square kernel2d, // final double [] kernel, // square
...@@ -179,8 +210,8 @@ public class CuasDetectRT { ...@@ -179,8 +210,8 @@ public class CuasDetectRT {
alpha0); // final double alpha) alpha0); // final double alpha)
} }
if (save_LoG_pixels) { if (save_LoG_pixels) {
String title_conv2d = getBaseName()+SUFFIX_CONV2D+"-PSF"+cuasRTUtils.getPsfRadius()+ String title_conv2d = getBaseName()+SUFFIX_CONV2D+"-PSF"+d2s(cuasRTUtils.getPsfRadius())+
"-KR"+cuasRTUtils.getKernel2dRadius()+"-ALPHA0_"+alpha0; "-KR"+d2s(cuasRTUtils.getKernel2dRadius())+"-ALPHA0_"+d2s(alpha0);
ImagePlus imp_conv2d = ShowDoubleFloatArrays.makeArrays( ImagePlus imp_conv2d = ShowDoubleFloatArrays.makeArrays(
dpixels_log, // float[][] pixels, dpixels_log, // float[][] pixels,
...@@ -193,14 +224,14 @@ public class CuasDetectRT { ...@@ -193,14 +224,14 @@ public class CuasDetectRT {
QuadCLTCPU.saveImagePlusInDirectory(imp_conv2d, getModelDirectory()); QuadCLTCPU.saveImagePlusInDirectory(imp_conv2d, getModelDirectory());
} }
double w3d3_now = clt_parameters.imp.curt_3d3_wnow;
double w3d3_prev = clt_parameters.imp.curt_3d3_wprev;
double alpha1 = 1.0 - clt_parameters.imp.curt_rleak1;
int dim3d3 = (2*cuasRTUtils.get3d3Radius()+1); int dim3d3 = (2*cuasRTUtils.get3d3Radius()+1);
// int size3x3 = dim3d3 * dim3d3; // int size3x3 = dim3d3 * dim3d3;
double [][][] dpixels_3d3 = new double [dpixels.length-1][width*height][dim3d3 * dim3d3]; double [][][] dpixels_3d3 = new double [dpixels.length-1][width*height][dim3d3 * dim3d3];
String title_conv3d3 = getBaseName()+SUFFIX_CONV3D3+"-PSF"+cuasRTUtils.getPsfRadius()+ String title_conv3d3 = getBaseName()+SUFFIX_CONV3D3+"-PSF"+d2s(cuasRTUtils.getPsfRadius())+
"-KR"+cuasRTUtils.getKernel2dRadius()+"-ALPHA0_"+alpha0+"+N"+w3d3_now+":"+w3d3_prev+"-ALPHA1_"+alpha1; "-KR"+d2s(cuasRTUtils.getKernel2dRadius())+"-ALPHA0_"+d2s(alpha0)+
"-ALPHAPYR_"+d2s(alpha_pyr)+"-M"+curt_3d3_mode+"-F"+d2s(curt_3d3_frac)+"-T"+d2s(curt_3d3_thrsh)+"-P"+d2s(curt_3d3_power)+
"-N"+d2s(w3d3_now)+":"+d2s(w3d3_prev)+
"-ALPHA1_"+d2s(alpha1);
// getTimeStamps(int from_indx) // getTimeStamps(int from_indx)
int dbg_seq = 480; int dbg_seq = 480;
for (int nseq = 1; nseq < dpixels_log.length; nseq++) { for (int nseq = 1; nseq < dpixels_log.length; nseq++) {
...@@ -209,6 +240,10 @@ public class CuasDetectRT { ...@@ -209,6 +240,10 @@ public class CuasDetectRT {
dpixels_log[nseq], // final double [] data, dpixels_log[nseq], // final double [] data,
dpixels_log[nseq-1], // final double [] data_prev, dpixels_log[nseq-1], // final double [] data_prev,
dpixels_3d3[nseq-1], // double [][] result_in, dpixels_3d3[nseq-1], // double [][] result_in,
curt_3d3_mode, // final int mode_3d3,
curt_3d3_frac, // final double curt_3d3_frac, // = 0.5; // for stronger signals give this fraction of the total (of 9) weight to the 1-of-9 winner
curt_3d3_thrsh, //final double curt_3d3_thrsh, // = 1.0; // scale down curt_3d3_frac for weaker signals (in ratio of min(data[now]/curt_3d3_thrsh,1.0)
curt_3d3_power, //final double curt_3d3_power, // = 2.0; // in mode_3d3=2, redistribute coarse velocities weights as the specified power of their positive values (ignore negative ones)
w3d3_now, // final double w_now, // normally 0.5, so center will propagate to the next pyramid levels w3d3_now, // final double w_now, // normally 0.5, so center will propagate to the next pyramid levels
w3d3_prev, // final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels w3d3_prev, // final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels
alpha1, // final double alpha) { alpha1, // final double alpha) {
...@@ -222,6 +257,12 @@ public class CuasDetectRT { ...@@ -222,6 +257,12 @@ public class CuasDetectRT {
QuadCLTCPU.saveImagePlusInDirectory(imp_3d3, getModelDirectory()); QuadCLTCPU.saveImagePlusInDirectory(imp_3d3, getModelDirectory());
} }
// building pyramid // building pyramid
int pyramid_levels = clt_parameters.imp.curt_pyramid; int pyramid_levels = clt_parameters.imp.curt_pyramid;
...@@ -230,8 +271,18 @@ public class CuasDetectRT { ...@@ -230,8 +271,18 @@ public class CuasDetectRT {
double [][][][] dpixels_3d3_pyramid = new double [pyramid_levels][][][]; double [][][][] dpixels_3d3_pyramid = new double [pyramid_levels][][][];
ts_pyramid[0] = getTimeStamps(1); ts_pyramid[0] = getTimeStamps(1);
dpixels_3d3_pyramid[0] = dpixels_3d3; dpixels_3d3_pyramid[0] = dpixels_3d3;
dpixels_pyramid[0] = new double[dpixels_log.length-1][width*height];
for (int nseq = 1; nseq < dpixels_log.length; nseq++) {
cuasRTUtils.temporalAverageLReLU(
dpixels_log[nseq], // final double [] data_now,
dpixels_log[nseq-1], // final double [] data_prev,
dpixels_pyramid[0][nseq-1], // double [] result_in,
alpha_pyr); // final double alpha)
}
// System.arraycopy(dpixels_log, 1, dpixels_pyramid[0], 0, dpixels_pyramid[0].length);
int center9 = 4; int center9 = 4;
for (int nlev = 0; nlev < pyramid_levels; nlev++) { for (int nlev = 0; nlev < pyramid_levels; nlev++) {
/*
// copy centers // copy centers
dpixels_pyramid[nlev] = new double [dpixels_3d3_pyramid[nlev].length][width*height]; dpixels_pyramid[nlev] = new double [dpixels_3d3_pyramid[nlev].length][width*height];
for (int nseq = 0; nseq < dpixels_pyramid[nlev].length; nseq++) { for (int nseq = 0; nseq < dpixels_pyramid[nlev].length; nseq++) {
...@@ -239,10 +290,10 @@ public class CuasDetectRT { ...@@ -239,10 +290,10 @@ public class CuasDetectRT {
dpixels_pyramid[nlev][nseq][npix] = dpixels_3d3_pyramid[nlev][nseq][npix][center9]; dpixels_pyramid[nlev][nseq][npix] = dpixels_3d3_pyramid[nlev][nseq][npix][center9];
} }
} }
*/
if (save_LoG_pixels) { if (save_LoG_pixels) {
String title_conv2d_lev = getBaseName()+SUFFIX_CONV2D+"-PSF"+cuasRTUtils.getPsfRadius()+ String title_conv2d_lev = getBaseName()+SUFFIX_CONV2D+"-PSF"+d2s(cuasRTUtils.getPsfRadius())+
"-KR"+cuasRTUtils.getKernel2dRadius()+"-ALPHA0_"+alpha0+"-LEV"+nlev; "-KR"+d2s(cuasRTUtils.getKernel2dRadius())+"-ALPHA0_"+d2s(alpha0)+"-ALPHAPYR_"+d2s(alpha_pyr)+"-LEV"+nlev;
ImagePlus imp_conv2d = ShowDoubleFloatArrays.makeArrays( ImagePlus imp_conv2d = ShowDoubleFloatArrays.makeArrays(
dpixels_pyramid[nlev], // float[][] pixels, dpixels_pyramid[nlev], // float[][] pixels,
getWidth(), // int width, getWidth(), // int width,
...@@ -256,18 +307,30 @@ public class CuasDetectRT { ...@@ -256,18 +307,30 @@ public class CuasDetectRT {
// run next pyramid level (use half of the temporal slices) // run next pyramid level (use half of the temporal slices)
if (nlev < (pyramid_levels -1)) { if (nlev < (pyramid_levels -1)) {
int num_lev_scenes = (dpixels_pyramid[nlev].length)/2 -1; int num_lev_scenes = (dpixels_pyramid[nlev].length)/2 -1;
dpixels_pyramid[nlev+1] = new double[num_lev_scenes][width*height];
dpixels_3d3_pyramid[nlev+1] = new double [num_lev_scenes][width*height][dim3d3 * dim3d3]; dpixels_3d3_pyramid[nlev+1] = new double [num_lev_scenes][width*height][dim3d3 * dim3d3];
ts_pyramid[nlev+1] = new String[num_lev_scenes]; ts_pyramid[nlev+1] = new String[num_lev_scenes];
for (int nseq = 0; nseq < num_lev_scenes; nseq++) { for (int nseq = 0; nseq < num_lev_scenes; nseq++) {
ts_pyramid[nlev+1][nseq] = ts_pyramid[nlev][2*(nseq + 1)]; ts_pyramid[nlev+1][nseq] = ts_pyramid[nlev][2*(nseq + 1)];
cuasRTUtils.temporalAverageLReLU(
dpixels_pyramid[nlev][2*nseq+2], // final double [] data_now,
dpixels_pyramid[nlev][2*nseq], // final double [] data_prev,
dpixels_pyramid[nlev+1][nseq], // double [] result_in,
alpha_pyr); // final double alpha)
cuasRTUtils.convolve3D3LReLU( cuasRTUtils.convolve3D3LReLU(
dpixels_pyramid[nlev][2*nseq+2], // final double [] data, dpixels_pyramid[nlev][2*nseq+2], // final double [] data,
dpixels_pyramid[nlev][2*nseq], // final double [] data_prev, dpixels_pyramid[nlev][2*nseq], // final double [] data_prev,
dpixels_3d3_pyramid[nlev+1][nseq], // double [][] result_in, dpixels_3d3_pyramid[nlev+1][nseq], // double [][] result_in,
curt_3d3_mode, // final int mode_3d3,
curt_3d3_frac, // final double curt_3d3_frac, // = 0.5; // for stronger signals give this fraction of the total (of 9) weight to the 1-of-9 winner
curt_3d3_thrsh, //final double curt_3d3_thrsh, // = 1.0; // scale down curt_3d3_frac for weaker signals (in ratio of min(data[now]/curt_3d3_thrsh,1.0)
curt_3d3_power, //final double curt_3d3_power, // = 2.0; // in mode_3d3=2, redistribute coarse velocities weights as the specified power of their positive values (ignore negative ones)
w3d3_now, // final double w_now, // normally 0.5, so center will propagate to the next pyramid levels w3d3_now, // final double w_now, // normally 0.5, so center will propagate to the next pyramid levels
w3d3_prev, // final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels w3d3_prev, // final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels
alpha1, // final double alpha) { alpha1, // final double alpha) {
debugLevel); // final int debugLevel) debugLevel); // final int debugLevel)
} }
if (save_3d3_pixels) { if (save_3d3_pixels) {
ImagePlus imp_3d3 = cuasRTUtils.render3d3Hyperstack( ImagePlus imp_3d3 = cuasRTUtils.render3d3Hyperstack(
......
...@@ -184,6 +184,7 @@ public class CuasRTUtils { ...@@ -184,6 +184,7 @@ public class CuasRTUtils {
throw new IllegalArgumentException("Kernel length = "+kernel.length+" does not match kernel size (2*"+kernel2d_rad+"+1) * (2*"+kernel2d_rad+"+1) ="+(kernel_size * kernel_size)); throw new IllegalArgumentException("Kernel length = "+kernel.length+" does not match kernel size (2*"+kernel2d_rad+"+1) * (2*"+kernel2d_rad+"+1) ="+(kernel_size * kernel_size));
} }
} }
public double [][][] convolve3d( public double [][][] convolve3d(
final double [][][] data, // outer index - historic layers, [0] - latest, second index - pixel, third - direction ([9]) final double [][][] data, // outer index - historic layers, [0] - latest, second index - pixel, third - direction ([9])
double [][][] result_in){ double [][][] result_in){
...@@ -198,8 +199,6 @@ public class CuasRTUtils { ...@@ -198,8 +199,6 @@ public class CuasRTUtils {
for (int nhist = 0; nhist < nlayers; nhist++) { for (int nhist = 0; nhist < nlayers; nhist++) {
final int fhist = nhist; final int fhist = nhist;
final int spat_rad = consolidationKernel.getSpatialRadius(); // may be later dependent on nhist for efficiency final int spat_rad = consolidationKernel.getSpatialRadius(); // may be later dependent on nhist for efficiency
// final int spat_dim = consolidationKernel.getSpatialDim();
// final int tl_offset = spat_rad * (width+1);
final double [][][][] kernel_hist = kernel[fhist]; final double [][][][] kernel_hist = kernel[fhist];
final double [][] data_hist = data[fhist]; final double [][] data_hist = data[fhist];
ai.set(0); ai.set(0);
...@@ -289,6 +288,330 @@ public class CuasRTUtils { ...@@ -289,6 +288,330 @@ public class CuasRTUtils {
} }
return result; return result;
} }
public double[][] convolve3D3LReLU(
final double [] data,
final double [] data_prev,
double [][] result_in,
final int mode_3d3,
final double curt_3d3_frac, // = 0.5; // for stronger signals give this fraction of the total (of 9) weight to the 1-of-9 winner
final double curt_3d3_thrsh, // = 1.0; // scale down curt_3d3_frac for weaker signals (in ratio of min(data[now]/curt_3d3_thrsh,1.0)
final double curt_3d3_power, // = 2.0; // in mode_3d3=2, redistribute coarse velocities weights as the specified power of their positive values (ignore negative ones)
final double w_now, // normally 0.5, so center will propagate to the next pyramid levels
final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels
final double alpha,
final int debugLevel) {
switch (mode_3d3) {
case CuasDetectRT.CONV3D3_MODE_PLAIN:
return convolve3D3LReLU(
data, // final double [] data,
data_prev, // final double [] data_prev,
result_in, // double [][] result_in,
w_now, // final double w_now, // normally 0.5, so center will propagate to the next pyramid levels
w_prev, // final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels
alpha, // final double alpha,
debugLevel); // final int debugLevel)
case CuasDetectRT.CONV3D3_MODE_WINNER:
return convolve3D3LReLU(
data, // final double [] data,
data_prev, // final double [] data_prev,
result_in, // double [][] result_in,
curt_3d3_frac, // final double curt_3d3_frac, // = 0.5; // for stronger signals give this fraction of the total (of 9) weight to the 1-of-9 winner
curt_3d3_thrsh, //final double curt_3d3_thrsh, // = 1.0; // scale down curt_3d3_frac for weaker signals (in ratio of min(data[now]/curt_3d3_thrsh,1.0)
w_now, // final double w_now, // normally 0.5, so center will propagate to the next pyramid levels
w_prev, // final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels
alpha, // final double alpha,
debugLevel); // final int debugLevel)
case CuasDetectRT.CONV3D3_MODE_POWER:
return convolve3D3LReLU(
data, // final double [] data,
data_prev, // final double [] data_prev,
result_in, // double [][] result_in,
curt_3d3_frac, // final double curt_3d3_frac, // = 0.5; // for stronger signals give this fraction of the total (of 9) weight to the 1-of-9 winner
curt_3d3_thrsh, // final double curt_3d3_thrsh, // = 1.0; // scale down curt_3d3_frac for weaker signals (in ratio of min(data[now]/curt_3d3_thrsh,1.0)
curt_3d3_power, // final double curt_3d3_power, // = 2.0; // in mode_3d3=2, redistribute coarse velocities weights as the specified power of their positive values (ignore negative ones)
w_now, // final double w_now, // normally 0.5, so center will propagate to the next pyramid levels
w_prev, // final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels
alpha, // final double alpha,
debugLevel); // final int debugLevel)
default:
System.out.println ("convolve3D3LReLU(): mode_3d3="+mode_3d3+" is undefined");
return null;
}
}
/**
*
* @param data
* @param data_prev
* @param result_in
* @param curt_3d3_frac
* @param curt_3d3_thrsh
* @param w_now
* @param w_prev
* @param alpha
* @param debugLevel
* @return
*/
public double[][] convolve3D3LReLU(
final double [] data,
final double [] data_prev,
double [][] result_in,
final double curt_3d3_frac, // = 0.5; // for stronger signals give this fraction of the total (of 9) weight to the 1-of-9 winner
final double curt_3d3_thrsh, // = 1.0; // scale down curt_3d3_frac for weaker signals (in ratio of min(data[now]/curt_3d3_thrsh,1.0)
final double w_now, // normally 0.5, so center will propagate to the next pyramid levels
final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels
final double alpha,
final int debugLevel) {
final int kern_size_3d3 = 2 * kernel3d3_rad + 1;
final double [][] result = (result_in != null) ? result_in : new double [data.length][kern_size_3d3*kern_size_3d3];
int dbg_thresh = 10; // -4;
checkData(data);
checkData(data_prev);
checkData(result);
final int tl_offset = kernel3d3_rad * (width+1);
final int center_index = 2 * kernel3d3_rad * (kernel3d3_rad + 1);
final int row_offset = width - (2*kernel3d3_rad +1);
final int dbg_pix = (debugLevel > dbg_thresh) ? (300+ 173*width):-1;
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
// processing center area, no need to care about margins
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [] coarse_vel = new double [kern_size_3d3*kern_size_3d3];
for (int nPix = ai.getAndIncrement(); nPix < indx_center_3d3.length; nPix = ai.getAndIncrement()) {
int ipix_dst = indx_center_3d3[nPix];
if (ipix_dst == dbg_pix) {
System.out.println("convolve3D3LReLU(): ipix_dst="+ipix_dst);
}
int ipix_prev = ipix_dst- tl_offset;
int ikern = kern_size_3d3*kern_size_3d3;
Arrays.fill(coarse_vel, 0);
double v0 = w_now * data[ipix_dst]; // will be added to all velocity outputs
for (int iy = 0; iy < kern_size_3d3; iy++) {
for (int ix = 0; ix < kern_size_3d3; ix++) {
double v = data_prev[ipix_prev++] * w_prev + v0;
coarse_vel[--ikern] = v;
}
ipix_prev += row_offset;
}
// velocity competition
double frac = Math.min(curt_3d3_frac, data[ipix_dst]/curt_3d3_thrsh);
if (frac > 0) {
double sumv = 0;
int imx = 0;
double bestd=coarse_vel[imx];
for (int i = 0; i < coarse_vel.length;i++) {
double d = coarse_vel[i];
sumv += d;
coarse_vel[i] = d * (1.0 -frac);
if (d > bestd) {
imx = i;
bestd= d;
}
}
coarse_vel[imx] += sumv * frac;
}
// Apply LReLU
for (int i = 0; i < coarse_vel.length;i++) {
double v = coarse_vel[i];
result[ipix_dst][i] = Math.max(v, alpha * v);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
// marginal area, check indices
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
TileNeibs tn = new TileNeibs(width, height);
double [] coarse_vel = new double [kern_size_3d3*kern_size_3d3];
for (int nPix = ai.getAndIncrement(); nPix < indx_margins_3d3.length; nPix = ai.getAndIncrement()) {
int ipix_dst = indx_margins_3d3[nPix];
int ikern = kern_size_3d3*kern_size_3d3;
Arrays.fill(coarse_vel, 0);
double v0 = w_now * data[ipix_dst]; // will be added to all velocity outputs
for (int iy = 0; iy < kern_size_3d3; iy++) {
int dy = iy-kernel3d3_rad;
for (int ix = 0; ix < kern_size_3d3; ix++) {
int dx = ix-kernel3d3_rad;
int ipix_prev = tn.getNeibIndex(ipix_dst, dx, dy);
double v = v0;
if (ipix_prev >= 0) {
v += data_prev[ipix_prev] * w_prev;
}
coarse_vel[--ikern] = v;
}
}
// velocity competition
double frac = Math.min(curt_3d3_frac, data[ipix_dst]/curt_3d3_thrsh);
if (frac > 0) {
double sumv = 0;
int imx = 0;
double bestd=coarse_vel[imx];
for (int i = 0; i < coarse_vel.length;i++) {
double d = coarse_vel[i];
sumv += d;
coarse_vel[i] = d * (1.0 -frac);
if (d > bestd) {
imx = i;
bestd= d;
}
}
coarse_vel[imx] += sumv * frac;
}
// Apply LReLU
for (int i = 0; i < coarse_vel.length;i++) {
double v = coarse_vel[i];
result[ipix_dst][i] = Math.max(v, alpha * v);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return result;
}
public double[][] convolve3D3LReLU(
final double [] data,
final double [] data_prev,
double [][] result_in,
final double curt_3d3_frac, // = 0.5; // for stronger signals give this fraction of the total (of 9) weight to the 1-of-9 winner
final double curt_3d3_thrsh, // = 1.0; // scale down curt_3d3_frac for weaker signals (in ratio of min(data[now]/curt_3d3_thrsh,1.0)
final double curt_3d3_power, // = 2.0; // in mode_3d3=2, redistribute coarse velocities weights as the specified power of their positive values (ignore negative ones)
final double w_now, // normally 0.5, so center will propagate to the next pyramid levels
final double w_prev,// normally 0.5, so center will propagate to the next pyramid levels
final double alpha,
final int debugLevel) {
final int kern_size_3d3 = 2 * kernel3d3_rad + 1;
final double [][] result = (result_in != null) ? result_in : new double [data.length][kern_size_3d3*kern_size_3d3];
int dbg_thresh = 10; // -4;
checkData(data);
checkData(data_prev);
checkData(result);
final int tl_offset = kernel3d3_rad * (width+1);
// final int center_index = 2 * kernel3d3_rad * (kernel3d3_rad + 1);
final int row_offset = width - (2*kernel3d3_rad +1);
final int dbg_pix = (debugLevel > dbg_thresh) ? (300+ 173*width):-1;
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
// processing center area, no need to care about margins
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [] coarse_vel = new double [kern_size_3d3*kern_size_3d3];
double [] coarse_vel_pwr = new double [kern_size_3d3*kern_size_3d3];
for (int nPix = ai.getAndIncrement(); nPix < indx_center_3d3.length; nPix = ai.getAndIncrement()) {
int ipix_dst = indx_center_3d3[nPix];
if (ipix_dst == dbg_pix) {
System.out.println("convolve3D3LReLU(): ipix_dst="+ipix_dst);
}
int ipix_prev = ipix_dst- tl_offset;
int ikern = kern_size_3d3*kern_size_3d3;
Arrays.fill(coarse_vel, 0);
Arrays.fill(coarse_vel_pwr, 0);
double v0 = w_now * data[ipix_dst]; // will be added to all velocity outputs
for (int iy = 0; iy < kern_size_3d3; iy++) {
for (int ix = 0; ix < kern_size_3d3; ix++) {
double v = data_prev[ipix_prev++] * w_prev + v0;
coarse_vel[--ikern] = v;
}
ipix_prev += row_offset;
}
// velocity competition
double frac = Math.min(curt_3d3_frac, data[ipix_dst]/curt_3d3_thrsh);
if (frac > 0) {
double sumv = 0;
double sumv_pwr = 0;
for (int i = 0; i < coarse_vel.length;i++) {
double d = coarse_vel[i]; // includes v0;
double d_pwr = (d > 0) ? Math.pow(d, curt_3d3_power) : 0;
sumv += d;
sumv_pwr += d_pwr;
coarse_vel_pwr[i] = d_pwr;
}
double w = sumv * frac / sumv_pwr;
if (sumv_pwr > 0) {
for (int i = 0; i < coarse_vel.length;i++) {
coarse_vel[i] = (1.0 -frac) * coarse_vel[i] + w * coarse_vel_pwr[i];
}
}
}
// Apply LReLU
for (int i = 0; i < coarse_vel.length;i++) {
double v = coarse_vel[i];
result[ipix_dst][i] = Math.max(v, alpha * v);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
// marginal area, check indices
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
TileNeibs tn = new TileNeibs(width, height);
double [] coarse_vel = new double [kern_size_3d3*kern_size_3d3];
double [] coarse_vel_pwr = new double [kern_size_3d3*kern_size_3d3];
for (int nPix = ai.getAndIncrement(); nPix < indx_margins_3d3.length; nPix = ai.getAndIncrement()) {
int ipix_dst = indx_margins_3d3[nPix];
int ikern = kern_size_3d3*kern_size_3d3;
Arrays.fill(coarse_vel, 0);
Arrays.fill(coarse_vel_pwr, 0);
double v0 = w_now * data[ipix_dst]; // will be added to all velocity outputs
for (int iy = 0; iy < kern_size_3d3; iy++) {
int dy = iy-kernel3d3_rad;
for (int ix = 0; ix < kern_size_3d3; ix++) {
int dx = ix-kernel3d3_rad;
int ipix_prev = tn.getNeibIndex(ipix_dst, dx, dy);
double v = v0;
if (ipix_prev >= 0) {
v += data_prev[ipix_prev] * w_prev;
}
coarse_vel[--ikern] = v;
}
}
// velocity competition
double frac = Math.min(curt_3d3_frac, data[ipix_dst]/curt_3d3_thrsh);
if (frac > 0) {
double sumv = 0;
double sumv_pwr = 0;
for (int i = 0; i < coarse_vel.length;i++) {
double d = coarse_vel[i]; // includes v0;
double d_pwr = (d > 0) ? Math.pow(d, curt_3d3_power) : 0;
sumv += d;
sumv_pwr += d_pwr;
coarse_vel_pwr[i] = d_pwr;
}
double w = sumv * frac / sumv_pwr;
if (sumv_pwr > 0) {
for (int i = 0; i < coarse_vel.length;i++) {
coarse_vel[i] = (1.0 -frac) * coarse_vel[i] + w * coarse_vel_pwr[i];
}
}
}
// Apply LReLU
for (int i = 0; i < coarse_vel.length;i++) {
double v = coarse_vel[i];
result[ipix_dst][i] = Math.max(v, alpha * v);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return result;
}
...@@ -365,6 +688,41 @@ public class CuasRTUtils { ...@@ -365,6 +688,41 @@ public class CuasRTUtils {
return result; return result;
} }
/**
* Combine (pairwise average)2 pixel arrays
* @param data_now pixel data [width*height]
* @param data_prev pixel data [width*height]
* @param result_in allocated pixel array or null (to be allocated)
* @param alpha for LReLU (0 - classic ReLU, 1.0 - linear transfer, no ReLU)
* @return result pixel array, same as result_in if not null
*/
public double[] temporalAverageLReLU(
final double [] data_now,
final double [] data_prev,
double [] result_in,
final double alpha) {
// assuming symmetrical kernel, not inverting indices
final double [] result = (result_in != null) ? result_in : new double [data_now.length];
final int kernel_size = 2 * kernel2d_rad + 1;
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
// processing center area, no need to care about margins
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nPix = ai.getAndIncrement(); nPix < indx_all_2d.length; nPix = ai.getAndIncrement()) {
int ipix = indx_all_2d[nPix];
double v = 0.5*(data_now[ipix]+data_prev[ipix]);
result[ipix] = Math.max(v, alpha * v);
}
}
};
}
ImageDtt.startAndJoin(threads);
return result;
}
public double[] convolve2DLReLU( public double[] convolve2DLReLU(
final double [] data, final double [] data,
......
...@@ -31,6 +31,7 @@ import java.util.StringTokenizer; ...@@ -31,6 +31,7 @@ import java.util.StringTokenizer;
import com.elphel.imagej.common.GenericJTabbedDialogMcp; // codex 2026-01-25 import com.elphel.imagej.common.GenericJTabbedDialogMcp; // codex 2026-01-25
import com.elphel.imagej.cuas.CuasMotion; import com.elphel.imagej.cuas.CuasMotion;
import com.elphel.imagej.cuas.rt.CuasDetectRT;
import com.elphel.imagej.orthomosaic.ComboMatch; import com.elphel.imagej.orthomosaic.ComboMatch;
import com.elphel.imagej.vegetation.VegetationLMA; import com.elphel.imagej.vegetation.VegetationLMA;
...@@ -1123,16 +1124,23 @@ min_str_neib_fpn 0.35 ...@@ -1123,16 +1124,23 @@ min_str_neib_fpn 0.35
public double cuas_rng_limit = 5000; // maximal displayed distance to target public double cuas_rng_limit = 5000; // maximal displayed distance to target
// CUAS Realtime // CUAS Realtime
public boolean curt_en = false; // enable cuas rt calculation public boolean curt_en = true; // enable cuas rt calculation (not needed with a separate button)
public int curt_pyramid = 7; // temporal pyramid levels //=== LoG prefilter ===
public double curt_psf_radius = 1.6; // sensor PSF radius for LoG pre-filter public double curt_psf_radius = 1.0; // sensor PSF radius for LoG pre-filter
public double curt_n_sigma = 4.0; // cutoff LoG kernel array, number of sigmas public double curt_n_sigma = 4.0; // cutoff LoG kernel array, number of sigmas
public double curt_rleak0 = 0.1; // 1-ReLU leak (0 - linear, 1.0 - classic ReLU) for the LoG prefilter public double curt_rleak0 = 0.1; // 1-ReLU leak (0 - linear, 1.0 - classic ReLU) for the LoG prefilter
//=== Temporal binary pyramid ===
public int curt_pyramid = 7; // temporal pyramid levels
public double curt_rleak_pyr = 0.1; // 1-ReLU leak (0 - linear, 1.0 - classic ReLU) after averaging 2 consecutive samples
// === Coarse velocities layer (from -1 to +1 in each direction, 9 total) ===
public int curt_3d3_mode = 2; // 0 (plain) integration, 1 - fraction to the winner, 2 use strength power
public double curt_3d3_frac = 0.5; // for stronger signals give this fraction of the total (of 9) weight to the 1-of-9 winner
public double curt_3d3_thrsh = 1.0; // scale down curt_3d3_frac for weaker signals (in ratio of min(data[now]/curt_3d3_thrsh,1.0)
public double curt_3d3_power = 2.0; // in mode_3d3=2, redistribute coarse velocities weights as the specified power of their positive values (ignore negative ones)
public double curt_3d3_wnow = 0.5; // Weight of the latest (now) temporal slice when creating coarse velocities public double curt_3d3_wnow = 0.5; // Weight of the latest (now) temporal slice when creating coarse velocities
public double curt_3d3_wprev = 0.5; // Weight of the previous temporal slice when creating coarse velocities public double curt_3d3_wprev = 0.5; // Weight of the previous temporal slice when creating coarse velocities
public double curt_rleak1 = 0.1; // 1-ReLU leak (0 - linear, 1.0 - classic ReLU) for the coarse velocity 3d convolution public double curt_rleak1 = 0.1; // 1-ReLU leak (0 - linear, 1.0 - classic ReLU) for the coarse velocity 3d convolution
// === Fine velocities layer ===
public int curt_pix_decimate = 1; // decimate pixel resolution public int curt_pix_decimate = 1; // decimate pixel resolution
public int curt_vel_decimate = 4; // decimate velocities public int curt_vel_decimate = 4; // decimate velocities
public int curt_vel_radius = 5; // velocities radius in decimated samples public int curt_vel_radius = 5; // velocities radius in decimated samples
...@@ -3358,20 +3366,38 @@ min_str_neib_fpn 0.35 ...@@ -3358,20 +3366,38 @@ min_str_neib_fpn 0.35
gd.addTab("CUAS RT", "CUAS Real Time"); gd.addTab("CUAS RT", "CUAS Real Time");
gd.addCheckbox ("CUAS realtime enable", this.curt_en, gd.addCheckbox ("CUAS realtime enable", this.curt_en,
"Enable testing of the realtime CUAS detection."); "Enable testing of the realtime CUAS detection.");
gd.addNumericField("Temporal pyramid levels", this.curt_pyramid, 0,3,"",
"Number of binary temporal pyramid levels."); gd.addMessage("=== LoG prefilter ===");
gd.addNumericField("Optical PSF radius", this.curt_psf_radius, 6,8,"pix", gd.addNumericField("Optical PSF radius", this.curt_psf_radius, 6,8,"pix",
"Sensor optical PSF radius for the LoG pre-filter."); "Sensor optical PSF radius for the LoG pre-filter.");
gd.addNumericField("N-sigmas for LoG cutoff", this.curt_n_sigma, 6,8,"x", gd.addNumericField("N-sigmas for LoG cutoff", this.curt_n_sigma, 6,8,"x",
"Cutoff LoG kernel array, number of sigmas."); "Cutoff LoG kernel array, number of sigmas.");
gd.addNumericField("Reversed LReLU LoG leak", this.curt_rleak0, 6,8,"x", gd.addNumericField("Reversed LReLU LoG leak", this.curt_rleak0, 6,8,"x",
"1-ReLU leak (0 - linear, 1.0 - classic ReLU) for the LoG prefilter."); "1-ReLU leak (0 - linear, 1.0 - classic ReLU) for the LoG prefilter.");
gd.addMessage("=== Temporal binary pyramid ===");
gd.addNumericField("Temporal pyramid levels", this.curt_pyramid, 0,3,"",
"Number of binary temporal pyramid levels.");
gd.addNumericField("Reversed LReLU leak after 2:1 averaging",this.curt_rleak_pyr, 6,8,"x",
"1-ReLU leak (0 - linear, 1.0 - classic ReLU) after merging to consecutive samples from the previous level data.");
gd.addMessage("=== Coarse velocities layer (from -1 to +1 in each direction, 9 total) ===");
gd. addChoice("Coarse velocities non-linearities mode", CuasDetectRT.CONV3D3_MODES, CuasDetectRT.CONV3D3_MODES[this.curt_3d3_mode],
"0 (plain) integration only, 1 - fraction to the winner, 2 - use velocities strength power.");
gd.addNumericField("Fraction for the winner", this.curt_3d3_frac, 6,8,"x",
"For stronger signals give this fraction of the total (of 9) weight to the 1-of-9 winner.");
gd.addNumericField("Winner threshold", this.curt_3d3_thrsh, 6,8,"x",
"Scale (down) curt_3d3_frac for weaker signals (in ratio of min(data[now]/curt_3d3_thrsh,1.0).");
gd.addNumericField("Velocities power", this.curt_3d3_power, 6,8,"x",
"In mode_3d3=2, redistribute coarse velocities weights as the specified power of their positive values (ignore negative ones).");
gd.addNumericField("Coarse velocities weight now", this.curt_3d3_wnow, 6,8,"x", gd.addNumericField("Coarse velocities weight now", this.curt_3d3_wnow, 6,8,"x",
"Weight of the latest (now) temporal slice when creating coarse velocities."); "Weight of the latest (now) temporal slice when creating coarse velocities.");
gd.addNumericField("Coarse velocities weight previous", this.curt_3d3_wprev, 6,8,"x", gd.addNumericField("Coarse velocities weight previous", this.curt_3d3_wprev, 6,8,"x",
"Weight of the previous temporal slice when creating coarse velocities."); "Weight of the previous temporal slice when creating coarse velocities.");
gd.addNumericField("Reversed LReLU 3d3 leak", this.curt_rleak1, 6,8,"x", gd.addNumericField("Reversed LReLU 3d3 leak", this.curt_rleak1, 6,8,"x",
" 1-ReLU leak (0 - linear, 1.0 - classic ReLU) for the coarse velocity 3d convolution."); " 1-ReLU leak (0 - linear, 1.0 - classic ReLU) for the coarse velocity 3d convolution.");
gd.addMessage("=== Fine velocities layer ===");
gd.addNumericField("Pixel decimate", this.curt_pix_decimate, 0,3,"", gd.addNumericField("Pixel decimate", this.curt_pix_decimate, 0,3,"",
"Decimate pixels (increase resolution)."); "Decimate pixels (increase resolution).");
gd.addNumericField("Velocity decimate", this.curt_vel_decimate, 0,3,"", gd.addNumericField("Velocity decimate", this.curt_vel_decimate, 0,3,"",
...@@ -4854,13 +4880,22 @@ min_str_neib_fpn 0.35 ...@@ -4854,13 +4880,22 @@ min_str_neib_fpn 0.35
this.cuas_rng_limit = gd.getNextNumber(); this.cuas_rng_limit = gd.getNextNumber();
this.curt_en = gd.getNextBoolean(); this.curt_en = gd.getNextBoolean();
this.curt_pyramid = (int) gd.getNextNumber();
this.curt_psf_radius = gd.getNextNumber(); this.curt_psf_radius = gd.getNextNumber();
this.curt_n_sigma = gd.getNextNumber(); this.curt_n_sigma = gd.getNextNumber();
this.curt_rleak0 = gd.getNextNumber(); this.curt_rleak0 = gd.getNextNumber();
this.curt_pyramid = (int) gd.getNextNumber();
this.curt_rleak_pyr = gd.getNextNumber();
this.curt_3d3_mode = gd.getNextChoiceIndex();
this.curt_3d3_frac = gd.getNextNumber();
this.curt_3d3_thrsh = gd.getNextNumber();
this.curt_3d3_power = gd.getNextNumber();
this.curt_3d3_wnow = gd.getNextNumber(); this.curt_3d3_wnow = gd.getNextNumber();
this.curt_3d3_wprev = gd.getNextNumber(); this.curt_3d3_wprev = gd.getNextNumber();
this.curt_rleak1 = gd.getNextNumber(); this.curt_rleak1 = gd.getNextNumber();
this.curt_pix_decimate = (int) gd.getNextNumber(); this.curt_pix_decimate = (int) gd.getNextNumber();
this.curt_vel_decimate = (int) gd.getNextNumber(); this.curt_vel_decimate = (int) gd.getNextNumber();
this.curt_vel_radius = (int) gd.getNextNumber(); this.curt_vel_radius = (int) gd.getNextNumber();
...@@ -6167,13 +6202,22 @@ min_str_neib_fpn 0.35 ...@@ -6167,13 +6202,22 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_rng_limit", this.cuas_rng_limit+""); // double properties.setProperty(prefix+"cuas_rng_limit", this.cuas_rng_limit+""); // double
properties.setProperty(prefix+"curt_en", this.curt_en+""); // boolean properties.setProperty(prefix+"curt_en", this.curt_en+""); // boolean
properties.setProperty(prefix+"curt_pyramid", this.curt_pyramid+""); // int
properties.setProperty(prefix+"curt_psf_radius", this.curt_psf_radius+""); // double properties.setProperty(prefix+"curt_psf_radius", this.curt_psf_radius+""); // double
properties.setProperty(prefix+"curt_n_sigma", this.curt_n_sigma+""); // double properties.setProperty(prefix+"curt_n_sigma", this.curt_n_sigma+""); // double
properties.setProperty(prefix+"curt_rleak0", this.curt_rleak0+""); // double properties.setProperty(prefix+"curt_rleak0", this.curt_rleak0+""); // double
properties.setProperty(prefix+"curt_pyramid", this.curt_pyramid+""); // int
properties.setProperty(prefix+"curt_rleak_pyr", this.curt_rleak_pyr+""); // double
properties.setProperty(prefix+"curt_3d3_mode", this.curt_3d3_mode+""); // int
properties.setProperty(prefix+"curt_3d3_frac", this.curt_3d3_frac+""); // double
properties.setProperty(prefix+"curt_3d3_thrsh", this.curt_3d3_thrsh+""); // double
properties.setProperty(prefix+"curt_3d3_power", this.curt_3d3_power+""); // double
properties.setProperty(prefix+"curt_3d3_wnow", this.curt_3d3_wnow+""); // double properties.setProperty(prefix+"curt_3d3_wnow", this.curt_3d3_wnow+""); // double
properties.setProperty(prefix+"curt_3d3_wprev", this.curt_3d3_wprev+""); // double properties.setProperty(prefix+"curt_3d3_wprev", this.curt_3d3_wprev+""); // double
properties.setProperty(prefix+"curt_rleak1", this.curt_rleak1+""); // double properties.setProperty(prefix+"curt_rleak1", this.curt_rleak1+""); // double
properties.setProperty(prefix+"curt_pix_decimate", this.curt_pix_decimate+""); // int properties.setProperty(prefix+"curt_pix_decimate", this.curt_pix_decimate+""); // int
properties.setProperty(prefix+"curt_vel_decimate", this.curt_vel_decimate+""); // int properties.setProperty(prefix+"curt_vel_decimate", this.curt_vel_decimate+""); // int
properties.setProperty(prefix+"curt_vel_radius", this.curt_vel_radius+""); // int properties.setProperty(prefix+"curt_vel_radius", this.curt_vel_radius+""); // int
...@@ -7463,16 +7507,24 @@ min_str_neib_fpn 0.35 ...@@ -7463,16 +7507,24 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_rng_limit")!=null) this.cuas_rng_limit=Double.parseDouble(properties.getProperty(prefix+"cuas_rng_limit")); if (properties.getProperty(prefix+"cuas_rng_limit")!=null) this.cuas_rng_limit=Double.parseDouble(properties.getProperty(prefix+"cuas_rng_limit"));
if (properties.getProperty(prefix+"curt_en")!=null) this.curt_en=Boolean.parseBoolean(properties.getProperty(prefix+"curt_en")); if (properties.getProperty(prefix+"curt_en")!=null) this.curt_en=Boolean.parseBoolean(properties.getProperty(prefix+"curt_en"));
if (properties.getProperty(prefix+"curt_pyramid")!=null) this.curt_pyramid=Integer.parseInt(properties.getProperty(prefix+"curt_pyramid"));
if (properties.getProperty(prefix+"curt_psf_radius")!=null) this.curt_psf_radius=Double.parseDouble(properties.getProperty(prefix+"curt_psf_radius")); if (properties.getProperty(prefix+"curt_psf_radius")!=null) this.curt_psf_radius=Double.parseDouble(properties.getProperty(prefix+"curt_psf_radius"));
if (properties.getProperty(prefix+"curt_n_sigma")!=null) this.curt_n_sigma=Double.parseDouble(properties.getProperty(prefix+"curt_n_sigma")); if (properties.getProperty(prefix+"curt_n_sigma")!=null) this.curt_n_sigma=Double.parseDouble(properties.getProperty(prefix+"curt_n_sigma"));
if (properties.getProperty(prefix+"curt_rleak0")!=null) this.curt_rleak0=Double.parseDouble(properties.getProperty(prefix+"curt_rleak0")); if (properties.getProperty(prefix+"curt_rleak0")!=null) this.curt_rleak0=Double.parseDouble(properties.getProperty(prefix+"curt_rleak0"));
if (properties.getProperty(prefix+"curt_pyramid")!=null) this.curt_pyramid=Integer.parseInt(properties.getProperty(prefix+"curt_pyramid"));
if (properties.getProperty(prefix+"curt_rleak_pyr")!=null) this.curt_rleak_pyr=Double.parseDouble(properties.getProperty(prefix+"curt_rleak_pyr"));
if (properties.getProperty(prefix+"curt_3d3_mode")!=null) this.curt_3d3_mode=Integer.parseInt(properties.getProperty(prefix+"curt_3d3_mode"));
if (properties.getProperty(prefix+"curt_3d3_frac")!=null) this.curt_3d3_frac=Double.parseDouble(properties.getProperty(prefix+"curt_3d3_frac"));
if (properties.getProperty(prefix+"curt_3d3_thrsh")!=null) this.curt_3d3_thrsh=Double.parseDouble(properties.getProperty(prefix+"curt_3d3_thrsh"));
if (properties.getProperty(prefix+"curt_3d3_power")!=null) this.curt_3d3_power=Double.parseDouble(properties.getProperty(prefix+"curt_3d3_power"));
if (properties.getProperty(prefix+"curt_3d3_wnow")!=null) this.curt_3d3_wnow=Double.parseDouble(properties.getProperty(prefix+"curt_3d3_wnow")); if (properties.getProperty(prefix+"curt_3d3_wnow")!=null) this.curt_3d3_wnow=Double.parseDouble(properties.getProperty(prefix+"curt_3d3_wnow"));
if (properties.getProperty(prefix+"curt_3d3_wprev")!=null) this.curt_3d3_wprev=Double.parseDouble(properties.getProperty(prefix+"curt_3d3_wprev")); if (properties.getProperty(prefix+"curt_3d3_wprev")!=null) this.curt_3d3_wprev=Double.parseDouble(properties.getProperty(prefix+"curt_3d3_wprev"));
if (properties.getProperty(prefix+"curt_rleak1")!=null) this.curt_rleak1=Double.parseDouble(properties.getProperty(prefix+"curt_rleak1")); if (properties.getProperty(prefix+"curt_rleak1")!=null) this.curt_rleak1=Double.parseDouble(properties.getProperty(prefix+"curt_rleak1"));
if (properties.getProperty(prefix+"curt_pix_decimate")!=null) this.curt_pix_decimate=Integer.parseInt(properties.getProperty(prefix+"curt_pix_decimate")); if (properties.getProperty(prefix+"curt_pix_decimate")!=null) this.curt_pix_decimate=Integer.parseInt(properties.getProperty(prefix+"curt_pix_decimate"));
if (properties.getProperty(prefix+"curt_vel_decimate")!=null) this.curt_vel_decimate=Integer.parseInt(properties.getProperty(prefix+"curt_vel_decimate")); if (properties.getProperty(prefix+"curt_vel_decimate")!=null) this.curt_vel_decimate=Integer.parseInt(properties.getProperty(prefix+"curt_vel_decimate"));
if (properties.getProperty(prefix+"curt_vel_radius")!=null) this.curt_vel_radius=Integer.parseInt(properties.getProperty(prefix+"curt_vel_radius")); if (properties.getProperty(prefix+"curt_vel_radius")!=null) this.curt_vel_radius=Integer.parseInt(properties.getProperty(prefix+"curt_vel_radius"));
...@@ -8743,13 +8795,21 @@ min_str_neib_fpn 0.35 ...@@ -8743,13 +8795,21 @@ min_str_neib_fpn 0.35
imp.cuas_rng_limit = this.cuas_rng_limit; imp.cuas_rng_limit = this.cuas_rng_limit;
imp.curt_en = this.curt_en; imp.curt_en = this.curt_en;
imp.curt_pyramid = this.curt_pyramid;
imp.curt_psf_radius = this.curt_psf_radius; imp.curt_psf_radius = this.curt_psf_radius;
imp.curt_n_sigma = this.curt_n_sigma; imp.curt_n_sigma = this.curt_n_sigma;
imp.curt_rleak0 = this.curt_rleak0; imp.curt_rleak0 = this.curt_rleak0;
imp.curt_pyramid = this.curt_pyramid;
imp.curt_rleak_pyr = this.curt_rleak_pyr;
imp.curt_3d3_mode = this.curt_3d3_mode;
imp.curt_3d3_frac = this.curt_3d3_frac;
imp.curt_3d3_thrsh = this.curt_3d3_thrsh;
imp.curt_3d3_power = this.curt_3d3_power;
imp.curt_3d3_wnow = this.curt_3d3_wnow; imp.curt_3d3_wnow = this.curt_3d3_wnow;
imp.curt_3d3_wprev = this.curt_3d3_wprev; imp.curt_3d3_wprev = this.curt_3d3_wprev;
imp.curt_rleak1 = this.curt_rleak1; imp.curt_rleak1 = this.curt_rleak1;
imp.curt_pix_decimate = this.curt_pix_decimate; imp.curt_pix_decimate = this.curt_pix_decimate;
imp.curt_vel_decimate = this.curt_vel_decimate; imp.curt_vel_decimate = this.curt_vel_decimate;
imp.curt_vel_radius = this.curt_vel_radius; imp.curt_vel_radius = this.curt_vel_radius;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment