Commit 200f2455 authored by Andrey Filippov's avatar Andrey Filippov

Mixing noise - random and FPN for performance evaluation

parent 3ca96c86
......@@ -28,64 +28,95 @@ package com.elphel.imagej.cameras;
import java.util.Properties;
import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.tileprocessor.NoiseParameters;
public class InterNoiseParameters {
public double noise_sigma = 1.5;
public double noise_scale = 0.01;
public double initial_offset = 1.0;
public NoiseParameters noise = new NoiseParameters (0.1, 0.0, 1.5, 1.0, 16);
// public double noise_sigma = 1.5;
// public double noise_scale = 0.01;
// public double initial_offset = 1.0;
public boolean ref_only = false; // also see imgdtt_params.dbg_pair_mask to switch between all pairs (63) and binocular only (1)
public boolean show_final_2d = true; // show 2d correlations during last interation step
public int noise_debug_level = -1; // Noise testing debug level
public void dialogQuestions(GenericJTabbedDialog gd) {
gd.addMessage("Additive noise parameters");
gd.addMessage("LMA other parameters");
gd.addNumericField("Noise Gaussian sigma", this.noise_sigma, 3,5,"pix",
gd.addNumericField("Noise Gaussian sigma", this.noise.sigma, 3,5,"pix",
"Blur noise with 2D Gaussian");
gd.addNumericField("Scale noise", this.noise_scale, 6,8,"",
gd.addNumericField("Scale noise random (each scene indepemdent)", this.noise.scale_random, 6,8,"",
"Scale noise relative to the average value of the color component");
gd.addNumericField("Scale noise FPN (same for each scene)", this.noise.scale_fpn, 6,8,"",
"Scale noise relative to the average value of the color component.");
gd.addNumericField("Offset target disparity", this.initial_offset, 3,5,"pix",
gd.addNumericField("Offset target disparity", this.noise.initial_offset, 3,5,"pix",
"Offset target disparity before attempting to correlate and refine.");
gd.addNumericField("Subset number of sensors (2/4/8/16)", this.noise.used_sensors, 0,3,"",
"Performance comparison - use only some of 16 sensors");
gd.addCheckbox ("Reference scene only", this.ref_only,
"Process only reference scene (intra-scene, no inter-scene accumulation).");
gd.addNumericField("Debug level", this.noise_debug_level, 0,3,"",
gd.addCheckbox ("Show 2d correlations for the last iteration", this.show_final_2d,
"Show single-scene and interframe 2d correlations for the last iteration");
gd.addNumericField("Debug level", this.noise_debug_level, 0,3,"",
"Debug level of interscene noise testing.");
}
public void dialogAnswers(GenericJTabbedDialog gd) {
this.noise_sigma = gd.getNextNumber();
this.noise_scale = gd.getNextNumber();
this.initial_offset = gd.getNextNumber();
this.noise.sigma = gd.getNextNumber();
this.noise.scale_random = gd.getNextNumber();
this.noise.scale_fpn = gd.getNextNumber();
this.noise.initial_offset = gd.getNextNumber();
this.noise.used_sensors = (int) gd.getNextNumber();
this.ref_only = gd.getNextBoolean();
this.show_final_2d = gd.getNextBoolean();
this.noise_debug_level = (int) gd.getNextNumber();
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"noise_sigma", this.noise_sigma+"");
properties.setProperty(prefix+"noise_scale", this.noise_scale+"");
properties.setProperty(prefix+"initial_offset", this.initial_offset+"");
properties.setProperty(prefix+"ref_only", this.ref_only+"");
properties.setProperty(prefix+"noise_debug_level", this.noise_debug_level+"");
properties.setProperty(prefix+"noise.sigma", this.noise.sigma+"");
properties.setProperty(prefix+"noise.scale_random", this.noise.scale_random+"");
properties.setProperty(prefix+"noise.scale_fpn", this.noise.scale_fpn+"");
properties.setProperty(prefix+"noise.initial_offset", this.noise.initial_offset+"");
properties.setProperty(prefix+"noise.used_sensors", this.noise.used_sensors+"");
properties.setProperty(prefix+"ref_only", this.ref_only+"");
properties.setProperty(prefix+"show_final_2d", this.show_final_2d+"");
properties.setProperty(prefix+"noise_debug_level", this.noise_debug_level+"");
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"noise_sigma")!=null) this.noise_sigma=Double.parseDouble(properties.getProperty(prefix+"noise_sigma"));
if (properties.getProperty(prefix+"noise_scale")!=null) this.noise_scale=Double.parseDouble(properties.getProperty(prefix+"noise_scale"));
if (properties.getProperty(prefix+"initial_offset")!=null) this.initial_offset=Double.parseDouble(properties.getProperty(prefix+"initial_offset"));
if (properties.getProperty(prefix+"noise.sigma")!=null) {
this.noise.sigma=Double.parseDouble(properties.getProperty(prefix+"noise.sigma"));
} else if (properties.getProperty(prefix+"noise_sigma")!=null) { // old format
this.noise.sigma=Double.parseDouble(properties.getProperty(prefix+"noise_sigma"));
}
if (properties.getProperty(prefix+"noise.scale_random")!=null) {
this.noise.scale_random=Double.parseDouble(properties.getProperty(prefix+"noise.scale_random"));
} else if (properties.getProperty(prefix+"noise_scale")!=null) {
this.noise.scale_random=Double.parseDouble(properties.getProperty(prefix+"noise_scale"));
}
if (properties.getProperty(prefix+"noise.scale_fpn")!=null) this.noise.scale_fpn=Double.parseDouble(properties.getProperty(prefix+"noise.scale_fpn"));
if (properties.getProperty(prefix+"noise.initial_offset")!=null) {
this.noise.initial_offset=Double.parseDouble(properties.getProperty(prefix+"noise.initial_offset"));
} else if (properties.getProperty(prefix+"initial_offset")!=null) {
this.noise.initial_offset=Double.parseDouble(properties.getProperty(prefix+"initial_offset"));
}
if (properties.getProperty(prefix+"noise.used_sensors")!=null) this.noise.used_sensors=Integer.parseInt(properties.getProperty(prefix+"noise.used_sensors"));
if (properties.getProperty(prefix+"ref_only")!=null) this.ref_only=Boolean.parseBoolean(properties.getProperty(prefix+"ref_only"));
if (properties.getProperty(prefix+"show_final_2d")!=null) this.show_final_2d=Boolean.parseBoolean(properties.getProperty(prefix+"show_final_2d"));
if (properties.getProperty(prefix+"noise_debug_level")!=null) this.noise_debug_level=Integer.parseInt(properties.getProperty(prefix+"noise_debug_level"));
}
@Override
public InterNoiseParameters clone() throws CloneNotSupportedException {
InterNoiseParameters inp = new InterNoiseParameters();
inp.noise_sigma = this.noise_sigma;
inp.noise_scale = this.noise_scale;
inp.initial_offset = this.initial_offset;
InterNoiseParameters inp = new InterNoiseParameters();
inp.noise = this.noise.clone();
inp.ref_only = this.ref_only;
inp.show_final_2d = this.show_final_2d;
inp.noise_debug_level = this.noise_debug_level;
return inp;
}
}
package com.elphel.imagej.tileprocessor;
import com.elphel.imagej.cameras.InterNoiseParameters;
public class NoiseParameters {
public double scale_random = 0.1;
public double scale_fpn = 0.0;
public double sigma = 1.5;
public double initial_offset = 1.0;
public int used_sensors = 16; // 2/4/8/16
public NoiseParameters (
double scale_random,
double scale_fpn,
double sigma,
double initial_offset,
int used_sensors) {
this.scale_random = scale_random;
this.scale_fpn = scale_fpn;
this.sigma = sigma;
this.initial_offset= initial_offset;
this.used_sensors = used_sensors;
}
@Override
public NoiseParameters clone() throws CloneNotSupportedException {
return new NoiseParameters(
scale_random,
scale_fpn,
sigma,
initial_offset,
used_sensors);
}
}
......@@ -228,7 +228,8 @@ public class QuadCLTCPU {
String set_name,
CLTParameters clt_parameters,
ColorProcParameters colorProcParameters,
double [] noise_sigma_level,
NoiseParameters noise_sigma_level,
QuadCLTCPU ref_scene, // may be null if scale_fpn <= 0
int threadsMax,
int debugLevel)
{
......@@ -238,6 +239,7 @@ public class QuadCLTCPU {
clt_parameters,
colorProcParameters,
noise_sigma_level, // double [] noise_sigma_level,
ref_scene, // QuadCLTCPU ref_scene, // may be null if scale_fpn <= 0
threadsMax,
debugLevel);
......@@ -282,7 +284,8 @@ public class QuadCLTCPU {
quadCLT.restoreFromModel(
clt_parameters,
colorProcParameters,
null, // double [] noise_sigma_level,
null, // double [] noise_sigma_level,
null, // final QuadCLTCPU ref_scene, // may be null if scale_fpn <= 0
threadsMax,
debugLevel);
......@@ -614,7 +617,9 @@ public class QuadCLTCPU {
public QuadCLTCPU restoreFromModel(
CLTParameters clt_parameters,
ColorProcParameters colorProcParameters,
double [] noise_sigma_level,
// double []
NoiseParameters noise_sigma_level,
QuadCLTCPU ref_scene, // may be null if scale_fpn <= 0
int threadsMax,
int debugLevel)
......@@ -654,6 +659,7 @@ public class QuadCLTCPU {
if (noise_sigma_level != null) {
generateAddNoise(
"-NOISE",
ref_scene, // final QuadCLTCPU ref_scene, // may be null if scale_fpn <= 0
noise_sigma_level,
threadsMax,
1); // debugLevel); // final int debug_level)
......@@ -686,12 +692,110 @@ public class QuadCLTCPU {
public void generateAddNoise(
final String suffix,
final double [] noise_sigma_level,
final QuadCLTCPU ref_scene, // may be null if scale_fpn <= 0
// final double []
final NoiseParameters noise_sigma_level,
final int threadsMax,
final int debug_level)
{
final double scale_random = noise_sigma_level.scale_random; // _sigma_level[0];
final double scale_fpn = noise_sigma_level.scale_fpn; // noise_sigma_level[0];
final double sigma = noise_sigma_level.sigma; // [1];
ImagePlus imp = generateAddNoise(
suffix, // final String suffix,
sigma, // final double sigma,
threadsMax, // final int threadsMax,
debug_level); // final int debug_level) : null;
ImagePlus imp_ref = null;
if (scale_fpn >0){
if (ref_scene !=null) {
imp_ref= ref_scene.generateAddNoise(
suffix, // final String suffix,
sigma, // final double sigma,
threadsMax, // final int threadsMax,
debug_level); // final int debug_level) : null;
} else {
imp_ref= imp; // when calculating ref_scene itself it is provided as null
}
}
final int num_cams = this.image_data.length;
final int num_cols = image_data[0].length;
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
ImageStack imageStack = imp.getStack();
final float [][] fpixels = new float [num_cams][];
for (int q = 0; q < num_cams; q++) {
fpixels[q] = (float[]) imageStack.getPixels(q+1);
}
final float [][] fpixels_ref = (imp_ref != null) ? (new float [num_cams][]): null;
if (imp_ref != null) {
ImageStack imageStack_ref = imp_ref.getStack();
for (int q = 0; q < num_cams; q++) {
fpixels_ref[q] = (float[]) imageStack_ref.getPixels(q+1);
}
}
for (int q = 0; q < num_cams; q++) {
final int fq = q;
for (int c =0; c < num_cols; c++) {
final int fc = c;
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int i = ai.getAndIncrement(); i < image_data[fq][fc].length; i = ai.getAndIncrement()) {
if (image_data[fq][fc][i] != 0.0) {
image_data[fq][fc][i] += scale_random * fpixels[fq][i];
if (fpixels_ref != null) {
image_data[fq][fc][i] += scale_fpn * fpixels_ref[fq][i];
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
}
if (debug_level > 100) {
double [][] dbg_data = new double [num_cams*num_cols][];
for (int q = 0; q < num_cams;q++) {
for (int c = 0; c < num_cols; c++) {
dbg_data[q*num_cols+c] = image_data[q][c];
}
}
int [] image_wh = geometryCorrection.getSensorWH();
String noise_suffix = suffix + sigma;
saveDoubleArrayInModelDirectory(
noise_suffix + "-MIXED-RND"+scale_random+"-FPN"+scale_fpn, // noise_sigma_level[0], // String suffix,
null, // String [] labels, // or null
dbg_data, // double [][] data,
image_wh[0], // int width,
image_wh[1]); // int height)
}
}
// May need to run twice - for both refscene and this one if fpn >=0
/**
* Load existing noise image, generate if it did no exist
* @param suffix file name suffix (sigma will be added)
* @param sigma blur sigma (in pixels), the amount of added noise will be used by caller, noise image only depends on sigma
* @param threadsMax
* @param debug_level
* @return Noise image, one slice per sensor (Bayer mosaic still use 1 slice per sensor)
*/
public ImagePlus generateAddNoise(
final String suffix,
final double sigma,
final int threadsMax,
final int debug_level)
{
final double scale =noise_sigma_level[0];
final double sigma =noise_sigma_level[1];
final int num_cams = this.image_data.length;
final int num_cols = image_data[0].length;
final int [] image_wh = geometryCorrection.getSensorWH();
......@@ -815,45 +919,12 @@ public class QuadCLTCPU {
image_wh[0], // int width,
image_wh[1]); // int height)
}
ImageStack imageStack = imp.getStack();
float [][] fpixels = new float [num_cams][];
for (int q = 0; q < num_cams; q++) {
fpixels[q] = (float[]) imageStack.getPixels(q+1);
}
for (int q = 0; q < num_cams; q++) {
final int fq = q;
for (int c =0; c < num_cols; c++) {
final int fc = c;
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int i = ai.getAndIncrement(); i < image_data[fq][fc].length; i = ai.getAndIncrement()) {
if (image_data[fq][fc][i] != 0.0) {
image_data[fq][fc][i] += scale * fpixels[fq][i];
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
}
if (debug_level > 100) {
double [][] dbg_data = new double [num_cams*num_cols][];
for (int q = 0; q < num_cams;q++) {
for (int c = 0; c < num_cols; c++) {
dbg_data[q*num_cols+c] = image_data[q][c];
}
}
saveDoubleArrayInModelDirectory(
noise_suffix + "-MIXED"+noise_sigma_level[0], // String suffix,
null, // String [] labels, // or null
dbg_data, // double [][] data,
image_wh[0], // int width,
image_wh[1]); // int height)
}
}
return imp;
}
public ImagePlus saveDoubleArrayInModelDirectory(
......@@ -874,6 +945,7 @@ public class QuadCLTCPU {
ImagePlus imp = new ImagePlus( file_name, imageStack);
FileSaver fs=new FileSaver(imp);
fs.saveAsTiff(file_path);
System.out.println("saveDoubleArrayInModelDirectory(): saved "+file_path);
return imp;
}
......
......@@ -8619,6 +8619,7 @@ if (debugLevel > -100) return true; // temporarily !
clt_parameters,
colorProcParameters, //
null, // noise_sigma_level, // double [] noise_sigma_level,
null, // final QuadCLTCPU ref_scene, // may be null if scale_fpn <= 0
threadsMax,
debugLevel);
// temporarily fix wrong sign:
......@@ -8664,12 +8665,16 @@ if (debugLevel > -100) return true; // temporarily !
// double [] noise_sigma_level = {1.0, 1.5, 1.0}; // amount, sigma, offset
// double [] noise_sigma_level = {3.0, 1.5, 1.0}; // amount, sigma, offset
// double [] noise_sigma_level = {5.0, 1.5, 1.0}; // amount, sigma, offset
double [] noise_sigma_level = null;
if (clt_parameters.inp.noise_scale > 0.0) {
noise_sigma_level = new double[] {
// double [] noise_sigma_level = null;
NoiseParameters noise_sigma_level = null;
if ((clt_parameters.inp.noise.scale_random > 0.0) || (clt_parameters.inp.noise.scale_fpn > 0.0)){
noise_sigma_level = clt_parameters.inp.noise.clone();
/*
new double[] {
clt_parameters.inp.noise_scale,
clt_parameters.inp.noise_sigma,
clt_parameters.inp.initial_offset}; // amount, sigma, offset
*/
}
boolean ref_only = clt_parameters.inp.ref_only; // true; // process only reference frame (false - inter-scene)
......@@ -8692,6 +8697,7 @@ if (debugLevel > -100) return true; // temporarily !
clt_parameters,
colorProcParameters, //
noise_sigma_level, // double [] noise_sigma_level,
null, // QuadCLTCPU ref_scene, // may be null if scale_fpn <= 0
threadsMax,
clt_parameters.inp.noise_debug_level); // debugLevel);
/**/
......@@ -8722,12 +8728,16 @@ if (debugLevel > -100) return true; // temporarily !
// double [] noise_sigma_level = {1.0, 1.5, 1.0}; // amount, sigma, offset
// double [] noise_sigma_level = {3.0, 1.5, 1.0}; // amount, sigma, offset
// double [] noise_sigma_level = {5.0, 1.5, 1.0}; // amount, sigma, offset
double [] noise_sigma_level = null;
if (clt_parameters.inp.noise_scale >= 0.0) {// <0 - will generate no-noise data
noise_sigma_level = new double[] {
// double [] noise_sigma_level = null;
NoiseParameters noise_sigma_level = null;
if ((clt_parameters.inp.noise.scale_random >= 0.0) || (clt_parameters.inp.noise.scale_fpn >= 0.0)) {// <0 - will generate no-noise data
noise_sigma_level = clt_parameters.inp.noise.clone();
/*
noise_sigma_level = new double[] {
clt_parameters.inp.noise_scale,
clt_parameters.inp.noise_sigma,
clt_parameters.inp.initial_offset}; // amount, sigma, offset
clt_parameters.inp.initial_offset}; // amount, sigma, offset\
*/
}
boolean ref_only = clt_parameters.inp.ref_only; // true; // process only reference frame (false - inter-scene)
......@@ -8750,6 +8760,7 @@ if (debugLevel > -100) return true; // temporarily !
clt_parameters,
colorProcParameters, //
noise_sigma_level, // double [] noise_sigma_level,
null, // final QuadCLTCPU ref_scene, // may be null if scale_fpn <= 0
threadsMax,
clt_parameters.inp.noise_debug_level); // debugLevel);
/*
......@@ -8760,7 +8771,10 @@ if (debugLevel > -100) return true; // temporarily !
*/
// Create 4-slice image with noise from the current data
if (noise_sigma_level != null) {
String noisy_4slice_suffix = "-noise-level_"+ noise_sigma_level[0]+"-sigma_"+noise_sigma_level[1];
String noisy_4slice_suffix =
"-noise-random_"+ noise_sigma_level.scale_random+
"-noise-fpn_"+ noise_sigma_level.scale_fpn+
"-sigma_"+noise_sigma_level.sigma;
ref_quadCLT.genSave4sliceImage(
clt_parameters, // CLTParameters clt_parameters,
noisy_4slice_suffix, // String suffix,
......
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