Commit 92f321f5 authored by Andrey Filippov's avatar Andrey Filippov

fixed old bug, used macro correlation

parent d67d3674
......@@ -141,6 +141,7 @@ public class AlignmentCorrection {
}
ArrayList<Sample> samples_list = selectInfinityTiles(
clt_parameters.fcorr_radius, // final double fcorr_radius,
clt_parameters.fcorr_inf_vert,// final boolean use_vertical,
min_strength,
max_diff,
......@@ -195,33 +196,44 @@ public class AlignmentCorrection {
mismatch_corr_coefficiants, // double [][][] corr,
"");// String prefix)
}
/*
if (disparity_corr_coefficiants == null) {
disparity_corr_coefficiants = mismatch_corr_coefficiants;
if (debugLevel > -1){
System.out.println("infinityCorrection(): using only coefficient increments from infinityMismatchCorrection");
return mismatch_corr_coefficiants;
}
} else {
for (int i = 0; i < disparity_corr_coefficiants.length; i++){
for (int j = 0; j < disparity_corr_coefficiants[i].length; j++){
for (int k = 0; k < disparity_corr_coefficiants[i][j].length; k++){
disparity_corr_coefficiants[i][j][k] += mismatch_corr_coefficiants[i][j][k];
}
}
}
if (debugLevel > -1){
System.out.println("infinityCorrection(): combining coefficient increments from infinityCorrection and infinityMismatchCorrection");
/**
* Discard correction data outside of the center image area
* @param fcorr_radius fraction of the image to use (1.0 - 100%)
* @param tilesX width in tiles
* @param tilesY height in tiles
* @return boolean array in linescan order
*/
public boolean[] getCenterMask(
double fcorr_radius,
int tilesX,
int tilesY)
{
boolean [] mask = new boolean [tilesX * tilesY];
int y0 = (int) (0.5 * tilesY*(1.0 - fcorr_radius));
int y1 = (int) (0.5 * tilesY*(1.0 + fcorr_radius));
int x0 = (int) (0.5 * tilesX*(1.0 - fcorr_radius));
int x1 = (int) (0.5 * tilesX*(1.0 + fcorr_radius));
if (y0 < 0) y0 = 0;
if (y1 > tilesY) y1 = tilesY;
if (x0 < 0) x0 = 0;
if (x1 > tilesX) x1 = tilesX;
for (int ty = y0; ty < y1; ty++){
for (int tx = x0; tx < x1; tx++){
mask[tx + tilesX * ty] = true;
}
}
*/
// }
return mismatch_corr_coefficiants;
return mask;
}
/**
* Select infinity tiles from a single or multiple image sets
* Next parameters are made separate to be able to modify them between different runs keeping clt_parameters
* @param fcorr_radius do not use peripheral tiles
* @param min_strength minimal correlation strength to use tile
* @param max_diff maximal disparity difference between tiles and previous approximation to use tiles
* @param max_iterations maximal number of iterations to find disparity surface
......@@ -236,6 +248,7 @@ public class AlignmentCorrection {
* @return per sub-camera, per direction (x,y) 6 quadratic polynomial coefficients, same format as fine_geometry_correction()
*/
public ArrayList<Sample> selectInfinityTiles(
final double fcorr_radius,
final boolean use_vertical,
final double min_strength,
final double max_diff,
......@@ -250,6 +263,7 @@ public class AlignmentCorrection {
{
final int numTiles = disp_strength[0].length;
final int tilesY = numTiles/tilesX;
final boolean [] center_mask = getCenterMask(fcorr_radius, tilesX, tilesY);
double [] disparity_poly = new double[6];
PolynomialApproximation pa = new PolynomialApproximation();
double thresholdLin = 1.0E-20; // threshold ratio of matrix determinant to norm for linear approximation (det too low - fail)
......@@ -275,7 +289,7 @@ public class AlignmentCorrection {
for (int num_set = 0; num_set < disp_strength.length/NUM_SLICES; num_set++){
int disp_index = NUM_SLICES * num_set;
int str_index = NUM_SLICES * num_set + 1;
for (int nTile = 0; nTile < numTiles; nTile++){
for (int nTile = 0; nTile < numTiles; nTile++) if (center_mask[nTile]){
if ((disp_strength[str_index][nTile] > min_strength) &&
// (Math.abs(disp_strength[disp_index][nTile] - disp_surface[nTile]) < max_diff)){
((disp_strength[disp_index][nTile] - disp_surface[nTile]) < max_diff)){
......@@ -1505,6 +1519,7 @@ public class AlignmentCorrection {
public double [][][] lazyEyeCorrection(
final double fcorr_radius,
final double min_strength_in,
final double max_diff,
// final double comp_strength_var,
......@@ -1538,6 +1553,7 @@ public class AlignmentCorrection {
final int num_scans = scans_14.length/NUM_ALL_SLICES;
final int num_tiles = scans_14[0].length;
final int tilesY = num_tiles/tilesX;
final boolean [] center_mask = getCenterMask(fcorr_radius, tilesX, tilesY);
final double [][] scans = new double [num_scans * NUM_SLICES][];
final int [] indices_14_10 = {0,1,2,3,5,6,8,9,11,12};
final double [][] comp_strength_rms = new double [num_scans][num_tiles];
......@@ -1546,9 +1562,6 @@ public class AlignmentCorrection {
scans[ns * NUM_SLICES + i] = scans_14[ns * NUM_ALL_SLICES + indices_14_10[i]];
}
}
// (new showDoubleFloatArrays()).showArrays(scans_14, tilesX, tilesY, true, "scans14");
// (new showDoubleFloatArrays()).showArrays(scans, tilesX, tilesY, true, "scans10");
for (int ns = 0; ns < num_scans; ns++){
for (int nTile = 0; nTile < num_tiles; nTile++){
......@@ -1563,24 +1576,6 @@ public class AlignmentCorrection {
comp_strength_rms[ns][nTile] = Math.sqrt(s2 - s1*s1);
}
}
/*
for (int ns = 0; ns < num_scans; ns++){
for (int nTile = 0; nTile < num_tiles; nTile++){
double s1=0.0, s2=0.0;
for (int pair = 0; pair <4; pair++){
double s = scans_14[ns * NUM_ALL_SLICES + 4 + 3 * pair][nTile];
if (pair == 0){
s1 = s;
s2 = s;
} else {
s1= Math.min(s, s1);
s2= Math.max(s, s2);
}
}
comp_strength_rms[ns][nTile] = s2 - s1;
}
}
*/
/*
* None of comp_strength_rms methods works to detect potential outliers for horizontal/vertical features
*/
......@@ -1809,6 +1804,7 @@ public class AlignmentCorrection {
// create list for infinity data
ArrayList<Sample> inf_samples_list = selectInfinityTiles(
clt_parameters.fcorr_radius, // final double fcorr_radius,
clt_parameters.fcorr_inf_vert,// final boolean use_vertical,
0.0, // any > 0.0
max_diff, // max_diff, //clt_parameters.fcorr_inf_diff
......@@ -1836,7 +1832,7 @@ public class AlignmentCorrection {
total_weights[0] += s.weight;
}
for (int nTile = 0; nTile < num_tiles; nTile++) {
for (int nTile = 0; nTile < num_tiles; nTile++) if (center_mask[nTile]){
total_weights[1]+= inf_and_ly[1 * NUM_SLICES + 1][nTile];
}
......@@ -1855,7 +1851,7 @@ public class AlignmentCorrection {
}
// Supplement list with the lazy eye scans data - use all tiles
for (int nTile = 0; nTile < num_tiles; nTile++) {
for (int nTile = 0; nTile < num_tiles; nTile++) if (center_mask[nTile]) {
double w = inf_and_ly[1 * NUM_SLICES + 1][nTile];
if (w > 0.0) {
inf_samples_list.add(new Sample(1,nTile,w));
......@@ -2124,6 +2120,7 @@ public class AlignmentCorrection {
ArrayList<Sample> inf_samples_list = selectInfinityTiles(
clt_parameters.fcorr_radius, // final double fcorr_radius,
clt_parameters.fcorr_inf_vert,// final boolean use_vertical,
0.0, // any > 0.0
clt_parameters.fcorr_inf_diff, // max_diff, //clt_parameters.fcorr_inf_diff
......
......@@ -67,6 +67,19 @@ public class CLTPass3d{
{
this.tileProcessor = tileProcessor;
}
public CLTPass3d (TileProcessor tileProcessor, int mode)
{
this.tileProcessor = tileProcessor;
switch (mode){
case 0:
tile_op = new int [tileProcessor.getTilesY()][tileProcessor.getTilesX()];
disparity = new double [tileProcessor.getTilesY()][tileProcessor.getTilesX()];
break;
}
}
public TileProcessor getTileProcessor()
{
return this.tileProcessor;
......
......@@ -633,7 +633,8 @@ public class GeometryCorrection {
double rri = 1.0;
for (int j = 0; j < a.length; j++){
rri *= ri;
rD2rND += a[j]*(rri - a[j]); // BUG here !!!! - fix later, will need to re-adjust all fine corr
// rD2rND += a[j]*(rri - a[j]); // BUG here !!!! - fix later, will need to re-adjust all fine corr
rD2rND += a[j]*(rri - 1.0); // Fixed
}
double pXid = pXci * rD2rND;
double pYid = pYci * rD2rND;
......@@ -672,7 +673,7 @@ public class GeometryCorrection {
double rri = 1.0;
for (int j = 0; j < a.length; j++){
rri *= ri;
rD2rND += a[j]*(rri - a[j]);
rD2rND += a[j]*(rri - 1.0);
}
double pXid = pXci * rD2rND;
double pYid = pYci * rD2rND;
......
......@@ -3606,12 +3606,12 @@ public class ImageDtt {
} else { // copy by 1
for (int i = 0; i < transform_size2; i++){
int pi = ctile_top + i;
if (pi < 0) pi = 0;
else if (pi >= height) pi = height - 1;
if (pi < 0) pi &= 1;
else if (pi >= height) pi = height - 2 + (pi & 1);
for (int j = 0; j < transform_size2; j++){
int pj = ctile_left + j;
if (pj < 0) pj = 0;
else if (pj >= width) pj = width - 1;
if (pj < 0) pj &= 1;
else if (pj >= width) pj = width - 2 + (pj & 1);
tile_in[transform_size2 * i + j] = image_data[chn][pi * width + pj];
}
}
......
......@@ -23,6 +23,12 @@
**
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicInteger;
public class MacroCorrelation {
TileProcessor tp; // pixel tile processor
TileProcessor mtp; // macro tile processor
......@@ -339,7 +345,7 @@ public class MacroCorrelation {
EyesisCorrectionParameters.CLTParameters clt_parameters,
GeometryCorrection geometryCorrection,
final double trustedCorrelation,
final double disp_far, // limit results to the disparity range
final double disp_far, // limit results to the disparity range, far - start with 1 step above 0 (was valid for all)
final double disp_near,
final double minStrength,
final double unique_tolerance,
......@@ -373,7 +379,217 @@ public class MacroCorrelation {
}
public ArrayList <CLTPass3d> prepareMeasurementsFromMacro(
final ArrayList <CLTPass3d> macro_passes, // macro correlation measurements
// in pixels
final double disp_far, // limit results to the disparity range
final double disp_near,
final double minStrength,
final double mc_trust_fin, // = 0.3; // When consolidating macro results, exclude high residual disparity
final double mc_trust_sigma, // = 0.2; // Gaussian sigma to reduce weight of large residual disparity
final double mc_ortho_weight, // = 0.5; // Weight from ortho neighbor supertiles
final double mc_diag_weight, // = 0.25; // Weight from diagonal neighbor supertiles
final double mc_gap, // = 0.4; // Do not remove measurements farther from the kept ones
final boolean usePoly, // use polynomial method to find max), valid if useCombo == false
final boolean sort_disparity, // sort results for increasing disparity (false - decreasing strength)
final int dbg_x,
final int dbg_y,
final int debugLevel)
{
class DispStrength{
double disparity;
double strength;
DispStrength (double disparity, double strength){
this.disparity = disparity;
this.strength = strength;
}
double [] toArray(){
double [] arr = {disparity, strength};
return arr;
}
public String toString(){
return String.format("disparity=%7.3f strength=%7.4f",disparity, strength);
}
}
final int mTilesX = mtp.getTilesX();
final int mTilesY = mtp.getTilesY();
final int mTiles = mTilesX * mTilesY;
final ArrayList <CLTPass3d> measurements = new ArrayList <CLTPass3d>();
final TileNeibs tnSurface = new TileNeibs(mtp.getTilesX(), mtp.getTilesY());
final Thread[] threads = ImageDtt.newThreadArray(tp.threadsMax);
final int [] max_meas = new int [threads.length]; // maximal numer of measurements per tile
final int [] num_meas = new int [threads.length]; // maximal numer of measurements per tile
final AtomicInteger ai_thread = new AtomicInteger(0);
final AtomicInteger ai = new AtomicInteger(0);
final int dbg_tile = dbg_x + dbg_y * mTilesX;
final double [][][] macro_ds = new double [mTiles][][];
final int firstPass = 0;
final int lastPassPlus1 = macro_passes.size();
final int disparity_index = usePoly ? ImageDtt.DISPARITY_INDEX_POLY : ImageDtt.DISPARITY_INDEX_CM;
final double disp_far8 = disp_far/tp.getTileSize(); // here tp, not mtp
final double disp_near8 = disp_near/tp.getTileSize(); // here tp, not mtp
final double corr_magic_scale = mtp.getMagicScale();
//mtp.clt_3d_passes
final double [] neib_weights = {
mc_ortho_weight,
mc_diag_weight,
mc_ortho_weight,
mc_diag_weight,
mc_ortho_weight,
mc_diag_weight,
mc_ortho_weight,
mc_diag_weight,
1.0};
final double kexp = (mc_trust_sigma == 0.0) ? 0.0: (0.5/mc_trust_sigma/mc_trust_sigma);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int this_thread = ai_thread.getAndIncrement();
for (int mTile0 = ai.getAndIncrement(); mTile0 < mTiles; mTile0 = ai.getAndIncrement()) {
int dl = (mTile0 == dbg_tile) ? debugLevel : -1;
if (dl > 0){
System.out.println("prepareMeasurementsFromMacro() mTile0="+mTile0);
}
ArrayList<DispStrength> ds_list = new ArrayList<DispStrength>();
for (int ipass = firstPass; ipass <lastPassPlus1; ipass++ ){
CLTPass3d pass = macro_passes.get(ipass);
if ( pass.isMeasured()) { // current tile has valid data
for (int dir = 0; dir < neib_weights.length; dir++){ // 8 - center
int mTile = tnSurface.getNeibIndex(mTile0, dir);
if ((mTile >= 0) && (neib_weights[dir] != 0.0)) {
int mty = mTile / mTilesX;
int mtx = mTile % mTilesX;
if (pass.tile_op[mty][mtx] != 0 ) { // current tile has valid data
double mdisp = pass.disparity_map[disparity_index][mTile];
double strength = pass.disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX][mTile];
double adiff = Math.abs(mdisp);
if ((strength >= minStrength) && (adiff <= mc_trust_fin)){
double disp = mdisp/corr_magic_scale + pass.disparity[mty][mtx];
if ((disp >= disp_far8) && (disp <= disp_near8)) {
double weight = strength * neib_weights[dir];
if (mc_trust_sigma != 0.0){
weight *= Math.exp(-kexp*mdisp*mdisp);
}
ds_list.add(new DispStrength(disp, weight));
}
}
}
}
}
}
}
// sort by strength copy to new list then remove all that are closer than usePoly, repeat until not empty
Collections.sort(ds_list, new Comparator<DispStrength>() {
@Override
public int compare(DispStrength lhs, DispStrength rhs) {
// descending
return (lhs.strength > rhs.strength) ? -1 : (lhs.strength < rhs.strength) ? 1 : 0;
}
});
ArrayList<DispStrength> ds_list_keep = new ArrayList<DispStrength>();
while (!ds_list.isEmpty()){
DispStrength ds_kept = ds_list.remove(0);
ds_list_keep.add(ds_kept); // move strongest
for (int i = ds_list.size(); i > 0; i--){
DispStrength ds = ds_list.remove(0);
if (Math.abs(ds_kept.disparity-ds.disparity) >= mc_gap){
ds_list.add(ds);
}
}
}
if (!ds_list_keep.isEmpty()){
if (sort_disparity){
Collections.sort(ds_list_keep, new Comparator<DispStrength>() {
@Override
public int compare(DispStrength lhs, DispStrength rhs) {
// ascending
return (lhs.disparity < rhs.disparity) ? -1 : (lhs.disparity > rhs.disparity) ? 1 : 0;
}
});
}
macro_ds[mTile0] = new double[ds_list_keep.size()][];
int indx=0;
for (DispStrength ds:ds_list_keep){
macro_ds[mTile0][indx++] = ds.toArray();
}
if (max_meas[this_thread] < ds_list_keep.size()){
max_meas[this_thread] = ds_list_keep.size();
if (debugLevel > -1){ // (dl > 0){
System.out.println("prepareMeasurementsFromMacro() mTile0="+mTile0+" max_meas["+this_thread+"]="+max_meas[this_thread]);
}
}
num_meas[this_thread] += ds_list_keep.size();
}
}
}
};
}
ImageDtt.startAndJoin(threads);
int longest = 0;
int total_meas = 0;
for (int i = 0; i < max_meas.length; i++){
if (longest < max_meas[i]) {
longest = max_meas[i];
total_meas +=num_meas[i];
}
}
if (debugLevel > -1){
System.out.println("prepareMeasurementsFromMacro(): longest="+longest+" total_meas="+total_meas);
}
int op = ImageDtt.setImgMask(0, 0xf);
op = ImageDtt.setPairMask(op,0xf);
op = ImageDtt.setForcedDisparity(op,true);
final int fop = op;
ai.set(0);
ai_thread.set(0);
for (int i = 0; i < longest; i++){
measurements.add(new CLTPass3d(tp, 0 )); // mode 0 - initialize tile_op and disparity arrays
}
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// int this_thread = ai_thread.getAndIncrement();
int tileSize = tp.getTileSize();
int tilesX = tp.getTilesX();
int tilesY = tp.getTilesY();
for (int mTile = ai.getAndIncrement(); mTile < mTiles; mTile = ai.getAndIncrement()) {
int dl = (mTile == dbg_tile) ? debugLevel : -1;
if (dl > 0){
System.out.println("prepareMeasurementsFromMacro().1 mTile0="+mTile);
}
if (macro_ds[mTile] != null){
int mty = mTile / mTilesX;
int mtx = mTile % mTilesX;
int ty0 = mty * tileSize;
int tx0 = mtx * tileSize;
int ty1 = ty0 + tileSize; if (ty1 > tilesY) ty1 = tilesY;
int tx1 = tx0 + tileSize; if (tx1 > tilesX) tx1 = tilesX;
for (int ipass = 0; ipass < macro_ds[mTile].length;ipass++){
CLTPass3d pass = measurements.get(ipass);
for (int ty = ty0; ty < ty1; ty++){
for (int tx = tx0; tx < tx1; tx++){
pass.tile_op[ty][tx] = fop;
pass.disparity[ty][tx] = macro_ds[mTile][ipass][0]*tileSize;
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return measurements;
}
}
This diff is collapsed.
......@@ -640,11 +640,9 @@ public class TileProcessor {
{
final int dbg_tile = (debugLevel > 0)? 839: -1; // x = 122, y= 108; -1; // 27669;
CLTPass3d combo_pass =new CLTPass3d(this);
final int tlen = tilesX * tilesY;
final int disparity_index = usePoly ? ImageDtt.DISPARITY_INDEX_POLY : ImageDtt.DISPARITY_INDEX_CM;
combo_pass.tile_op = new int [tilesY][tilesX];
combo_pass.disparity = new double [tilesY][tilesX];
// for (int i = 0; i< ImageDtt.QUAD; i++) combo_pass.disparity_map[ImageDtt.IMG_DIFF0_INDEX + i] = new double[tlen];
int op = ImageDtt.setImgMask(0, 0xf);
op = ImageDtt.setPairMask(op,0xf);
op = ImageDtt.setForcedDisparity(op,true);
......@@ -679,7 +677,7 @@ public class TileProcessor {
double disp_low = Math.min(disp, pass.disparity[ty][tx]);
double disp_high = Math.max(disp, pass.disparity[ty][tx]);
// if ((disp_high - disp_low) > 2 * unique_tolerance) { // suggested correction is not too small
if ((disp_high - disp_low) > unique_tolerance) { // suggested correction is not too small
if ((disp_high - disp_low) >= unique_tolerance) { // suggested correction is not too small
boolean duplicate = false;
for (int iother = firstPass; iother <lastPassPlus1; iother++ ) {
CLTPass3d other = passes.get(iother);
......@@ -714,8 +712,6 @@ public class TileProcessor {
/**
* Verify that selected points are not all on the same line
* @param sel 2-d sample selection in linescan order
......@@ -7357,7 +7353,8 @@ public class TileProcessor {
for (int x = 0; (x < width) && (indx <= maxIndex); x++){
if (indices[y][x] >=0){
// center coordinates for 8*8 tile is [3.5,3.5]
double disp = disparity[(bounds.y + y) * tilesX + (bounds.x + x)];
// double disp = disparity[(bounds.y + y) * tilesX + (bounds.x + x)];
double disp = (disparity == null)? min_disparity:( disparity[(bounds.y + y) * tilesX + (bounds.x + x)]);
if (disp < min_disparity) disp = min_disparity;
else if (disp > max_disparity) disp = max_disparity;
indexedDisparity[indx] =disp;
......@@ -7370,7 +7367,7 @@ public class TileProcessor {
public double [][] getCoords( // get world XYZ in meters for indices
double [] disparity,
double [] disparity, // null - use min_disparity
double min_disparity,
double max_disparity,
Rectangle bounds,
......@@ -7390,7 +7387,7 @@ public class TileProcessor {
// center coordinates for 8*8 tile is [3.5,3.5]
double px = (bounds.x + x + 0.5) * tile_size - 0.5;
double py = (bounds.y + y + 0.5) * tile_size - 0.5;
double disp = disparity[(bounds.y + y) * tilesX + (bounds.x + x)];
double disp = (disparity == null)? min_disparity:( disparity[(bounds.y + y) * tilesX + (bounds.x + x)]);
if (disp < min_disparity) disp = min_disparity;
else if (disp > max_disparity) disp = max_disparity;
coordinate[indx] = geometryCorrection.getWorldCoordinates(
......@@ -7528,7 +7525,7 @@ public class TileProcessor {
String [] titles = {"disparity","triangles"};
double [][] dbg_img = new double [titles.length][tilesX*tilesY*tile_size*tile_size];
for (int i = 0; i < selected.length; i++ ){
double d = selected[i]?disparity[i]:Double.NaN;
double d = selected[i]? ((disparity.length >1) ? disparity[i] : disparity[0]):Double.NaN;
int y = i / tilesX;
int x = i % tilesX;
for (int dy = 0; dy <tile_size; dy ++){
......
......@@ -64,7 +64,7 @@ public class X3dOutput {
this.clt_3d_passes = clt_3d_passes;
}
// init document, bounding box, backdrop
public void generateBackground()
public void generateBackground(boolean use_backdrop)
{
try {
......@@ -98,6 +98,7 @@ public class X3dOutput {
Element el_Bgnd = x3dDoc.createElement("Background");
el_Bgnd.setAttribute("class","Background");
el_Bgnd.setAttribute("id", "Background");
if (use_backdrop) {
el_Bgnd.setAttribute("frontUrl", bgnd_pass.texture);
// temporarily - add same picture to all other sides. Actually - any square will work, make some
// perspective grids/ colors to simplify orientation when looking wrong way
......@@ -106,6 +107,7 @@ public class X3dOutput {
el_Bgnd.setAttribute("rightUrl", bgnd_pass.texture);
el_Bgnd.setAttribute("topUrl", bgnd_pass.texture);
el_Bgnd.setAttribute("bottomUrl", bgnd_pass.texture);
}
el_Scene.appendChild(el_Bgnd);
}
......
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