Commit 54256ab9 authored by Andrey Filippov's avatar Andrey Filippov

Adding temperature to sky discrimination

parent 411af03f
...@@ -35,7 +35,8 @@ public class CLTPass3d{ ...@@ -35,7 +35,8 @@ public class CLTPass3d{
private double [][] disparity_sav; // saved disparity private double [][] disparity_sav; // saved disparity
private int [][] tile_op_sav; // saved tile_op private int [][] tile_op_sav; // saved tile_op
public double [][] disparity_map = null; // add 4 layers - worst difference for the port public double [][] disparity_map = null; // add 4 layers - worst difference for the port
public double [] second_max = null; public double [] second_max = null; // second maximal difference between channels
public double [] avg_val = null; // average pixel value for all channels (for cold sky)
public double [][] lazy_eye_data = null; public double [][] lazy_eye_data = null;
public int lma_cluster_size = -1; public int lma_cluster_size = -1;
public boolean [] lazy_eye_force_disparity = null; public boolean [] lazy_eye_force_disparity = null;
...@@ -325,6 +326,16 @@ public class CLTPass3d{ ...@@ -325,6 +326,16 @@ public class CLTPass3d{
for (int i = 0; i< these_diffs.length; i++) these_diffs[i] = disparity_map[ImageDtt.IMG_DIFF0_INDEX + i]; // IMG_DIFF0_INDEX does not depend on num sensors for (int i = 0; i< these_diffs.length; i++) these_diffs[i] = disparity_map[ImageDtt.IMG_DIFF0_INDEX + i]; // IMG_DIFF0_INDEX does not depend on num sensors
return these_diffs; return these_diffs;
} }
public double [][] getRBGs (){
if (disparity_map == null) return null;
int numcol = tileProcessor.isMonochrome()? 1: 3;
double [][] these_RBGs = new double[numcol*getNumSensors()][];
for (int i = 0; i< these_RBGs.length; i++) these_RBGs[i] = disparity_map[ImageDtt.getImgToneRGB(getNumSensors()) + i]; // IMG_DIFF0_INDEX does not depend on num sensors
return these_RBGs;
}
//getImgToneRGB()
public void resetCalc(){ // only needed if the same task was reused public void resetCalc(){ // only needed if the same task was reused
calc_disparity = null; calc_disparity = null;
...@@ -751,7 +762,6 @@ public class CLTPass3d{ ...@@ -751,7 +762,6 @@ public class CLTPass3d{
public void resetByDiff( public void resetByDiff(
double max_diff, double max_diff,
double mismatch_override) { double mismatch_override) {
setSecondMax();
if ((disparity_map == null) ||(disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX] == null)) { if ((disparity_map == null) ||(disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX] == null)) {
System.out.println("resetByDiff(): strength is null! (no tiles left)"); System.out.println("resetByDiff(): strength is null! (no tiles left)");
return; return;
...@@ -1161,6 +1171,62 @@ public class CLTPass3d{ ...@@ -1161,6 +1171,62 @@ public class CLTPass3d{
return this.second_max; return this.second_max;
} }
public void setAvgVal(double [] avg_val) { // setting "fake" for the non-measurement scan
this.avg_val = avg_val;
}
public void setAvgVal() {
this.avg_val = getLowResChn();
}
public double [] getAvgVal() {
if (this.avg_val == null) {
setAvgVal();
}
return this.avg_val;
}
public double [] getLowResChn ()
{
final int numcolors = tileProcessor.isMonochrome()?1:3;
final double [][] rbg = getRBGs();
if (rbg == null) return null;
for (int i = 0; i < rbg.length; i++) {
if (rbg[i] == null) return null;
}
final double [] col_weights = {0.25,0.25,0.5};
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int num_tiles = tilesX * tilesY;
final double [] lowres = new double [num_tiles];
final boolean [] measured = measuredTiles ();
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < num_tiles; nTile = ai.getAndIncrement()) {
double d = 0.0;
if (numcolors == 1) {
for (int i = 0; i < rbg.length; i++) {
d += rbg[i][nTile];
}
} else {
for (int i = 0; i < rbg.length; i++) {
int col= i%numcolors;
d += rbg[i][nTile]*col_weights[col];
}
}
lowres[nTile] = d/getNumSensors();
}
}
};
}
ImageDtt.startAndJoin(threads);
return lowres;
}
public double [] getSecondMaxDiff ( public double [] getSecondMaxDiff (
final boolean averaged) final boolean averaged)
{ {
...@@ -1222,6 +1288,9 @@ public class CLTPass3d{ ...@@ -1222,6 +1288,9 @@ public class CLTPass3d{
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
return second_max_averaged; return second_max_averaged;
} }
@Deprecated @Deprecated
public double [] getFOM( public double [] getFOM(
double w_adisp, double w_adisp,
......
...@@ -422,6 +422,7 @@ public class QuadCLTCPU { ...@@ -422,6 +422,7 @@ public class QuadCLTCPU {
* and so on. * and so on.
* *
* @param sky_seed minimal value of strength*spread to seed sky areas * @param sky_seed minimal value of strength*spread to seed sky areas
* @param disparity_seed maximal disparity to seed sky areas (not needed for expand)
* @param sky_lim maximal value of strength*spread over which sky area will * @param sky_lim maximal value of strength*spread over which sky area will
* be expanded * be expanded
* @param sky_shrink shrink initial sky area to eliminate small non-sky areas. * @param sky_shrink shrink initial sky area to eliminate small non-sky areas.
...@@ -431,31 +432,138 @@ public class QuadCLTCPU { ...@@ -431,31 +432,138 @@ public class QuadCLTCPU {
* @param spread 1d array of tile spreads (second maximal difference from * @param spread 1d array of tile spreads (second maximal difference from
* of per-sensor pixel values in a tile to their average * of per-sensor pixel values in a tile to their average
* in scanline order. * in scanline order.
* @param disparity 1d array of tile disparity in scanline order
* @param debugLevel debug level * @param debugLevel debug level
* @return boolean 1d array of the pixels belonging to the blue sky. * @return boolean 1d array of the pixels belonging to the blue sky.
*/ */
public static boolean [] getBlueSky ( public static boolean [] getBlueSky (
double sky_seed, // = 7.0; // start with product of strength by diff_second below this double sky_seed, // = 7.0; // start with product of strength by diff_second below this
double disparity_seed, // 2.0; // seed - disparity_lma limit
double sky_lim, // = 15.0; // then expand to product of strength by diff_second below this double sky_lim, // = 15.0; // then expand to product of strength by diff_second below this
int sky_shrink, // = 4; int sky_shrink, // = 4;
int sky_expand_extra, // = 100; // 1? int sky_expand_extra, // = 100; // 1?
int width, int width,
double [] strength, double [] strength,
double [] spread, double [] spread,
double [] disparity,
double [] avg_val,
int debugLevel) { int debugLevel) {
if ((strength == null) || (spread==null)) { if ((strength == null) || (spread==null)) {
return null; return null;
} }
double [] temp_scales = null;
double cold_scale = 0.2; // <=1.0. 1.0 - disables temperature dependence
double cold_frac = 0.005; // this and lower will scale fom by cold_scale
double hot_frac = 0.9; // this and above will scale fom by 1.0
double min_strength = 0.08;
int seed_rows = 5; // sky should appear in this top rows
int num_bins = 1000;
if (avg_val != null) {
double min_temp = Double.NaN, max_temp=Double.NaN, avg_temp = 0;
int num_def = 0;
for (int i = 0; i < avg_val.length; i++) {
double d = avg_val[i];
if (!Double.isNaN(d)) {
if (!(d <= max_temp)) max_temp = d;
if (!(d >= min_temp)) min_temp = d;
avg_temp += d;
num_def++;
}
}
if (num_def > 00) {
avg_temp/= num_def;
// build a histogram from min to max
double [] hist = new double [num_bins];
double kbin = num_bins/(max_temp - min_temp);
int maxbin = num_bins - 1;
double s = 1.0/num_def;
for (int i = 0; i < avg_val.length; i++) {
double d = avg_val[i];
if (!Double.isNaN(d)) {
int ibin = (int) Math.floor((d - min_temp) * kbin);
if (ibin <0) ibin = 0;
else if (ibin > maxbin) {
ibin = maxbin;
}
hist[ibin] += s;
}
}
for (int i = 1; i < num_bins; i++) { // make cumulative, last is 1.0;
hist[i] += hist[i-1];
}
double temp_cold = min_temp;
double temp_hot = max_temp;
for (int i = 0; i < num_bins; i++) {
if (hist[i] > cold_frac) {
double d = hist[i];
double d_prev = (i > 0)? hist[ i-1 ]: 0.0;
double b_cold = (cold_frac-d_prev)/(d-d_prev) + i;
temp_cold = min_temp + b_cold* (max_temp - min_temp) / num_bins;
break;
}
}
for (int i = num_bins - 2; i >= 0; i--) {
if (hist[i] <= hot_frac) {
double d = hist[i];
double d_next = hist[i+1];
double b_hot = (hot_frac - d)/(d_next - d) + i;
temp_hot = min_temp + b_hot* (max_temp - min_temp) / num_bins;
break;
}
}
temp_scales = new double[avg_val.length];
Arrays.fill(temp_scales, Double.NaN);
double kscale = (1.0 - cold_scale)/(temp_hot - temp_cold);
for (int i = 0; i < avg_val.length; i++) {
double d = avg_val[i];
if (!Double.isNaN(d)) {
if (d < temp_cold) {
temp_scales[i] = cold_scale;
} else if (d > temp_hot) {
temp_scales[i] = 1.0;
} else {
temp_scales[i] = cold_scale + (d - temp_cold) * kscale;
}
}
}
}
}
String [] dbg_in_titles = {"fom", "strength", "spread", "disparity", "avg_val", "tscale"};
String [] dbg_titles = {"sky", "seed", "max", "shrank"}; String [] dbg_titles = {"sky", "seed", "max", "shrank"};
if (debugLevel>0) {
double [] fom = new double[strength.length];
for (int i = 0; i < fom.length; i++) {
fom[i] = Math.max(strength[i], min_strength) * spread[i] * temp_scales[i];
}
(new ShowDoubleFloatArrays()).showArrays(
new double[][] {fom, strength, spread, disparity, avg_val, temp_scales},
width,
fom.length/width,
true,
"sky_input",
dbg_in_titles); // dsrbg_titles);
}
double [][] dbg_img = (debugLevel>0) ? new double [dbg_titles.length][strength.length]:null; double [][] dbg_img = (debugLevel>0) ? new double [dbg_titles.length][strength.length]:null;
boolean [] sky_tiles = new boolean [strength.length]; boolean [] sky_tiles = new boolean [strength.length];
boolean [] prohibit_tiles = new boolean [strength.length]; boolean [] prohibit_tiles = new boolean [strength.length];
for (int i = 0; i < sky_tiles.length; i++) { for (int i = 0; i < sky_tiles.length; i++) {
double d = strength[i] * spread[i]; double d = Math.max(strength[i], min_strength) * spread[i];
sky_tiles[i] = (d < sky_seed); if (temp_scales != null) {
d *=temp_scales[i];
}
prohibit_tiles[i] = (d >= sky_lim); prohibit_tiles[i] = (d >= sky_lim);
int row = i/width;
// sky_tiles[i] = (row < seed_rows) && (d < sky_seed) && !(disparity[i] > disparity_seed);
sky_tiles[i] = (d < sky_seed) && !(disparity[i] > disparity_seed);
} }
//seed_rows
if (dbg_img != null) { if (dbg_img != null) {
for (int i = 0; i < sky_tiles.length; i++) { for (int i = 0; i < sky_tiles.length; i++) {
dbg_img[1][i] = sky_tiles[i]? 1 : 0; dbg_img[1][i] = sky_tiles[i]? 1 : 0;
...@@ -467,6 +575,9 @@ public class QuadCLTCPU { ...@@ -467,6 +575,9 @@ public class QuadCLTCPU {
sky_shrink, // int shrink, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more sky_shrink, // int shrink, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
sky_tiles, // boolean [] tiles, sky_tiles, // boolean [] tiles,
null); // boolean [] prohibit) null); // boolean [] prohibit)
if (seed_rows > 0) {
Arrays.fill(sky_tiles, seed_rows * width, sky_tiles.length, false);
}
if (dbg_img != null) { if (dbg_img != null) {
for (int i = 0; i < sky_tiles.length; i++) { for (int i = 0; i < sky_tiles.length; i++) {
dbg_img[3][i] = sky_tiles[i]? 1 : 0; dbg_img[3][i] = sky_tiles[i]? 1 : 0;
...@@ -510,21 +621,27 @@ public class QuadCLTCPU { ...@@ -510,21 +621,27 @@ public class QuadCLTCPU {
public void setBlueSky ( public void setBlueSky (
double sky_seed, // = 7.0; // start with product of strength by diff_second below this double sky_seed, // = 7.0; // start with product of strength by diff_second below this
double lma_seed, // 2.0; // seed - disparity_lma limit
double sky_lim, // = 15.0; // then expand to product of strength by diff_second below this double sky_lim, // = 15.0; // then expand to product of strength by diff_second below this
int sky_shrink, // = 4; int sky_shrink, // = 4;
int sky_expand_extra, // = 100; // 1? int sky_expand_extra, // = 100; // 1?
double [] strength, double [] strength,
double [] spread, double [] spread,
double [] disp_lma,
double [] avg_val,
int debugLevel) { int debugLevel) {
int width = tp.getTilesX(); int width = tp.getTilesX();
this.blue_sky = getBlueSky ( this.blue_sky = getBlueSky (
sky_seed, // = 7.0; // start with product of strength by diff_second below this sky_seed, // = 7.0; // start with product of strength by diff_second below this
lma_seed, // 2.0; // seed - disparity_lma limit
sky_lim, // = 15.0; // then expand to product of strength by diff_second below this sky_lim, // = 15.0; // then expand to product of strength by diff_second below this
sky_shrink, // = 4; sky_shrink, // = 4;
sky_expand_extra, // = 100; // 1? sky_expand_extra, // = 100; // 1?
width, width,
strength, strength,
spread, spread,
disp_lma,
avg_val,
debugLevel); debugLevel);
} }
...@@ -1020,7 +1137,7 @@ public class QuadCLTCPU { ...@@ -1020,7 +1137,7 @@ public class QuadCLTCPU {
} }
// try to restore DSI generated from interscene if available, if not use single-scene -DSI_MAIN // try to restore DSI generated from interscene if available, if not use single-scene -DSI_MAIN
int dsi_result = -1; int dsi_result = -1;
double [][] dsi_tmp = new double [11][]; double [][] dsi_tmp = new double [OpticalFlow.COMBO_DSN_TITLES.length][];
for (int i = 0; i <DSI_SUFFIXES.length; i++) { for (int i = 0; i <DSI_SUFFIXES.length; i++) {
dsi_result =restoreDSI( dsi_result =restoreDSI(
DSI_SUFFIXES[i], DSI_SUFFIXES[i],
...@@ -9722,6 +9839,7 @@ public class QuadCLTCPU { ...@@ -9722,6 +9839,7 @@ public class QuadCLTCPU {
} }
// copy second_max from the BG pass to the last one (to be used) // copy second_max from the BG pass to the last one (to be used)
tp.clt_3d_passes.get(tp.clt_3d_passes.size()-1).setSecondMax(tp.clt_3d_passes.get(bg_pass).getSecondMax()); tp.clt_3d_passes.get(tp.clt_3d_passes.size()-1).setSecondMax(tp.clt_3d_passes.get(bg_pass).getSecondMax());
tp.clt_3d_passes.get(tp.clt_3d_passes.size()-1).setAvgVal(tp.clt_3d_passes.get(bg_pass).getAvgVal());
///// Refining after all added - end ///// Refining after all added - end
Runtime.getRuntime().gc(); Runtime.getRuntime().gc();
System.out.println("preExpandCLTQuad3d(): processing finished at "+ System.out.println("preExpandCLTQuad3d(): processing finished at "+
...@@ -13965,6 +14083,8 @@ public class QuadCLTCPU { ...@@ -13965,6 +14083,8 @@ public class QuadCLTCPU {
scan.is_measured = true; // but no disparity map/textures scan.is_measured = true; // but no disparity map/textures
scan.is_combo = false; scan.is_combo = false;
scan.has_lma = null; scan.has_lma = null;
scan.setAvgVal();
scan.setSecondMax(); // always needed even with max_chn_diff==0 as it is exported in a file
if (max_chn_diff > 0 ) { if (max_chn_diff > 0 ) {
scan.resetByDiff( scan.resetByDiff(
max_chn_diff, max_chn_diff,
......
...@@ -343,10 +343,11 @@ public class TileNeibs{ ...@@ -343,10 +343,11 @@ public class TileNeibs{
boolean [] src_tiles = tiles.clone(); // just in case boolean [] src_tiles = tiles.clone(); // just in case
// grow // grow
boolean hor = true; boolean hor = true;
int num_prev = 0;
for (; grow > 0; grow--){ for (; grow > 0; grow--){
boolean single = (grow ==1) && hor; boolean single = (grow ==1) && hor;
src_tiles = tiles.clone(); src_tiles = tiles.clone();
int num_new = 0; int num_new = 1; // as if previous pass was successful
if (hor){ if (hor){
for (int tileY = 0; tileY < sizeY; tileY++){ for (int tileY = 0; tileY < sizeY; tileY++){
for (int tileX = 0; tileX < (sizeX - 1); tileX++){ for (int tileX = 0; tileX < (sizeX - 1); tileX++){
...@@ -394,9 +395,10 @@ public class TileNeibs{ ...@@ -394,9 +395,10 @@ public class TileNeibs{
} }
} }
hor = !hor; hor = !hor;
if (num_new == 0){ if ((num_new == 0) && (num_prev == 0)){
break; break;
} }
num_prev = num_new;
} }
} }
......
...@@ -3913,11 +3913,12 @@ ImageDtt.startAndJoin(threads); ...@@ -3913,11 +3913,12 @@ ImageDtt.startAndJoin(threads);
double [] disparity = scan.getDisparity(use_final?0:1); double [] disparity = scan.getDisparity(use_final?0:1);
double [] disparityLMA = scan.getDisparityLMA(); double [] disparityLMA = scan.getDisparityLMA();
double [] second_max_bg = scan.getSecondMax(); double [] second_max_bg = scan.getSecondMax();
double [] avg_val = scan.getAvgVal();
if (!use_final) { if (!use_final) {
scan.setStrength(null); scan.setStrength(null);
} }
double [] strength = scan.getStrength(); double [] strength = scan.getStrength();
return new double [][] {disparity, strength, disparityLMA,second_max_bg}; // second maximal difference between channels in BG return new double [][] {disparity, strength, disparityLMA,second_max_bg, avg_val}; // second maximal difference between channels in BG
} }
// TODO: update for variable length // TODO: update for variable length
......
...@@ -82,6 +82,8 @@ public class TwoQuadCLT { ...@@ -82,6 +82,8 @@ public class TwoQuadCLT {
public static int DSI_STRENGTH_RIG = 8; public static int DSI_STRENGTH_RIG = 8;
public static int DSI_SPREAD_MAIN = 9; public static int DSI_SPREAD_MAIN = 9;
public static int DSI_SPREAD_AUX = 10; public static int DSI_SPREAD_AUX = 10;
public static int DSI_AVGVAL_MAIN = 11;
public static int DSI_AVGVAL_AUX = 12;
public static String DSI_COMBO_SUFFIX = "-DSI_COMBO"; public static String DSI_COMBO_SUFFIX = "-DSI_COMBO";
public static String DSI_MAIN_SUFFIX = "-DSI_MAIN"; public static String DSI_MAIN_SUFFIX = "-DSI_MAIN";
...@@ -97,7 +99,9 @@ public class TwoQuadCLT { ...@@ -97,7 +99,9 @@ public class TwoQuadCLT {
"strength_aux", "strength_aux",
"strength_rig", "strength_rig",
"spread_main", "spread_main",
"spread_aux"}; "spread_aux",
"avgval_main",
"avgval_aux"};
public long startTime; // start of batch processing public long startTime; // start of batch processing
public long startSetTime; // start of set processing public long startSetTime; // start of set processing
......
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