Commit 4a5fabd6 authored by Andrey Filippov's avatar Andrey Filippov

Improving FPN removal

parent 33bb38e2
......@@ -19,7 +19,7 @@ public class PolynomialApproximation {
double [] SF=new double [N+1];
for (int i=0;i<=2*N;i++) S[i]=0.0;
for (int i=0;i<=N;i++) SF[i]=0.0;
for (int i=0;i<data.length;i++){
for (int i=0;i<data.length;i++) if (data[i] != null){
double wxn=(data[i].length>2)?data[i][2]:1.0;
if (wxn>0.0){ // save time on 0.0 that can be used to mask out some samples
double f=data[i][1];
......
......@@ -697,16 +697,20 @@ public class Cuas {
final int num_colors = refCLT.getNumColors();
final int tilesX = refCLT.getTilesX();
final int tilesY = refCLT.getTilesY();
final double[][] tile_diffs = (debug_pxpyd && (cuasData != null)) ? new double [quadCLTs.length][tilesX*tilesY]:null;
// final double[][] tile_diffs = (debug_pxpyd && (cuasData != null)) ? new double [quadCLTs.length][tilesX*tilesY]:null;
final double[][] tile_diffs = (debug_pxpyd ) ? new double [quadCLTs.length][tilesX*tilesY]:null;
if (tile_diffs != null) {
for (int i = 0; i < tile_diffs.length; i++) {
Arrays.fill(tile_diffs[i], Double.NaN);
}
}
final double [][] dnum_vars = (debug_pxpyd && (cuasData != null)) ? new double [quadCLTs.length][tilesX*tilesY]:null;
// final double [][] dnum_vars = (debug_pxpyd && (cuasData != null)) ? new double [quadCLTs.length][tilesX*tilesY]:null;
final double [][] dnum_vars = (debug_pxpyd ) ? new double [quadCLTs.length][tilesX*tilesY]:null;
double [][][] dbg_PxPyD = debug_pxpyd? (new double [dbg_slices][quadCLTs.length][]):null;
double [][][] dbg_PxPyD_slice = debug_pxpyd? (new double [1][][]):null;
final float [][] dbg_fclt = debug_pxpyd ? new float [quadCLTs.length][] : null;
int dbg_scene = -95;
if (ref_pXpYD == null) {
ref_pXpYD = OpticalFlow.transformToScenePxPyD( // now should work with offset ref_scene
......@@ -733,7 +737,6 @@ public class Cuas {
}
}
double [] stereo_atr = (stereo_atr_in != null)? stereo_atr_in: OpticalFlow.ZERO3; // maybe later play with rotated camera
boolean mode_cuas = (stereo_atr[0] != 0) || (stereo_atr[1] != 0) || (stereo_atr[2] != 0);
double [][] ref_pXpYD_or_null = null; // mode_cuas ? ref_pXpYD : null; // debugging cuas mode keeping old
......@@ -758,7 +761,7 @@ public class Cuas {
num_colors, // int num_colors,
tilesX, // int width, // should be multiple of width
tilesY); // int height) {
boolean show_src = false; // cuas_debug;
final Thread[] threads = ImageDtt.newThreadArray(ImageDtt.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int nscene = 0; nscene < quadCLTs.length ; nscene++) if (quadCLTs[nscene] != null){
......@@ -766,6 +769,23 @@ public class Cuas {
if (nscene== dbg_scene) {
System.out.println("renderSceneSequence(): nscene = "+nscene);
}
if (show_src) {
int tile_size = refCLT.getTileSize();
String title = quadCLTs[nscene].getImageName()+"-SRC";
double [][] dbg_data = new double [quadCLTs[nscene].getImageData().length][];
String [] titles = new String [dbg_data.length];
for (int i = 0; i < dbg_data.length; i++) {
titles[i] = "SENSOR-"+i;
dbg_data[i] = quadCLTs[nscene].getImageData()[i][0];
}
ShowDoubleFloatArrays.showArrays(
dbg_data,
tilesX * tile_size,
tilesY * tile_size,
true,
title,
titles);
}
String ts = quadCLTs[nscene].getImageName();
final double dts = quadCLTs[nscene].getTimeStamp();
double [] scene_xyz = OpticalFlow.ZERO3;
......@@ -873,6 +893,9 @@ public class Cuas {
}
}
final float [] ffclt = fclt[0];
if (dbg_fclt != null) {
dbg_fclt[nscene] = ffclt;
}
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
......@@ -984,6 +1007,35 @@ public class Cuas {
}
ImageDtt.startAndJoin(threads);
*/
if (dbg_fclt != null) {
double [][] dbg_data = new double [quadCLTs.length][];
int tile_size = refCLT.getTileSize();
String suffix ="-DBG_FCLT_SEQ";
String [] titles = new String [quadCLTs.length];
String title = refCLT.getImageName() + suffix;
for (int nscene = 0; nscene < titles.length; nscene++) {
titles[nscene] = quadCLTs[nscene].getImageName();
dbg_data[nscene] = refCLT. convertCenterClt(
new float[][] {dbg_fclt[nscene]})[0];//float [][] fclt)
}
ImagePlus imp = ShowDoubleFloatArrays.makeArrays(
dbg_data, // double[][] pixels,
tilesX*tile_size,// int width,
tilesY*tile_size,// int height,
title, // String title,
titles); // String [] titles)
if (imp != null) {
if (!batch_run) {
imp.show();
}
refCLT.saveImagePlusInModelDirectory(
suffix, // String suffix, // null - use title from the imp
imp); // ImagePlus imp)
}
}
if (dbg_PxPyD != null) {
String [] debug_frame_titles = {"pX","pY","Disparity"};
String [] debug_titles = new String[quadCLTs.length];
......@@ -1054,6 +1106,7 @@ public class Cuas {
imp); // ImagePlus imp)
}
}
return newCuasData; // new float [][][] {sumFclt,sum_weights};
}
......
......@@ -1274,13 +1274,24 @@ public class GpuQuad{ // quad camera description
* Copy a set of images to the GPU (if they are new)
* @param force set even if there is no new Bayer data available
*/
public void setBayerImages(
boolean force) {
setBayerImages(
force, // boolean force,
false); // boolean center)
}
public void setBayerImages(
boolean force,
boolean center) {
if (!force && this.gpuTileProcessor.bayer_set && !quadCLT.hasNewImageData()) {
return;
}
double [][] bayer_center = quadCLT.getImageCenter();
if (bayer_center != null) {
// if (bayer_center != null) {
if (center) {
quadCLT.getResetImageCenter();
setBayerImage(
bayer_center,
......@@ -1909,6 +1920,7 @@ public class GpuQuad{ // quad camera description
}
}
/**
* Direct CLT conversion and aberration correction
* Convert and save TD representation in either normal or reference scene. Reference scene TD representation
......@@ -1922,6 +1934,31 @@ public class GpuQuad{ // quad camera description
boolean ref_scene,
int [] wh,
int erase_clt) {
execConvertDirect(
ref_scene, // boolean ref_scene,
wh, // int [] wh,
erase_clt, // int erase_clt,
false, // boolean no_kernels)
false); // boolean use_center_image)
}
/**
* Direct CLT conversion and aberration correction
* Convert and save TD representation in either normal or reference scene. Reference scene TD representation
* is used for interscene correlation (for "IMU")
* @param ref_scene save result into a separate buffer for interscene correlation when true.
* @param wh window width, height (or null)
* @param erase_clt erase CLT data. Only needed before execImcltRbgAll() if not all the
* tiles are converted. <0 - do not erase, 0 - erase to 0, 1 - erase to NaN
* @param no_kernels skip deconvolution
* @param use_center_image use a single center image for all sensor (back propagation mode)
*/
public void execConvertDirect(
boolean ref_scene,
int [] wh,
int erase_clt,
boolean no_kernels,
boolean use_center_image) {
if (this.gpuTileProcessor.GPU_CONVERT_DIRECT_kernel == null)
{
IJ.showMessage("Error", "No GPU kernel: GPU_CONVERT_DIRECT_kernel");
......@@ -1932,14 +1969,18 @@ public class GpuQuad{ // quad camera description
IJ.showMessage("Error", "No GPU kernel: GPU_ERASE_CLT_TILES_kernel");
return;
}
boolean skip_kernels = rectilinear || (quadCLT == null) || no_kernels;
if (!rectilinear) {
// if ((quadCLT == null) || (quadCLT.getImageCenter() != null)) { // ????????????????
if ((quadCLT != null) && (quadCLT.getImageCenter() == null)) {
// if ((quadCLT != null) && (quadCLT.getImageCenter() == null)) {
if (!skip_kernels) {
setConvolutionKernels(false); // set kernels if they are not set already
}
setBayerImages(false); // set Bayer images if this.quadCLT instance has new ones
setBayerImages( // set Bayer images if this.quadCLT instance has new ones
false, // boolean force,
use_center_image); // boolean center)
}
boolean skip_kernels = rectilinear || (quadCLT == null) || (quadCLT.getImageCenter() != null) || !this.gpuTileProcessor.kernels_set || (quadCLT.no_kernels);
// boolean skip_kernels = rectilinear || (quadCLT == null) || (quadCLT.getImageCenter() != null) || !this.gpuTileProcessor.kernels_set || (quadCLT.no_kernels);
int [] wh1 = handleWH(
wh, // int [] wh_in,
......@@ -1976,31 +2017,6 @@ public class GpuQuad{ // quad camera description
}
}
Pointer kernelParameters;
// boolean rectilinear_or_back = rectilinear || (quadCLT == null) || (quadCLT.getImageCenter() != null);
/* if (rectilinear) {
kernelParameters = Pointer.to(
Pointer.to(new int[] { num_cams}), // int num_cams,
Pointer.to(new int[] { num_colors}), // int num_colors,
Pointer.to(gpu_bayer), // gpu_kernel_offsets), // just a legal pointer to gpu memory, will not be used
Pointer.to(gpu_bayer), // gpu_kernels), // just a legal pointer to gpu memory, will not be used
Pointer.to(gpu_bayer),
Pointer.to(gpu_ftasks),
Pointer.to(gpu_clt_selected), // gpu_clt), // select which one
Pointer.to(new int[] { mclt_stride }), // should be input image stride (in floats), not mclt!
Pointer.to(new int[] { num_task_tiles }),
// move lpf to 4-image generator kernel - DONE
Pointer.to(new int[] { 0 }), // lpf_mask
Pointer.to(new int[] { wh[0]}), // img_width}), // int woi_width,
Pointer.to(new int[] { wh[1]}), // img_height}), // int woi_height,
Pointer.to(new int[] { 0}), // int kernels_hor,
Pointer.to(new int[] { 0}), // int kernels_vert);
Pointer.to(gpu_active_tiles),
Pointer.to(gpu_num_active_tiles),
Pointer.to(new int[] { tilesX })
);
} else {// !rectilinear (normal way)
*/
kernelParameters = Pointer.to(
Pointer.to(new int[] { num_cams}), // int num_cams,
Pointer.to(new int[] { num_colors}), // int num_colors,
......
......@@ -1447,6 +1447,14 @@ public class ImageDtt extends ImageDttCPU {
int erase_clt) {
gpuQuad.execConvertDirect(use_reference_buffer, wh, erase_clt); // put results into a "reference" buffer
}
public void execConvertDirect(
boolean use_reference_buffer,
int [] wh,
int erase_clt,
boolean no_kernels,
boolean use_center_image){
gpuQuad.execConvertDirect(use_reference_buffer, wh, erase_clt, no_kernels, use_center_image); // put results into a "reference" buffer
}
public void preSetReferenceTD( // do not run execConvertDirect, exit after updating tasks
final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
......
......@@ -674,7 +674,7 @@ min_str_neib_fpn 0.35
public double cuas_max_abs_rowcol = 100.0; // consider pixels with abs(UM difference) does not exceed this value
public double cuas_outliers_rowcol = 0.001; // scale weight of the outliers with high difference (to prevent undefined values
public boolean cuas_reset_first= false; // Reset average in first scene (for large diffirence in unfinished row/col)
public int cuas_invert_margins = 1; // Expand image each side when inverting tasks
public int cuas_invert_margins = 0; // Expand image each side when inverting tasks
public int cuas_invert_iters = 4; // Enhance inversion iterations
public double cuas_invert_tolerance = 0.001; // Finish enhancing when last change was lower than
public int cuas_invert_gap2 = 10; // Maximal dual gap size for inversion (depends on scanning radius in tiles) <0 = use maximal possible
......
......@@ -5186,11 +5186,11 @@ public class OpticalFlow {
}
}
} // while (blue_sky == null)
boolean early_try_back = true;
boolean early_try_back = false; // true;
if ((center_CLT != null) && center_CLT.hasCenterClt()) { // float [] fclt
int fpn_width = center_CLT.getTilesX() * center_CLT.getTileSize(); // see if center_CLT can be used
double [][][] fpn = null;
boolean condition_dsi = true;
boolean condition_dsi = false; // true;
boolean show_fpn = cuas_debug && !clt_parameters.batch_run; //
if (cuas_subtract_fpn) {
int discard_border = clt_parameters.imp.cuas_discard_border;
......@@ -5225,7 +5225,7 @@ public class OpticalFlow {
}
quadCLTs[scene_index].setImageCenter(center_CLT.getImageCenter());
if (early_try_back) {
double [][][] back_prop = CorrectionFPN.backPropagate_dbg(
double [][][] back_prop = CorrectionFPN.backPropagate(
clt_parameters, // CLTParameters clt_parameters,
discard_border, // final int discard_border,
max_fold, // final double max_fold,
......@@ -5241,6 +5241,8 @@ public class OpticalFlow {
}
}
fpn = center_CLT.getCorrectionFPN().readImageFPN ( -1); // int sens_mask);
boolean created_fpn = false;
double [][] fpn_weights = null;
if ((fpn == null) || cuas_calc_fpn) {
if (debugLevel >-3) {
System.out.println("Calculating FPN.");
......@@ -5248,13 +5250,74 @@ public class OpticalFlow {
int num_scenes = quadCLTs.length;
int rot_periods = (int) Math.floor(num_scenes/cuas_rot_period);
int rot_scenes = (int) Math.floor(rot_periods *cuas_rot_period);
int [] rot_range = {0, rot_scenes-1};
// Two full camera rotations to equalize contributions of different offsets
int [] rot_range = {0, rot_scenes-1}; // {0,174}; //{175,349}; // {0, 149}; // {0+140, rot_scenes-1+140};
/*
fpn = CorrectionFPN.calculateFPN(
quadCLTs, // final QuadCLT [] quadCLTs,
rot_range, // final int [] range, // required
-1, // final int sensor_mask,
debugLevel); // final int debugLevel)
*/
double [][][] fpn_and_weights = CorrectionFPN.backPropagate(
clt_parameters, // CLTParameters clt_parameters,
discard_border, // final int discard_border,
max_fold, // final double max_fold,
min_in_row_col, // final int min_in_row_col, // Minimal number of defined tiles in a row/column
cuas_invert_margins, // final int invert_margins, // 1 Expand image each side when inverting tasks
cuas_invert_gap2, // final int invert_gap2, // 10 // Maximal dual gap size for inversion (depends on scanning radius in tiles)
cuas_invert_iters, // final int invert_iters, // 4 Enhance inversion iterations
cuas_invert_tolerance, // final double invert_tolerance,// 0.001 Finish enhancing when last change was lower than
center_CLT, // final QuadCLT center_CLT,
quadCLTs, // final QuadCLT[] quadCLTs,
rot_range[0], // final int first_index,
rot_range[1], // final int last_index,
disparity_center, // double [] disparity_center
debugLevel); // final int debugLevel)
fpn = new double [fpn_and_weights[0].length][1][];
for (int nsens = 0; nsens < fpn.length; nsens++) {
fpn[nsens][0] = fpn_and_weights[0][nsens];
}
// remove later - here just to safe save.
center_CLT.getCorrectionFPN().saveShowFPN(
fpn,// double [][][] fpn,
fpn_width, // int width,
true, // boolean save,
show_fpn, // boolean show) {
QuadCLT.CENTER_FPN_SUFFIX+"-ORIG"); // String suffix)
double [][] image_row_avg = CorrectionFPN.getRowAvgMulti(
fpn, // final double [][][] image_data,
fpn_width, // final int width,
cuas_max_abs_rowcol, // final double max_abs, // only average within +/- max_abs
cuas_outliers_rowcol); // final double weight_outlier)
double [][] image_col_avg = CorrectionFPN.getColAvgMulti(
fpn, // final double [][][] image_data,
fpn_width, // final int width,
cuas_max_abs_rowcol, // final double max_abs, // only average within +/- max_abs
cuas_outliers_rowcol); // final double weight_outlier)
double [][][] fpn_out = CorrectionFPN.applyRowCol(
fpn, // final double [][][] image_data,
image_row_avg, // final double [][] image_row_avg,
image_col_avg, // final double [][] image_col_avg,
false); // final boolean inplace )
fpn = fpn_out;
center_CLT.getCorrectionFPN().saveShowFPN(
fpn,// double [][][] fpn,
fpn_width, // int width,
true, // boolean save,
show_fpn, // boolean show) {
QuadCLT.CENTER_FPN_SUFFIX+"-ROWCOL_RANGE"+rot_range[0]+"-"+rot_range[1]); // String suffix)
String fpn_weights_suffix="-FPN-WEIGHTS";
CorrectionFPN.saveShowFPNWeights(
fpn_and_weights, // double [][][] fpn_weights,
center_CLT, // QuadCLT center_CLT,
fpn_weights_suffix, // String suffix,
true, // boolean save,
show_fpn); // boolean show) {
created_fpn = true;
int dbg_sens = -12; // disable testing
if (cuas_debug && (dbg_sens >= 0)) {
center_CLT.getCorrectionFPN().debugFPN(
......@@ -5274,11 +5337,13 @@ public class OpticalFlow {
}
}
// center_CLT.setImageData(fpn); // included in center_CLT.setApplyFPN(). // setting FPN images to the virtual (center) scene
if (created_fpn || show_fpn) {
center_CLT.getCorrectionFPN().saveShowFPN(
fpn,// double [][][] fpn,
fpn_width, // int width,
true, // boolean save,
created_fpn, // boolean save,
show_fpn); // boolean show) {
}
center_CLT.getCorrectionFPN().setApplyFPN(
quadCLTs, // QuadCLT [] quadCLTs,
fpn);// double [][][] fpn)
......
......@@ -6315,6 +6315,7 @@ public class QuadCLTCPU {
if ((imp == null) || (imp.getTitle() == null) || (imp.getTitle().equals(""))) {
return null;
}
System.out.println ("Read "+(imp.getStack().getSize())+" slices from "+file_path);
return readFloatArray(
imp, // ImagePlus imp,
num_slices, //int num_slices, // (0 - all)
......
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