Loading src/main/java/com/elphel/imagej/tileprocessor/Corr2dLMA.java +156 −68 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ public class Corr2dLMA { final static String PAR_NAME_CORRNDISP = "CORR-NDISP"; double [] all_pars; boolean [] par_mask; int [] par_map; double [] vector; double [] scales = {1.0, 2.0, 4.0}; ArrayList<Sample> samples = new ArrayList<Sample>(); Loading Loading @@ -119,6 +120,7 @@ public class Corr2dLMA { private final Matrix [][] m_pairs_last = new Matrix[NUM_CAMS][NUM_CAMS]; private final int [][] pindx = new int [NUM_CAMS][NUM_CAMS]; public class Sample{ // USED in lwir int fcam; // first camera index int scam; // second camera index Loading Loading @@ -194,6 +196,41 @@ public class Corr2dLMA { if ((w > 0) && !Double.isNaN(v)) samples.add(new Sample(fcam,scam,x,y,v,w)); } public double [][] dbgGetSamples(int mode){ int size = 2* transform_size -1; int size2 = size*size; double [][] rslt = new double [npairs][size2]; for (int np = 0; np < npairs; np++) { for (int i = 0; i < size2; i++) { rslt[np][i] = Double.NaN; } } double [] fx = null; if (mode == 2) { fx = getFx(); if (fx == null) return null; } for (int ns = 0; ns < samples.size(); ns++) { Sample s = samples.get(ns); double d = Double.NaN; if (mode == 0) d = s.v; else if (mode == 1) d = s.w; else if (mode == 2) d = fx[ns]; int np = USED_PAIRS_MAP[s.fcam][s.scam]; rslt[np][s.iy*size + s.ix] = d; } return rslt; } public String [] dbgGetSliceTiles() { String [] srslt = new String [npairs]; for (int f = 0; f < NUM_CAMS; f++) for (int s = 0; s < NUM_CAMS; s++) { if (USED_PAIRS_MAP[f][s] >= 0) { srslt[USED_PAIRS_MAP[f][s]] = ""+f+"->"+s; } } return srslt; } public int getPairIndex(int f, int s) { if (f > s) { Loading @@ -216,10 +253,12 @@ public class Corr2dLMA { boolean adjust_width, // adjust width of the maximum - lma_adjust_wm boolean adjust_scales, // adjust 2D correlation scales - lma_adjust_ag boolean adjust_ellipse, // allow non-circular correlation maximums lma_adjust_wy boolean adjust_lazyeye, // adjust disparity corrections and orthogonal disparities lma_adjust_wxy boolean adjust_lazyeye_par, // adjust disparity corrections parallel to disparities lma_adjust_wxy boolean adjust_lazyeye_ortho, // adjust disparity corrections orthogonal to disparities lma_adjust_ly1 double disp0, // initial value of disparity double half_width, // A=1/(half_widh)^2 lma_half_width double cost_lazyeye // cost for each of the non-zero disparity corrections and ortho disparity lma_cost_wy double cost_lazyeye_par, // cost for each of the non-zero disparity corrections lma_cost_wy double cost_lazyeye_odtho // cost for each of the non-zero ortho disparity corrections lma_cost_wxy ) { // int [][] pindx = new int [NUM_CAMS][NUM_CAMS]; for (int f = 0; f < NUM_CAMS; f++) { Loading @@ -238,16 +277,6 @@ public class Corr2dLMA { for (Sample s:samples) { // ignore zero-weight samples used_cameras[s.fcam]=true; used_cameras[s.scam]=true; /* if (s.fcam > last_cam) { second_last = false; last_cam = s.fcam; } if (s.scam > last_cam) { second_last = true; last_cam = s.scam; } */ used_pairs[pindx[s.fcam][s.scam]]=true; // throws < 0 - wrong pair, f==s used_pairs_dir[s.fcam][s.scam] = true; } Loading Loading @@ -290,17 +319,17 @@ public class Corr2dLMA { for (int i = 0; i <NUM_CAMS; i++) { this.all_pars[DDISP_INDEX + i] = 0.0; // C-A this.par_mask[DDISP_INDEX + i] = used_cameras[i] & adjust_lazyeye & (i != last_cam); this.par_mask[DDISP_INDEX + i] = used_cameras[i] & adjust_lazyeye_par & (i != last_cam); this.all_pars[NDISP_INDEX + i] = 0.0; // C-A this.par_mask[NDISP_INDEX + i] = used_cameras[i] & adjust_lazyeye; this.par_mask[NDISP_INDEX + i] = used_cameras[i] & adjust_lazyeye_ortho; } int np = samples.size(); weights = new double [np + 2 * NUM_CAMS]; // npairs]; values = new double [np + 2 * NUM_CAMS]; // npairs]; for (int i = 0; i < NUM_CAMS; i++) { weights[np + i] = (used_cameras[i] & adjust_lazyeye)? cost_lazyeye : 0.0; // ddisp - including last_camera weights[np + NUM_CAMS + i] = (used_cameras[i] & adjust_lazyeye)? cost_lazyeye : 0.0; // ndisp weights[np + i] = (used_cameras[i] & adjust_lazyeye_par)? cost_lazyeye_par : 0.0; // ddisp - including last_camera weights[np + NUM_CAMS + i] = (used_cameras[i] & adjust_lazyeye_ortho)? cost_lazyeye_odtho : 0.0; // ndisp values [np + i] = 0.0; values [np + NUM_CAMS + i] = 0.0; } Loading Loading @@ -340,6 +369,13 @@ public class Corr2dLMA { pair_weights[i]*=rspw; } } par_map = new int [par_mask.length]; int par_indx = 0; for (int i = 0; i < par_mask.length; i++) { if (par_mask[i]) par_map[i] = par_indx++; else par_map[i] = -1; } toVector(); } Loading Loading @@ -369,6 +405,8 @@ public class Corr2dLMA { double [][] jt) { // should be either [vector.length][samples.size()] or null - then only fx is calculated if (vector == null) return null; double [] av = fromVector(vector); // restoration of the last camera is moved to fromVector() /* // restore ddisp("x") offset for the last camera // prepare parameters common for each camera/camera pair before calculating fx and derivatives av[DDISP_INDEX + last_cam] = 0.0; Loading @@ -377,6 +415,7 @@ public class Corr2dLMA { av[DDISP_INDEX + last_cam] -= av[DDISP_INDEX + i]; } } */ Matrix [] xcam_ycam = new Matrix[NUM_CAMS]; for (int i = 0; i < NUM_CAMS; i++) if (used_cameras[i]) { double [] add_dnd = {av[DISP_INDEX]+ av[DDISP_INDEX + i], av[NDISP_INDEX + i]}; Loading Loading @@ -418,73 +457,106 @@ public class Corr2dLMA { double xmxp_ymyp = xmxp * ymyp; double d = Wp*(1.0 - (A*xmxp2 + 2 * B * xmxp_ymyp + C * ymyp2)); fx[ns] = d * Gp; int np = 0; if (Double.isNaN(fx[ns])) { System.out.println("fx["+ns+"]="+fx[ns]); } // int np = 0; if (jt != null) { if (par_mask[DISP_INDEX]) jt[np++][ns] = 2 * WGp * if (par_map[DISP_INDEX] >= 0) jt[par_map[DISP_INDEX]][ns] = 2 * WGp * ((A * xmxp + B * ymyp) * m_pairs[s.fcam][s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_pairs[s.fcam][s.scam].get(1, 0)); if (par_mask[A_INDEX]) jt[np++][ns] = -WGp*(xmxp2 + ymyp2); if (par_mask[B_INDEX]) jt[np++][ns] = -WGp* 2 * xmxp_ymyp; if (par_mask[CMA_INDEX]) jt[np++][ns] = -WGp* ymyp2; if (par_map[A_INDEX] >= 0) jt[par_map[A_INDEX]][ns] = -WGp*(xmxp2 + ymyp2); if (par_map[B_INDEX] >= 0) jt[par_map[B_INDEX]][ns] = -WGp* 2 * xmxp_ymyp; if (par_map[CMA_INDEX] >= 0) jt[par_map[CMA_INDEX]][ns] = -WGp* ymyp2; for (int p = 0; p < npairs; p++) { // par_mask[G0_INDEX + p] as all pairs either used, or not - then npairs == 0 if (par_mask[G0_INDEX + p]) jt[np++][ns] = (p== pair)? d : 0.0; // (par_mask[G0_INDEX + pair])? d; if (par_map[G0_INDEX + p] >= 0) jt[par_map[G0_INDEX + p]][ns] = (p== pair)? d : 0.0; // (par_mask[G0_INDEX + pair])? d; } // USED_PAIRS_MAP // USED_CAMS_MAP // process ddisp (last camera not used, is equal to minus sum of others to make a sum == 0) for (int f = 0; f < ncam - 1; f++) { // -1 for the last_cam jt[np + USED_CAMS_MAP[f]][ns] = 0.0; // Need to fix for missing parameters // for (int f = 0; f < ncam - 1; f++) if (par_map[DDISP_INDEX + f] >= 0) { // -1 for the last_cam // jt[np + USED_CAMS_MAP[f]][ns] = 0.0; for (int f = 0; f < NUM_CAMS; f++) if (par_map[DDISP_INDEX + f] >= 0) { // -1 for the last_cam jt[par_map[DDISP_INDEX + f]][ns] = 0.0; } if (par_map[DDISP_INDEX + s.fcam] >= 0){ // par_map[DDISP_INDEX + last_cam] always <0 jt[par_map[DDISP_INDEX + s.fcam]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 0)); } else if (s.fcam == last_cam) { for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && (par_map[DDISP_INDEX + c] >=0)) { jt[par_map[DDISP_INDEX + c]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 0)); } } if ((par_mask[DDISP_INDEX + s.fcam] || (s.fcam == last_cam)) && ((par_mask[DDISP_INDEX + s.scam] || (s.scam == last_cam)))) { if (par_map[DDISP_INDEX + s.scam]>= 0){ // par_map[DDISP_INDEX + last_cam] always <0 jt[par_map[DDISP_INDEX + s.scam]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 0)); } else if (s.scam == last_cam) { for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && (par_map[DDISP_INDEX + c] >= 0)) { jt[par_map[DDISP_INDEX + c]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 0)); } } /* if (((par_map[DDISP_INDEX + s.fcam] >= 0) || (s.fcam == last_cam)) && (((par_map[DDISP_INDEX + s.scam]>= 0) || (s.scam == last_cam)))) { if (s.fcam != last_cam) { jt[np + USED_CAMS_MAP[s.fcam]][ns] += 2 * WGp * if (par_map[DDISP_INDEX + s.fcam] >= 0) jt[par_map[DDISP_INDEX + s.fcam]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 0)); } else { // last camera - use all others with minus sign for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && par_mask[DDISP_INDEX + c]) { jt[np + USED_CAMS_MAP[c]][ns] -= 2 * WGp * // ((A * xmxp + B * ymyp) * m_disp[c].get(0, 0)+ // (B * xmxp + C * ymyp) * m_disp[c].get(1, 0)); for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && (par_map[DDISP_INDEX + c] >=0)) { jt[par_map[DDISP_INDEX + c]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 0)); } } if (s.scam != last_cam) { jt[np + USED_CAMS_MAP[s.scam]][ns] -= 2 * WGp * if (par_map[DDISP_INDEX + s.scam] >= 0) jt[par_map[DDISP_INDEX + s.scam]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 0)); } else { for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && par_mask[DDISP_INDEX + c]) { jt[np + USED_CAMS_MAP[c]][ns] += 2 * WGp * // ((A * xmxp + B * ymyp) * m_disp[c].get(0, 0)+ // (B * xmxp + C * ymyp) * m_disp[c].get(1, 0)); for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && (par_map[DDISP_INDEX + c] >= 0)) { jt[par_map[DDISP_INDEX + c]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 0)); } } } np += ncam -1;// -1 for the last_cam */ // np += ncam -1;// -1 for the last_cam // process ndisp for (int f = 0; f < ncam; f++) { jt[np + USED_CAMS_MAP[f]][ns] = 0.0; for (int f = 0; f < ncam; f++) if (par_map[NDISP_INDEX + f] >= 0) { jt[par_map[NDISP_INDEX + f]][ns] = 0.0; } if (par_mask[NDISP_INDEX + s.fcam] && (par_mask[NDISP_INDEX + s.scam] )) { jt[np + USED_CAMS_MAP[s.fcam]][ns] += 2 * WGp * if (par_map[NDISP_INDEX + s.fcam] >=0){ jt[par_map[NDISP_INDEX + s.fcam]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 1)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 1)); jt[np + USED_CAMS_MAP[s.scam]][ns] -= 2 * WGp * } if (par_map[NDISP_INDEX + s.scam] >= 0) { jt[par_map[NDISP_INDEX + s.scam]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 1)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 1)); } np += ncam; // np += ncam; } } int np = 0; // int np = 0; for (int n = 0; n < NUM_CAMS; n++) { // av[DDISP_INDEX +last_cam] is already populated fx[num_samples + n] = av[DDISP_INDEX + n]; fx[num_samples + NUM_CAMS + n] = av[NDISP_INDEX + n]; Loading @@ -492,28 +564,26 @@ public class Corr2dLMA { // and derivatives if (jt != null) { if (par_mask[DISP_INDEX]) np++; if (par_mask[A_INDEX]) np++; if (par_mask[B_INDEX]) np++; if (par_mask[CMA_INDEX]) np++; np+= npairs; // now it points to the ddisp block // if (par_mask[DISP_INDEX]) np++; // if (par_mask[A_INDEX]) np++; // if (par_mask[B_INDEX]) np++; // if (par_mask[CMA_INDEX]) np++; // np+= npairs; // now it points to the ddisp block for (int i = 0; i < NUM_CAMS; i++) { if ((i != last_cam) && par_mask[DDISP_INDEX + i]) { if ((i != last_cam) && (par_map[DDISP_INDEX + i] >= 0)) { for (int j = 0; j < NUM_CAMS; j++) { // j - column jt[np][num_samples + j] = (i==j)? 1.0 : 0.0; jt[par_map[DDISP_INDEX + i]][num_samples + j] = (i==j)? 1.0 : 0.0; } jt[np][num_samples + last_cam] = -1.0; np++; jt[par_map[DDISP_INDEX + i]][num_samples + last_cam] = -1.0; } } // np now points at the first ndisp for (int i = 0; i < NUM_CAMS; i++) { if (par_mask[NDISP_INDEX + i]) { if (par_map[NDISP_INDEX + i] >= 0) { for (int j = 0; j < NUM_CAMS; j++) { // j - column jt[np][num_samples + NUM_CAMS + j] = (i==j)? 1.0 : 0.0; jt[par_map[NDISP_INDEX + i] ][num_samples + NUM_CAMS + j] = (i==j)? 1.0 : 0.0; } } np++; } } return fx; Loading Loading @@ -544,7 +614,8 @@ public class Corr2dLMA { double [] fx = getFx(); if (fx == null) return; for (int i = 0; i < fx.length; i++) { double fx_pos = (fx[i] >= 0)? fx[i]: Double.NaN; // double fx_pos = (fx[i] >= 0)? fx[i]: Double.NaN; double fx_pos = fx[i]; if (i < samples.size()) { s = samples.get(i); System.out.println(String.format("%3d: x=%2d y=%2d v=%9.6f fx=%9.6f w=%9.7f fcam=%1d scam=%1d", i, s.ix, s.iy, s.v, fx_pos, s.w, s.fcam, s.scam)); Loading Loading @@ -605,13 +676,30 @@ public class Corr2dLMA { public void updateFromVector() { // USED in lwir int np = 0; for (int i = 0; i < par_mask.length; i++) if (par_mask[i]) all_pars[i] = vector[np++]; // just for reporting all_pars[DDISP_INDEX + last_cam] = 0.0; for (int i = 0; i < NUM_CAMS; i++) { if (used_cameras[i] & (i != last_cam)) { all_pars[DDISP_INDEX + last_cam] -= all_pars[DDISP_INDEX + i]; } } } public double [] fromVector(double [] vector) { // mix fixed and variable parameters // USED in lwir if ( all_pars == null) return null; double [] ap = all_pars.clone(); int np = 0; for (int i = 0; i < par_mask.length; i++) if (par_mask[i]) ap[i] = vector[np++]; ap[DDISP_INDEX + last_cam] = 0.0; for (int i = 0; i < NUM_CAMS; i++) { if (used_cameras[i] & (i != last_cam)) { ap[DDISP_INDEX + last_cam] -= ap[DDISP_INDEX + i]; } } return ap; } Loading src/main/java/com/elphel/imagej/tileprocessor/Correlation2d.java +40 −3 Original line number Diff line number Diff line Loading @@ -1755,6 +1755,7 @@ public class Correlation2d { public Corr2dLMA corrLMA2( // USED in lwir ImageDttParameters imgdtt_params, double [][] corr_wnd, // correlation window to save on re-calculation of the window double [] corr_wnd_limited, // correlation window, limited not to be smaller than threshold - used for finding max/convex areas (or null) double [][] corrs, double [][] disp_dist, // per camera disparity matrix as a 1d (linescan order) int pair_mask, // which pairs to process Loading Loading @@ -1791,6 +1792,11 @@ public class Correlation2d { for (int npair = 0; npair < corrs.length; npair++) if ((corrs[npair] != null) && (((pair_mask >> npair) & 1) !=0)){ double[] corr = corrs[npair].clone(); if (corr_wnd_limited != null) { for (int i = 0; i < corr.length; i++) { corr[i] /= corr_wnd_limited[i]; } } if (sigma > 0) { gb.blurDouble(corr, corr_size, corr_size, sigma, sigma, 0.01); } Loading Loading @@ -1853,10 +1859,13 @@ public class Correlation2d { imgdtt_params.lma_adjust_wm, // boolean adjust_width, // adjust width of the maximum - lma_adjust_wm imgdtt_params.lma_adjust_ag, // boolean adjust_scales, // adjust 2D correlation scales - lma_adjust_ag imgdtt_params.lma_adjust_wy, // boolean adjust_ellipse, // allow non-circular correlation maximums lma_adjust_wy imgdtt_params.lma_adjust_wxy, // boolean adjust_lazyeye, // adjust disparity corrections and orthogonal disparities lma_adjust_wxy imgdtt_params.lma_adjust_wxy, // boolean adjust_lazyeye_par, // adjust disparity corrections parallel to disparities lma_adjust_wxy imgdtt_params.lma_adjust_ly1, // boolean adjust_lazyeye_ortho, // adjust disparity corrections orthogonal to disparities lma_adjust_ly1 xcenter, // double disp0, // initial value of disparity imgdtt_params.lma_half_width, // double half_width, // A=1/(half_widh)^2 lma_half_width imgdtt_params.lma_cost_wy // double cost_lazyeye // cost for each of the non-zero disparity corrections and ortho disparity lma_cost_wy imgdtt_params.lma_cost_wy, // double cost_lazyeye_par, // cost for each of the non-zero disparity corrections lma_cost_wy imgdtt_params.lma_cost_wxy // double cost_lazyeye_odtho // cost for each of the non-zero ortho disparity corrections lma_cost_wxy ); lma.setMatrices(disp_dist); lma.initMatrices(); // should be called after initVector and after setMatrices Loading @@ -1864,6 +1873,8 @@ public class Correlation2d { if (debug_level > 1) { System.out.println("Input data:"); lma.printInputDataFx(false); lma.printParams(); } lmaSuccess = lma.runLma( Loading @@ -1886,6 +1897,31 @@ public class Correlation2d { System.out.println("Input data and approximation:"); lma.printInputDataFx(true); } if (debug_graphic && lmaSuccess) { String [] sliceTitles = lma.dbgGetSliceTiles(); (new ShowDoubleFloatArrays()).showArrays( lma.dbgGetSamples(0), corr_size, corr_size, true, "corr_values"+"_x"+tileX+"_y"+tileY, sliceTitles); (new ShowDoubleFloatArrays()).showArrays( lma.dbgGetSamples(1), corr_size, corr_size, true, "corr_weights"+"_x"+tileX+"_y"+tileY, sliceTitles); (new ShowDoubleFloatArrays()).showArrays( lma.dbgGetSamples(2), corr_size, corr_size, true, "corr_fx"+"_x"+tileX+"_y"+tileY, sliceTitles); } return lmaSuccess? lma: null; } Loading Loading @@ -2314,6 +2350,7 @@ public class Correlation2d { * @return cost packed array, corresponding to the input. selected convex points have weight * 1.0, other selected - nc_cost */ public double [] filterConvex(// USED in lwir double [] corr_data, int hwin, Loading src/main/java/com/elphel/imagej/tileprocessor/ImageDtt.java +52 −3 Original line number Diff line number Diff line Loading @@ -1576,6 +1576,12 @@ public class ImageDtt { final int globalDebugLevel) { final boolean debug_distort= true; // final double [][] debug_offsets = null; // final double [][] debug_offsets = {{0.5, 0.5},{0.0,0.0},{0.0,0.0},{-0.5,-0.5}}; // add to calculated CenterXY for evaluating new LMA // final double [][] debug_offsets = {{ 0.5, 0.5},{ 0.5,-0.5},{-0.5, 0.5},{-0.5,-0.5}}; // add to calculated CenterXY for evaluating new LMA // final double [][] debug_offsets = {{ 0.5, 0.0},{ -0.5, 0.0},{-0.5, 0.0},{ 0.5, 0.0}}; // add to calculated CenterXY for evaluating new LMA // final double [][] debug_offsets = {{ 1.0, 0.0},{ -1.0, 0.0},{-1.0, 0.0},{ 1.0, 0.0}}; // add to calculated CenterXY for evaluating new LMA final double [][] debug_offsets = {{ 0.0, 1.0},{ 0.0, -1.0},{ 0.0, -1.0},{ 0.0, 1.0}}; // add to calculated CenterXY for evaluating new LMA final boolean macro_mode = macro_scale != 1; // correlate tile data instead of the pixel data final int quad = 4; // number of subcameras final int numcol = 3; // number of colors // keep the same, just do not use [0] and [1], [2] - green Loading Loading @@ -1792,6 +1798,18 @@ public class ImageDtt { double [][][][] tcorr_tpartial = null; // [quad][numcol+1][4][8*8] double [] ports_rgb = null; double [][] corr_wnd = (new Corr2dLMA(transform_size, null)).getCorrWnd(); double [] corr_wnd_limited = null; if (imgdtt_params.lma_min_wnd <= 1.0) { corr_wnd_limited = new double [corr_wnd.length * corr_wnd[0].length]; int indx = 0; for (int i = 0; i < corr_wnd.length; i++) { for (int j = 0; j < corr_wnd[i].length; j++) { corr_wnd_limited[indx++] = Math.max(corr_wnd[i][j], imgdtt_params.lma_min_wnd); } } } Correlation2d corr2d = new Correlation2d( imgdtt_params, // ImageDttParameters imgdtt_params, transform_size, // int transform_size, Loading Loading @@ -1834,7 +1852,7 @@ public class ImageDtt { } if (macro_mode){ if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY)) { // before correction if ((globalDebugLevel > -1) && debugTile) { // before correction System.out.println("\nUsing MACRO mode, centerX="+centerX+", centerY="+centerY); } centersXY = geometryCorrection.getPortsCoordinatesIdeal( Loading Loading @@ -1870,13 +1888,33 @@ public class ImageDtt { disparity_array[tileY][tileX] + disparity_corr); } if ((globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)) { if (((globalDebugLevel > 0) || debug_distort) && debugTile) { for (int i = 0; i < quad; i++) { System.out.println("clt_aberrations_quad_corr(): tileX="+tileX+", tileY="+tileY+ " centerX="+centerX+" centerY="+centerY+" disparity="+disparity_array[tileY][tileX]+ " centersXY["+i+"][0]="+centersXY[i][0]+" centersXY["+i+"][1]="+centersXY[i][1]); } } if (debug_distort && debugTile && (debug_offsets != null)) { double [][] debug_offsets_xy = new double [debug_offsets.length][2]; for (int i = 0; i < debug_offsets.length; i++) { debug_offsets_xy[i][0] = disp_dist[i][0] * debug_offsets[i][0] + disp_dist[i][1] * debug_offsets[i][1]; debug_offsets_xy[i][1] = disp_dist[i][2] * debug_offsets[i][0] + disp_dist[i][3] * debug_offsets[i][1]; } for (int i = 0; i < quad; i++) { System.out.println(String.format("%d: {%8.3f, %8.3f}",i,debug_offsets_xy[i][0],debug_offsets_xy[i][1])); } for (int i = 0; i < debug_offsets.length; i++) { centersXY[i][0] += debug_offsets_xy[i][0]; centersXY[i][1] += debug_offsets_xy[i][1]; } for (int i = 0; i < quad; i++) { System.out.println("Corrected clt_aberrations_quad_corr(): tileX="+tileX+", tileY="+tileY+ " centerX="+centerX+" centerY="+centerY+" disparity="+disparity_array[tileY][tileX]+ " centersXY["+i+"][0]="+centersXY[i][0]+" centersXY["+i+"][1]="+centersXY[i][1]); } } if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY)) { // before correction System.out.print(disparity_array[tileY][tileX]+"\t"+ Loading Loading @@ -2305,6 +2343,7 @@ public class ImageDtt { Corr2dLMA lma2 = corr2d.corrLMA2( imgdtt_params, // ImageDttParameters imgdtt_params, corr_wnd, // double [][] corr_wnd, // correlation window to save on re-calculation of the window corr_wnd_limited, // corr_wnd_limited, // correlation window, limited not to be smaller than threshold - used for finding max/convex areas (or null) corrs, // double [][] corrs, disp_dist, imgdtt_params.dbg_pair_mask, // int pair_mask, // which pairs to process Loading @@ -2312,7 +2351,7 @@ public class ImageDtt { 0.5, // double sigma, // low-pass sigma to find maximum (and convex too corr_stat[0], // double xcenter, // preliminary center x in pixels for largest baseline imgdtt_params.ortho_vasw_pwr, // double vasw_pwr, // value as weight to this power, tile_lma_debug_level, // int debug_level, tile_lma_debug_level+2, // int debug_level, tileX, // int tileX, // just for debug output tileY ); // int tileY Loading @@ -2337,6 +2376,16 @@ public class ImageDtt { tileX, // int tileX, // just for debug output tileY ); // int tileY double [] lma_disparity_strength = null; double max_disp_diff_lma = 3.0; if (lma != null) { lma_disparity_strength = lma.getDisparityStrength(); if (Math.abs(lma_disparity_strength[0] - disparity ) > max_disp_diff_lma) { if (globalDebugLevel > -1) { System.out.println("Crazy LMA for tileX="+tileX+", tileY="+tileY+": disparity="+disparity+",lma_disparity_strength[0]="+lma_disparity_strength[0]); } lma = null; } } if (lma != null) { double [] mod_disparity_diff = null; double [][] dir_corr_strength = null; Loading Loading
src/main/java/com/elphel/imagej/tileprocessor/Corr2dLMA.java +156 −68 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ public class Corr2dLMA { final static String PAR_NAME_CORRNDISP = "CORR-NDISP"; double [] all_pars; boolean [] par_mask; int [] par_map; double [] vector; double [] scales = {1.0, 2.0, 4.0}; ArrayList<Sample> samples = new ArrayList<Sample>(); Loading Loading @@ -119,6 +120,7 @@ public class Corr2dLMA { private final Matrix [][] m_pairs_last = new Matrix[NUM_CAMS][NUM_CAMS]; private final int [][] pindx = new int [NUM_CAMS][NUM_CAMS]; public class Sample{ // USED in lwir int fcam; // first camera index int scam; // second camera index Loading Loading @@ -194,6 +196,41 @@ public class Corr2dLMA { if ((w > 0) && !Double.isNaN(v)) samples.add(new Sample(fcam,scam,x,y,v,w)); } public double [][] dbgGetSamples(int mode){ int size = 2* transform_size -1; int size2 = size*size; double [][] rslt = new double [npairs][size2]; for (int np = 0; np < npairs; np++) { for (int i = 0; i < size2; i++) { rslt[np][i] = Double.NaN; } } double [] fx = null; if (mode == 2) { fx = getFx(); if (fx == null) return null; } for (int ns = 0; ns < samples.size(); ns++) { Sample s = samples.get(ns); double d = Double.NaN; if (mode == 0) d = s.v; else if (mode == 1) d = s.w; else if (mode == 2) d = fx[ns]; int np = USED_PAIRS_MAP[s.fcam][s.scam]; rslt[np][s.iy*size + s.ix] = d; } return rslt; } public String [] dbgGetSliceTiles() { String [] srslt = new String [npairs]; for (int f = 0; f < NUM_CAMS; f++) for (int s = 0; s < NUM_CAMS; s++) { if (USED_PAIRS_MAP[f][s] >= 0) { srslt[USED_PAIRS_MAP[f][s]] = ""+f+"->"+s; } } return srslt; } public int getPairIndex(int f, int s) { if (f > s) { Loading @@ -216,10 +253,12 @@ public class Corr2dLMA { boolean adjust_width, // adjust width of the maximum - lma_adjust_wm boolean adjust_scales, // adjust 2D correlation scales - lma_adjust_ag boolean adjust_ellipse, // allow non-circular correlation maximums lma_adjust_wy boolean adjust_lazyeye, // adjust disparity corrections and orthogonal disparities lma_adjust_wxy boolean adjust_lazyeye_par, // adjust disparity corrections parallel to disparities lma_adjust_wxy boolean adjust_lazyeye_ortho, // adjust disparity corrections orthogonal to disparities lma_adjust_ly1 double disp0, // initial value of disparity double half_width, // A=1/(half_widh)^2 lma_half_width double cost_lazyeye // cost for each of the non-zero disparity corrections and ortho disparity lma_cost_wy double cost_lazyeye_par, // cost for each of the non-zero disparity corrections lma_cost_wy double cost_lazyeye_odtho // cost for each of the non-zero ortho disparity corrections lma_cost_wxy ) { // int [][] pindx = new int [NUM_CAMS][NUM_CAMS]; for (int f = 0; f < NUM_CAMS; f++) { Loading @@ -238,16 +277,6 @@ public class Corr2dLMA { for (Sample s:samples) { // ignore zero-weight samples used_cameras[s.fcam]=true; used_cameras[s.scam]=true; /* if (s.fcam > last_cam) { second_last = false; last_cam = s.fcam; } if (s.scam > last_cam) { second_last = true; last_cam = s.scam; } */ used_pairs[pindx[s.fcam][s.scam]]=true; // throws < 0 - wrong pair, f==s used_pairs_dir[s.fcam][s.scam] = true; } Loading Loading @@ -290,17 +319,17 @@ public class Corr2dLMA { for (int i = 0; i <NUM_CAMS; i++) { this.all_pars[DDISP_INDEX + i] = 0.0; // C-A this.par_mask[DDISP_INDEX + i] = used_cameras[i] & adjust_lazyeye & (i != last_cam); this.par_mask[DDISP_INDEX + i] = used_cameras[i] & adjust_lazyeye_par & (i != last_cam); this.all_pars[NDISP_INDEX + i] = 0.0; // C-A this.par_mask[NDISP_INDEX + i] = used_cameras[i] & adjust_lazyeye; this.par_mask[NDISP_INDEX + i] = used_cameras[i] & adjust_lazyeye_ortho; } int np = samples.size(); weights = new double [np + 2 * NUM_CAMS]; // npairs]; values = new double [np + 2 * NUM_CAMS]; // npairs]; for (int i = 0; i < NUM_CAMS; i++) { weights[np + i] = (used_cameras[i] & adjust_lazyeye)? cost_lazyeye : 0.0; // ddisp - including last_camera weights[np + NUM_CAMS + i] = (used_cameras[i] & adjust_lazyeye)? cost_lazyeye : 0.0; // ndisp weights[np + i] = (used_cameras[i] & adjust_lazyeye_par)? cost_lazyeye_par : 0.0; // ddisp - including last_camera weights[np + NUM_CAMS + i] = (used_cameras[i] & adjust_lazyeye_ortho)? cost_lazyeye_odtho : 0.0; // ndisp values [np + i] = 0.0; values [np + NUM_CAMS + i] = 0.0; } Loading Loading @@ -340,6 +369,13 @@ public class Corr2dLMA { pair_weights[i]*=rspw; } } par_map = new int [par_mask.length]; int par_indx = 0; for (int i = 0; i < par_mask.length; i++) { if (par_mask[i]) par_map[i] = par_indx++; else par_map[i] = -1; } toVector(); } Loading Loading @@ -369,6 +405,8 @@ public class Corr2dLMA { double [][] jt) { // should be either [vector.length][samples.size()] or null - then only fx is calculated if (vector == null) return null; double [] av = fromVector(vector); // restoration of the last camera is moved to fromVector() /* // restore ddisp("x") offset for the last camera // prepare parameters common for each camera/camera pair before calculating fx and derivatives av[DDISP_INDEX + last_cam] = 0.0; Loading @@ -377,6 +415,7 @@ public class Corr2dLMA { av[DDISP_INDEX + last_cam] -= av[DDISP_INDEX + i]; } } */ Matrix [] xcam_ycam = new Matrix[NUM_CAMS]; for (int i = 0; i < NUM_CAMS; i++) if (used_cameras[i]) { double [] add_dnd = {av[DISP_INDEX]+ av[DDISP_INDEX + i], av[NDISP_INDEX + i]}; Loading Loading @@ -418,73 +457,106 @@ public class Corr2dLMA { double xmxp_ymyp = xmxp * ymyp; double d = Wp*(1.0 - (A*xmxp2 + 2 * B * xmxp_ymyp + C * ymyp2)); fx[ns] = d * Gp; int np = 0; if (Double.isNaN(fx[ns])) { System.out.println("fx["+ns+"]="+fx[ns]); } // int np = 0; if (jt != null) { if (par_mask[DISP_INDEX]) jt[np++][ns] = 2 * WGp * if (par_map[DISP_INDEX] >= 0) jt[par_map[DISP_INDEX]][ns] = 2 * WGp * ((A * xmxp + B * ymyp) * m_pairs[s.fcam][s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_pairs[s.fcam][s.scam].get(1, 0)); if (par_mask[A_INDEX]) jt[np++][ns] = -WGp*(xmxp2 + ymyp2); if (par_mask[B_INDEX]) jt[np++][ns] = -WGp* 2 * xmxp_ymyp; if (par_mask[CMA_INDEX]) jt[np++][ns] = -WGp* ymyp2; if (par_map[A_INDEX] >= 0) jt[par_map[A_INDEX]][ns] = -WGp*(xmxp2 + ymyp2); if (par_map[B_INDEX] >= 0) jt[par_map[B_INDEX]][ns] = -WGp* 2 * xmxp_ymyp; if (par_map[CMA_INDEX] >= 0) jt[par_map[CMA_INDEX]][ns] = -WGp* ymyp2; for (int p = 0; p < npairs; p++) { // par_mask[G0_INDEX + p] as all pairs either used, or not - then npairs == 0 if (par_mask[G0_INDEX + p]) jt[np++][ns] = (p== pair)? d : 0.0; // (par_mask[G0_INDEX + pair])? d; if (par_map[G0_INDEX + p] >= 0) jt[par_map[G0_INDEX + p]][ns] = (p== pair)? d : 0.0; // (par_mask[G0_INDEX + pair])? d; } // USED_PAIRS_MAP // USED_CAMS_MAP // process ddisp (last camera not used, is equal to minus sum of others to make a sum == 0) for (int f = 0; f < ncam - 1; f++) { // -1 for the last_cam jt[np + USED_CAMS_MAP[f]][ns] = 0.0; // Need to fix for missing parameters // for (int f = 0; f < ncam - 1; f++) if (par_map[DDISP_INDEX + f] >= 0) { // -1 for the last_cam // jt[np + USED_CAMS_MAP[f]][ns] = 0.0; for (int f = 0; f < NUM_CAMS; f++) if (par_map[DDISP_INDEX + f] >= 0) { // -1 for the last_cam jt[par_map[DDISP_INDEX + f]][ns] = 0.0; } if (par_map[DDISP_INDEX + s.fcam] >= 0){ // par_map[DDISP_INDEX + last_cam] always <0 jt[par_map[DDISP_INDEX + s.fcam]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 0)); } else if (s.fcam == last_cam) { for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && (par_map[DDISP_INDEX + c] >=0)) { jt[par_map[DDISP_INDEX + c]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 0)); } } if ((par_mask[DDISP_INDEX + s.fcam] || (s.fcam == last_cam)) && ((par_mask[DDISP_INDEX + s.scam] || (s.scam == last_cam)))) { if (par_map[DDISP_INDEX + s.scam]>= 0){ // par_map[DDISP_INDEX + last_cam] always <0 jt[par_map[DDISP_INDEX + s.scam]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 0)); } else if (s.scam == last_cam) { for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && (par_map[DDISP_INDEX + c] >= 0)) { jt[par_map[DDISP_INDEX + c]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 0)); } } /* if (((par_map[DDISP_INDEX + s.fcam] >= 0) || (s.fcam == last_cam)) && (((par_map[DDISP_INDEX + s.scam]>= 0) || (s.scam == last_cam)))) { if (s.fcam != last_cam) { jt[np + USED_CAMS_MAP[s.fcam]][ns] += 2 * WGp * if (par_map[DDISP_INDEX + s.fcam] >= 0) jt[par_map[DDISP_INDEX + s.fcam]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 0)); } else { // last camera - use all others with minus sign for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && par_mask[DDISP_INDEX + c]) { jt[np + USED_CAMS_MAP[c]][ns] -= 2 * WGp * // ((A * xmxp + B * ymyp) * m_disp[c].get(0, 0)+ // (B * xmxp + C * ymyp) * m_disp[c].get(1, 0)); for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && (par_map[DDISP_INDEX + c] >=0)) { jt[par_map[DDISP_INDEX + c]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 0)); } } if (s.scam != last_cam) { jt[np + USED_CAMS_MAP[s.scam]][ns] -= 2 * WGp * if (par_map[DDISP_INDEX + s.scam] >= 0) jt[par_map[DDISP_INDEX + s.scam]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 0)); } else { for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && par_mask[DDISP_INDEX + c]) { jt[np + USED_CAMS_MAP[c]][ns] += 2 * WGp * // ((A * xmxp + B * ymyp) * m_disp[c].get(0, 0)+ // (B * xmxp + C * ymyp) * m_disp[c].get(1, 0)); for (int c = 0; c < NUM_CAMS; c++) if ((c != last_cam) && (par_map[DDISP_INDEX + c] >= 0)) { jt[par_map[DDISP_INDEX + c]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 0)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 0)); } } } np += ncam -1;// -1 for the last_cam */ // np += ncam -1;// -1 for the last_cam // process ndisp for (int f = 0; f < ncam; f++) { jt[np + USED_CAMS_MAP[f]][ns] = 0.0; for (int f = 0; f < ncam; f++) if (par_map[NDISP_INDEX + f] >= 0) { jt[par_map[NDISP_INDEX + f]][ns] = 0.0; } if (par_mask[NDISP_INDEX + s.fcam] && (par_mask[NDISP_INDEX + s.scam] )) { jt[np + USED_CAMS_MAP[s.fcam]][ns] += 2 * WGp * if (par_map[NDISP_INDEX + s.fcam] >=0){ jt[par_map[NDISP_INDEX + s.fcam]][ns] += 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.fcam].get(0, 1)+ (B * xmxp + C * ymyp) * m_disp[s.fcam].get(1, 1)); jt[np + USED_CAMS_MAP[s.scam]][ns] -= 2 * WGp * } if (par_map[NDISP_INDEX + s.scam] >= 0) { jt[par_map[NDISP_INDEX + s.scam]][ns] -= 2 * WGp * ((A * xmxp + B * ymyp) * m_disp[s.scam].get(0, 1)+ (B * xmxp + C * ymyp) * m_disp[s.scam].get(1, 1)); } np += ncam; // np += ncam; } } int np = 0; // int np = 0; for (int n = 0; n < NUM_CAMS; n++) { // av[DDISP_INDEX +last_cam] is already populated fx[num_samples + n] = av[DDISP_INDEX + n]; fx[num_samples + NUM_CAMS + n] = av[NDISP_INDEX + n]; Loading @@ -492,28 +564,26 @@ public class Corr2dLMA { // and derivatives if (jt != null) { if (par_mask[DISP_INDEX]) np++; if (par_mask[A_INDEX]) np++; if (par_mask[B_INDEX]) np++; if (par_mask[CMA_INDEX]) np++; np+= npairs; // now it points to the ddisp block // if (par_mask[DISP_INDEX]) np++; // if (par_mask[A_INDEX]) np++; // if (par_mask[B_INDEX]) np++; // if (par_mask[CMA_INDEX]) np++; // np+= npairs; // now it points to the ddisp block for (int i = 0; i < NUM_CAMS; i++) { if ((i != last_cam) && par_mask[DDISP_INDEX + i]) { if ((i != last_cam) && (par_map[DDISP_INDEX + i] >= 0)) { for (int j = 0; j < NUM_CAMS; j++) { // j - column jt[np][num_samples + j] = (i==j)? 1.0 : 0.0; jt[par_map[DDISP_INDEX + i]][num_samples + j] = (i==j)? 1.0 : 0.0; } jt[np][num_samples + last_cam] = -1.0; np++; jt[par_map[DDISP_INDEX + i]][num_samples + last_cam] = -1.0; } } // np now points at the first ndisp for (int i = 0; i < NUM_CAMS; i++) { if (par_mask[NDISP_INDEX + i]) { if (par_map[NDISP_INDEX + i] >= 0) { for (int j = 0; j < NUM_CAMS; j++) { // j - column jt[np][num_samples + NUM_CAMS + j] = (i==j)? 1.0 : 0.0; jt[par_map[NDISP_INDEX + i] ][num_samples + NUM_CAMS + j] = (i==j)? 1.0 : 0.0; } } np++; } } return fx; Loading Loading @@ -544,7 +614,8 @@ public class Corr2dLMA { double [] fx = getFx(); if (fx == null) return; for (int i = 0; i < fx.length; i++) { double fx_pos = (fx[i] >= 0)? fx[i]: Double.NaN; // double fx_pos = (fx[i] >= 0)? fx[i]: Double.NaN; double fx_pos = fx[i]; if (i < samples.size()) { s = samples.get(i); System.out.println(String.format("%3d: x=%2d y=%2d v=%9.6f fx=%9.6f w=%9.7f fcam=%1d scam=%1d", i, s.ix, s.iy, s.v, fx_pos, s.w, s.fcam, s.scam)); Loading Loading @@ -605,13 +676,30 @@ public class Corr2dLMA { public void updateFromVector() { // USED in lwir int np = 0; for (int i = 0; i < par_mask.length; i++) if (par_mask[i]) all_pars[i] = vector[np++]; // just for reporting all_pars[DDISP_INDEX + last_cam] = 0.0; for (int i = 0; i < NUM_CAMS; i++) { if (used_cameras[i] & (i != last_cam)) { all_pars[DDISP_INDEX + last_cam] -= all_pars[DDISP_INDEX + i]; } } } public double [] fromVector(double [] vector) { // mix fixed and variable parameters // USED in lwir if ( all_pars == null) return null; double [] ap = all_pars.clone(); int np = 0; for (int i = 0; i < par_mask.length; i++) if (par_mask[i]) ap[i] = vector[np++]; ap[DDISP_INDEX + last_cam] = 0.0; for (int i = 0; i < NUM_CAMS; i++) { if (used_cameras[i] & (i != last_cam)) { ap[DDISP_INDEX + last_cam] -= ap[DDISP_INDEX + i]; } } return ap; } Loading
src/main/java/com/elphel/imagej/tileprocessor/Correlation2d.java +40 −3 Original line number Diff line number Diff line Loading @@ -1755,6 +1755,7 @@ public class Correlation2d { public Corr2dLMA corrLMA2( // USED in lwir ImageDttParameters imgdtt_params, double [][] corr_wnd, // correlation window to save on re-calculation of the window double [] corr_wnd_limited, // correlation window, limited not to be smaller than threshold - used for finding max/convex areas (or null) double [][] corrs, double [][] disp_dist, // per camera disparity matrix as a 1d (linescan order) int pair_mask, // which pairs to process Loading Loading @@ -1791,6 +1792,11 @@ public class Correlation2d { for (int npair = 0; npair < corrs.length; npair++) if ((corrs[npair] != null) && (((pair_mask >> npair) & 1) !=0)){ double[] corr = corrs[npair].clone(); if (corr_wnd_limited != null) { for (int i = 0; i < corr.length; i++) { corr[i] /= corr_wnd_limited[i]; } } if (sigma > 0) { gb.blurDouble(corr, corr_size, corr_size, sigma, sigma, 0.01); } Loading Loading @@ -1853,10 +1859,13 @@ public class Correlation2d { imgdtt_params.lma_adjust_wm, // boolean adjust_width, // adjust width of the maximum - lma_adjust_wm imgdtt_params.lma_adjust_ag, // boolean adjust_scales, // adjust 2D correlation scales - lma_adjust_ag imgdtt_params.lma_adjust_wy, // boolean adjust_ellipse, // allow non-circular correlation maximums lma_adjust_wy imgdtt_params.lma_adjust_wxy, // boolean adjust_lazyeye, // adjust disparity corrections and orthogonal disparities lma_adjust_wxy imgdtt_params.lma_adjust_wxy, // boolean adjust_lazyeye_par, // adjust disparity corrections parallel to disparities lma_adjust_wxy imgdtt_params.lma_adjust_ly1, // boolean adjust_lazyeye_ortho, // adjust disparity corrections orthogonal to disparities lma_adjust_ly1 xcenter, // double disp0, // initial value of disparity imgdtt_params.lma_half_width, // double half_width, // A=1/(half_widh)^2 lma_half_width imgdtt_params.lma_cost_wy // double cost_lazyeye // cost for each of the non-zero disparity corrections and ortho disparity lma_cost_wy imgdtt_params.lma_cost_wy, // double cost_lazyeye_par, // cost for each of the non-zero disparity corrections lma_cost_wy imgdtt_params.lma_cost_wxy // double cost_lazyeye_odtho // cost for each of the non-zero ortho disparity corrections lma_cost_wxy ); lma.setMatrices(disp_dist); lma.initMatrices(); // should be called after initVector and after setMatrices Loading @@ -1864,6 +1873,8 @@ public class Correlation2d { if (debug_level > 1) { System.out.println("Input data:"); lma.printInputDataFx(false); lma.printParams(); } lmaSuccess = lma.runLma( Loading @@ -1886,6 +1897,31 @@ public class Correlation2d { System.out.println("Input data and approximation:"); lma.printInputDataFx(true); } if (debug_graphic && lmaSuccess) { String [] sliceTitles = lma.dbgGetSliceTiles(); (new ShowDoubleFloatArrays()).showArrays( lma.dbgGetSamples(0), corr_size, corr_size, true, "corr_values"+"_x"+tileX+"_y"+tileY, sliceTitles); (new ShowDoubleFloatArrays()).showArrays( lma.dbgGetSamples(1), corr_size, corr_size, true, "corr_weights"+"_x"+tileX+"_y"+tileY, sliceTitles); (new ShowDoubleFloatArrays()).showArrays( lma.dbgGetSamples(2), corr_size, corr_size, true, "corr_fx"+"_x"+tileX+"_y"+tileY, sliceTitles); } return lmaSuccess? lma: null; } Loading Loading @@ -2314,6 +2350,7 @@ public class Correlation2d { * @return cost packed array, corresponding to the input. selected convex points have weight * 1.0, other selected - nc_cost */ public double [] filterConvex(// USED in lwir double [] corr_data, int hwin, Loading
src/main/java/com/elphel/imagej/tileprocessor/ImageDtt.java +52 −3 Original line number Diff line number Diff line Loading @@ -1576,6 +1576,12 @@ public class ImageDtt { final int globalDebugLevel) { final boolean debug_distort= true; // final double [][] debug_offsets = null; // final double [][] debug_offsets = {{0.5, 0.5},{0.0,0.0},{0.0,0.0},{-0.5,-0.5}}; // add to calculated CenterXY for evaluating new LMA // final double [][] debug_offsets = {{ 0.5, 0.5},{ 0.5,-0.5},{-0.5, 0.5},{-0.5,-0.5}}; // add to calculated CenterXY for evaluating new LMA // final double [][] debug_offsets = {{ 0.5, 0.0},{ -0.5, 0.0},{-0.5, 0.0},{ 0.5, 0.0}}; // add to calculated CenterXY for evaluating new LMA // final double [][] debug_offsets = {{ 1.0, 0.0},{ -1.0, 0.0},{-1.0, 0.0},{ 1.0, 0.0}}; // add to calculated CenterXY for evaluating new LMA final double [][] debug_offsets = {{ 0.0, 1.0},{ 0.0, -1.0},{ 0.0, -1.0},{ 0.0, 1.0}}; // add to calculated CenterXY for evaluating new LMA final boolean macro_mode = macro_scale != 1; // correlate tile data instead of the pixel data final int quad = 4; // number of subcameras final int numcol = 3; // number of colors // keep the same, just do not use [0] and [1], [2] - green Loading Loading @@ -1792,6 +1798,18 @@ public class ImageDtt { double [][][][] tcorr_tpartial = null; // [quad][numcol+1][4][8*8] double [] ports_rgb = null; double [][] corr_wnd = (new Corr2dLMA(transform_size, null)).getCorrWnd(); double [] corr_wnd_limited = null; if (imgdtt_params.lma_min_wnd <= 1.0) { corr_wnd_limited = new double [corr_wnd.length * corr_wnd[0].length]; int indx = 0; for (int i = 0; i < corr_wnd.length; i++) { for (int j = 0; j < corr_wnd[i].length; j++) { corr_wnd_limited[indx++] = Math.max(corr_wnd[i][j], imgdtt_params.lma_min_wnd); } } } Correlation2d corr2d = new Correlation2d( imgdtt_params, // ImageDttParameters imgdtt_params, transform_size, // int transform_size, Loading Loading @@ -1834,7 +1852,7 @@ public class ImageDtt { } if (macro_mode){ if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY)) { // before correction if ((globalDebugLevel > -1) && debugTile) { // before correction System.out.println("\nUsing MACRO mode, centerX="+centerX+", centerY="+centerY); } centersXY = geometryCorrection.getPortsCoordinatesIdeal( Loading Loading @@ -1870,13 +1888,33 @@ public class ImageDtt { disparity_array[tileY][tileX] + disparity_corr); } if ((globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)) { if (((globalDebugLevel > 0) || debug_distort) && debugTile) { for (int i = 0; i < quad; i++) { System.out.println("clt_aberrations_quad_corr(): tileX="+tileX+", tileY="+tileY+ " centerX="+centerX+" centerY="+centerY+" disparity="+disparity_array[tileY][tileX]+ " centersXY["+i+"][0]="+centersXY[i][0]+" centersXY["+i+"][1]="+centersXY[i][1]); } } if (debug_distort && debugTile && (debug_offsets != null)) { double [][] debug_offsets_xy = new double [debug_offsets.length][2]; for (int i = 0; i < debug_offsets.length; i++) { debug_offsets_xy[i][0] = disp_dist[i][0] * debug_offsets[i][0] + disp_dist[i][1] * debug_offsets[i][1]; debug_offsets_xy[i][1] = disp_dist[i][2] * debug_offsets[i][0] + disp_dist[i][3] * debug_offsets[i][1]; } for (int i = 0; i < quad; i++) { System.out.println(String.format("%d: {%8.3f, %8.3f}",i,debug_offsets_xy[i][0],debug_offsets_xy[i][1])); } for (int i = 0; i < debug_offsets.length; i++) { centersXY[i][0] += debug_offsets_xy[i][0]; centersXY[i][1] += debug_offsets_xy[i][1]; } for (int i = 0; i < quad; i++) { System.out.println("Corrected clt_aberrations_quad_corr(): tileX="+tileX+", tileY="+tileY+ " centerX="+centerX+" centerY="+centerY+" disparity="+disparity_array[tileY][tileX]+ " centersXY["+i+"][0]="+centersXY[i][0]+" centersXY["+i+"][1]="+centersXY[i][1]); } } if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY)) { // before correction System.out.print(disparity_array[tileY][tileX]+"\t"+ Loading Loading @@ -2305,6 +2343,7 @@ public class ImageDtt { Corr2dLMA lma2 = corr2d.corrLMA2( imgdtt_params, // ImageDttParameters imgdtt_params, corr_wnd, // double [][] corr_wnd, // correlation window to save on re-calculation of the window corr_wnd_limited, // corr_wnd_limited, // correlation window, limited not to be smaller than threshold - used for finding max/convex areas (or null) corrs, // double [][] corrs, disp_dist, imgdtt_params.dbg_pair_mask, // int pair_mask, // which pairs to process Loading @@ -2312,7 +2351,7 @@ public class ImageDtt { 0.5, // double sigma, // low-pass sigma to find maximum (and convex too corr_stat[0], // double xcenter, // preliminary center x in pixels for largest baseline imgdtt_params.ortho_vasw_pwr, // double vasw_pwr, // value as weight to this power, tile_lma_debug_level, // int debug_level, tile_lma_debug_level+2, // int debug_level, tileX, // int tileX, // just for debug output tileY ); // int tileY Loading @@ -2337,6 +2376,16 @@ public class ImageDtt { tileX, // int tileX, // just for debug output tileY ); // int tileY double [] lma_disparity_strength = null; double max_disp_diff_lma = 3.0; if (lma != null) { lma_disparity_strength = lma.getDisparityStrength(); if (Math.abs(lma_disparity_strength[0] - disparity ) > max_disp_diff_lma) { if (globalDebugLevel > -1) { System.out.println("Crazy LMA for tileX="+tileX+", tileY="+tileY+": disparity="+disparity+",lma_disparity_strength[0]="+lma_disparity_strength[0]); } lma = null; } } if (lma != null) { double [] mod_disparity_diff = null; double [][] dir_corr_strength = null; Loading