Commit a70e08ac authored by Andrey Filippov's avatar Andrey Filippov

extracted classes to separate files

parent 53042eb0
/**
**
** CLTPass3d - A single processing "pass" over the image set. May be both actual
** FPGA operation or result of merging data from multiple passes
**
** Copyright (C) 2017 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** CLTPass3d.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
import java.awt.Rectangle;
import java.util.concurrent.atomic.AtomicInteger;
public class CLTPass3d{
public double [][] disparity; // per-tile disparity set for the pass[tileY][tileX]
public int [][] tile_op; // what was done in the current pass
public double [][] disparity_map = null; // add 4 layers - worst difference for the port
double [] calc_disparity = null; // composite disparity, calculated from "disparity", and "disparity_map" fields
// using horizontal features and corr_magic_scale
// used directly in TileProcessor.compositeScan()
double [] calc_disparity_hor = null; // composite disparity, calculated from "disparity", and "disparity_map" fields
double [] calc_disparity_vert = null; // composite disparity, calculated from "disparity", and "disparity_map" fields
double [] calc_disparity_combo = null; // composite disparity, calculated from "disparity", and "disparity_map" fields
double [] strength = null; // composite strength, initially uses a copy of raw 4-sensor correleation strength
double [] strength_hor = null; // updated hor strength, initially uses a copy of raw measured
double [] strength_vert = null; // updated hor strength, initially uses a copy of raw measured
// Bg disparity & strength is calculated from the supertiles and used instead of the tile disparity if it is too weak. Assuming, that
// foreground features should have good correlation details, and if the tile does not nhave them it likely belongs to the background.
// calculate disparity and strength from the (lapped) supertiles, using lowest allowed (>= minBgDisparity) disparity histogram maximums
// of the supertiles this tile belongs to
private double minBgDisparity = 0.0;
private double minBgFract = 0.0; // Use the lowest maximum if the strength strength (of all maximus >= minBgDisparity)
// exceeds minBgFract, otherwise proceed to the next one (and accumulate strength)
private double [] bgTileDisparity = null;
private double [] bgTileStrength = null;
public boolean [] border_tiles = null; // these are border tiles, zero out alpha
public boolean [] selected = null; // which tiles are selected for this layer
public double [][][][] texture_tiles;
public double [][] max_tried_disparity = null; //[ty][tx] used for combined passes, shows maximal disparity wor this tile, regardless of results
public boolean is_combo = false;
public boolean is_measured = false;
public String texture = null; // relative (to x3d) path
public Rectangle bounds;
public int dbg_index;
public int disparity_index = ImageDtt.DISPARITY_INDEX_CM; // may also be ImageDtt.DISPARITY_INDEX_POLY
SuperTiles superTiles = null;
TileProcessor tileProcessor;
public CLTPass3d (TileProcessor tileProcessor)
{
this.tileProcessor = tileProcessor;
}
public TileProcessor getTileProcessor()
{
return this.tileProcessor;
}
public void updateSelection(){ // add updating border tiles?
int tilesX = tileProcessor.getTilesX();
int tilesY = tileProcessor.getTilesY();
selected = new boolean[tilesY*tilesX];
int minX = tilesX, minY = tilesY, maxX = -1, maxY = -1;
for (int ty = 0; ty < tilesY; ty++) for (int tx = 0; tx < tilesX; tx++){
if (texture_tiles[ty][tx] != null) {
selected[ty * tilesX + tx] = true;
if (maxX < tx) maxX = tx;
if (minX > tx) minX = tx;
if (maxY < ty) maxY = ty;
if (minY > ty) minY = ty;
} else {
selected[ty * tilesX + tx] = false; // may be omitted
}
}
bounds = new Rectangle(minX, minY, maxX - minX +1, maxY - minY +1 );
}
public boolean isProcessed(){
return calc_disparity != null;
}
public boolean isMeasured(){
return is_measured;
// return (disparity_map != null) && (disparity != null); // disparity == null for composite scans
}
public boolean isCombo(){
return is_combo;
}
/**
* Called after each measurement
*/
public void resetProcessed(){
fixNaNDisparity();
calc_disparity = null; // composite disparity, calculated from "disparity", and "disparity_map" fields
calc_disparity_hor = null; // composite disparity, calculated from "disparity", and "disparity_map" fields
calc_disparity_vert = null; // composite disparity, calculated from "disparity", and "disparity_map" fields
calc_disparity_combo = null; // composite disparity, calculated from "disparity", and "disparity_map" fields
strength = null; // composite strength, initially uses a copy of raw 4-sensor correleation strength
strength_hor = null; // updated hor strength, initially uses a copy of raw measured
strength_vert = null; // updated hor strength, initially uses a copy of raw measured
bgTileDisparity = null;
bgTileStrength = null;
// border_tiles = null; // these are border tiles, zero out alpha
// selected = null; // which tiles are selected for this layer
superTiles = null;
}
/**
* Get FPGA-calculated per-tile maximal differences between the particular image and the average one.
* @return per-camera sesnor array of line-scan differences
*/
public double [][] getDiffs (){
double [][] these_diffs = new double[ImageDtt.QUAD][];
for (int i = 0; i< ImageDtt.QUAD; i++) these_diffs[i] = disparity_map[ImageDtt.IMG_DIFF0_INDEX + i];
return these_diffs;
}
public void resetCalc(){ // only needed if the same task was reused
calc_disparity = null;
strength = null;
strength_hor = null;
strength_vert = null;
superTiles = null;
}
public boolean [] getSelected(){
return selected;
}
public void fixNaNDisparity()
{
fixNaNDisparity(
null,
disparity_map[disparity_index],
disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX]);
fixNaNDisparity(
null,
disparity_map[ImageDtt.DISPARITY_INDEX_HOR],
disparity_map[ImageDtt.DISPARITY_INDEX_HOR_STRENGTH]);
fixNaNDisparity(
null,
disparity_map[ImageDtt.DISPARITY_INDEX_VERT],
disparity_map[ImageDtt.DISPARITY_INDEX_VERT_STRENGTH]);
}
public void fixNaNDisparity(
boolean [] select, // which tiles to correct (null - all)
double [] disparity,
double [] strength)
{
// depends on direction, but that is OK - just converge faster when smoothing
int tilesX = tileProcessor.getTilesX();
int tilesY = tileProcessor.getTilesY();
int [] dirs8 = {-tilesX, -tilesX + 1, 1, tilesX +1, tilesX, tilesX - 1, -1, -tilesX - 1};
for (int ty = 1; ty < (tilesY -1); ty ++) for (int tx = 1; tx < (tilesX -1); tx++){
int nt = ty * tilesX + tx;
if (Double.isNaN(disparity[nt]) && ((select == null) || select[nt])) {
if (strength != null) strength[nt] = 0.0;
double sd = 0.0, sw = 0.0;
for (int dir=0; dir < dirs8.length; dir++){
int nt1 = nt + dirs8[dir];
// if (!Double.isNaN(disparity[nt1]) && ((select == null) || !select[nt1])) {
if (!Double.isNaN(disparity[nt1])) { // for wide borders - use neighbors already defined too
double w = (strength == null) ? 1.0 : strength[nt1];
sd += w * disparity[nt1];
sw += w;
}
}
if (sw > 0.0) sd /= sw;
disparity[nt] = sd;
}
}
// on top/bottom/right/left rows replace NaN disparity with 0.0;
for (int ty = 0; ty < tilesY; ty ++) {
int nt = ty * tilesX + 0;
if (Double.isNaN(disparity[nt]) && ((select == null) || select[nt])) {
if (strength != null) strength[nt] = 0.0;
disparity[nt] = 0.0;
}
nt = ty * tilesX + tilesX -1;
if (Double.isNaN(disparity[nt]) && ((select == null) || select[nt])) {
if (strength != null) strength[nt] = 0.0;
disparity[nt] = 0.0;
}
}
for (int tx = 0; tx < tilesX; tx ++) {
int nt = 0 * tilesX + tx;
if (Double.isNaN(disparity[nt]) && ((select == null) || select[nt])) {
if (strength != null) strength[nt] = 0.0;
disparity[nt] = 0.0;
}
nt = (tilesY -1) * tilesX + tx;
if (Double.isNaN(disparity[nt]) && ((select == null) || select[nt])) {
if (strength != null) strength[nt] = 0.0;
disparity[nt] = 0.0;
}
}
}
public double [] combineHorVertStrength(
boolean combineHor,
boolean combineVert)
{
getStrength(); // clone if not done yet
if (combineHor){
double [] hstrength = getHorStrength();
for (int i = 0; i < strength.length; i++) {
if (strength[i] < hstrength[i]) strength[i] = hstrength[i];
}
}
if (combineVert){
double [] vstrength = getVertStrength();
for (int i = 0; i < strength.length; i++) {
if (strength[i] < vstrength[i]) strength[i] = vstrength[i];
}
}
return strength;
}
public double [] combineSuper(
boolean updateStrength, // use ST strength if true, keep original (update disparity only) if false
double stStrengthScale,
double useSuper){
if (bgTileDisparity == null) { // no supertile disparity is available
return null;
}
double [] strength = getStrength();
double [] disparity = getDisparity(0);
for (int i = 0; i < disparity.length; i++){
if (strength[i] < useSuper) {
disparity[i] = bgTileDisparity[i];
if (updateStrength) strength[i] = stStrengthScale*bgTileStrength[i];
}
}
return disparity;
}
/**
* Returns per-tile correlation "strength". Initially - copy of the FPGA-generated data, b ut later may be replaced by a combination
* of the combined data from 4-sensor (4-pair) correlation and horizontal/vertical pairs only to improve detection of vertical/
* horizontal features
* @return line-scan array of per-tile correlation strength by reference (not a copy), so it can be modified
*/
public double [] getStrength(){
double trustedCorrelation = tileProcessor.getTrustedCorrelation();
if (strength == null){
strength = disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX].clone();
if (trustedCorrelation > 0.0){
for (int i = 0; i < strength.length; i++){
if (Math.abs(disparity_map[disparity_index][i]) > trustedCorrelation) strength[i] = 0.0; // too far
}
}
}
return strength;
}
/**
* Get four pairs (original) correlation strength. Not a copy
* @return line-scan array of per-tile horizontal pairs correlation strength by reference (not a copy)
*/
public double [] getOriginalStrength(){
return disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX];
}
/**
* Get horizontal pairs correlation strength for vertical features. Not a copy
* @return line-scan array of per-tile horizontal pairs correlation strength by reference (not a copy)
*/
public double [] getHorStrength(){
double trustedCorrelation = tileProcessor.getTrustedCorrelation();
if (strength_hor == null) {
strength_hor = disparity_map[ImageDtt.DISPARITY_INDEX_HOR_STRENGTH].clone();
if (trustedCorrelation > 0.0){
for (int i = 0; i < strength_hor.length; i++){
if (Math.abs(disparity_map[ImageDtt.DISPARITY_INDEX_HOR][i]) > trustedCorrelation) strength_hor[i] = 0.0; // too far
}
}
}
return strength_hor;
}
/**
* Get veriical pairs correlation strength for horizontal features. Not a copy
* @return line-scan array of per-tile horizontal pairs correlation strength by reference (not a copy)
*/
public double [] getVertStrength(){
double trustedCorrelation = tileProcessor.getTrustedCorrelation();
if (strength_vert == null) {
strength_vert = disparity_map[ImageDtt.DISPARITY_INDEX_VERT_STRENGTH].clone();
if (trustedCorrelation > 0.0){
for (int i = 0; i < strength_vert.length; i++){
if (Math.abs(disparity_map[ImageDtt.DISPARITY_INDEX_VERT][i]) > trustedCorrelation) strength_vert[i] = 0.0; // too far
}
}
}
return strength_vert;
}
/**
* Get Get combine per-tile disparity values from correlation combined with pre-programmed initial disparity shift.
* @return line-scan array of per-tile disparity by reference (not a copy), so it can be modified
*/
public double [] getDisparity() // get calculated combo disparity
{
return getDisparity(0);
}
/**
* Get one of the line-scan per-tile correlation data.
* @param mode 0 - final data (initially copy FPGA generated 4-pair correation)
* 1 - original FPGA generated 4-sensor correlation
* 2 - 2 - horizontal pairs correlation, detecting vertical features
* 3 - 2 - vertical pairs correlation, detecting horizontal features
* @return line-scan array of per-tile disparity by reference (not a copy), so it can be modified
*/
public double [] getDisparity(int mode) // mode = 0 - normal disparity, 1 - hor, 2 - vert
{
if (calc_disparity == null) conditionDisparity();
switch (mode) {
case 1: return calc_disparity;
case 2: return calc_disparity_hor;
case 3: return calc_disparity_vert;
default: if (calc_disparity_combo == null) calc_disparity_combo = calc_disparity.clone();
return calc_disparity_combo;
}
}
// methods to "condition" measured disparity values
public void conditionDisparity()
{
conditionDisparity(disparity_index);
}
public void conditionDisparity(int disparity_index)
{
int tilesX = tileProcessor.getTilesX();
int tilesY = tileProcessor.getTilesY();
double corr_magic_scale = tileProcessor.getMagicScale();
this.disparity_index = disparity_index;
calc_disparity = new double[tilesY*tilesX];
calc_disparity_hor = new double[tilesY*tilesX];
calc_disparity_vert = new double[tilesY*tilesX];
for (int i = 0; i < tilesY; i++){
for (int j = 0; j < tilesX; j++){
int indx = i * tilesX + j;
calc_disparity[indx] = disparity_map[disparity_index][indx]/corr_magic_scale + this.disparity[i][j];
calc_disparity_hor[indx] = disparity_map[ImageDtt.DISPARITY_INDEX_HOR][indx]/corr_magic_scale + this.disparity[i][j];
calc_disparity_vert[indx] = disparity_map[ImageDtt.DISPARITY_INDEX_VERT][indx]/corr_magic_scale + this.disparity[i][j];
}
}
calc_disparity_combo = calc_disparity.clone(); // for now - just clone, can be modified separately and combined with hor/vert
}
/**
* Replaces current combo disparity for tiles that are weak and do not have any neighbor within disparity range from this one
* @param selection optional boolean mask of tiles to use/update
* @param weakStrength maximal strength of the tile to be considered weak one
* @param maxDiff maximal difference from the most similar neighbor to be considered an outlayer
* @param disparityFar minimal acceptable disparity for weak tiles
* @param disparityNear maximal acceptable disparity for weak tiles
* @return mask of weak (replaced) tiles
*
* Replace weak by a weighted average of non-weak. If there are none - use weak ones, including this one too.
*/
public boolean[] replaceWeakOutlayers(
final boolean [] selection,
final double weakStrength, // strength to be considered weak, subject to this replacement
final double maxDiff,
final double maxDiffPos, // Replace weak outlayer tiles that have higher disparity than weighted average
final double maxDiffNeg, // Replace weak outlayer tiles that have lower disparity than weighted average
final double disparityFar,
final double disparityNear,
final int debugLevel)
{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int nTiles = tilesX*tilesY;
final boolean [] weakOutlayers = new boolean [nTiles];
int [] dirs8 = {-tilesX, -tilesX + 1, 1, tilesX +1, tilesX, tilesX - 1, -1, -tilesX - 1};
final int [] dirs = dirs8;
final double [] disparity = getDisparity(0);
final double [] strength = getStrength();
final double absMinDisparity = 0.5 * disparityFar; // adjust? below this is definitely wrong (weak)
final double absMaxDisparity = 1.5 * disparityNear; // change?
final int dbg_nTile = (debugLevel > 0) ? 43493: -1; // x=77,y=134; // 42228; // x = 108, y = 130 46462; // 41545;
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
// first pass = find outlayers
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
if (((strength[nTile] < weakStrength) ||
(disparity[nTile] < absMinDisparity) ||
(disparity[nTile] > absMaxDisparity))&& ((selection == null) || selection[nTile])) {
if (nTile == dbg_nTile){
System.out.println("replaceWeakOutlayers():1 nTile="+nTile);
}
double [] dbg_disparity = disparity;
double dbg_disparity_nTile = disparity[nTile];
double dbg_disparityFar = disparityFar;
double dbg_disparityNear = disparityNear;
boolean [] dbg_weakOutlayers = weakOutlayers;
int tileY = nTile / tilesX;
int tileX = nTile % tilesX;
if ((tileY > 0) && (tileY < (tilesY -1)) &&(tileX > 0) && (tileX < (tilesX -1))){ // disregard outer row/cols
weakOutlayers[nTile] = true;
boolean hasNeighbors = false;
double sd = 0.0, sw = 0.0;
for (int dir = 0; dir< dirs.length; dir++){
int nTile1 = nTile + dirs[dir];
double dbg_disparity_nTile1 = disparity[nTile1];
if (((selection == null) || selection[nTile1]) &&
(disparity[nTile1] >= disparityFar) && // don't count on too near/too far for averaging
(disparity[nTile1] <= disparityNear)){
double w = strength[nTile1];
sw += w;
sd += w * disparity[nTile1];
hasNeighbors = true;
if (Math.abs(disparity[nTile]-disparity[nTile1]) <= maxDiff){ // any outlayer - will be false
weakOutlayers[nTile] = false;
// break;
}
}
}
if (sw >= 0.0) {
sd /= sw;
if (disparity[nTile] < (sd - maxDiffNeg)) weakOutlayers[nTile] = true;
else if (disparity[nTile] > (sd + maxDiffPos)) weakOutlayers[nTile] = true;
}
if (disparity[nTile] < disparityFar) weakOutlayers[nTile] = true;
if (disparity[nTile] > disparityNear) weakOutlayers[nTile] = true;
if (!hasNeighbors) {
weakOutlayers[nTile] = false; // lone tile or NaN among NaNs
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
// second pass - replace outlayers
final double [] src_disparity = disparity.clone();
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
if (nTile == dbg_nTile){
System.out.println("replaceWeakOutlayers():2 nTile="+nTile);
}
if (weakOutlayers[nTile]) {
double sw = 0.0, sd = 0.0;
for (int dir = 0; dir< dirs.length; dir++){
int nTile1 = nTile + dirs[dir];
if (!weakOutlayers[nTile1] && ((selection == null) || selection[nTile1 ]) ) {
double w = strength[nTile1];
sw += w;
sd += w * src_disparity[nTile1];
}
}
if (sw == 0) { // Nothing strong around - repeat with weak and this one too.
double w = strength[nTile];
if (!Double.isNaN( src_disparity[nTile])) {
sw += w;
sd += w * src_disparity[nTile];
}
for (int dir = 0; dir< dirs.length; dir++){
int nTile1 = nTile + dirs[dir];
if ((selection == null) || selection[nTile1 ]) {
w = strength[nTile1];
if (!Double.isNaN( src_disparity[nTile1])) {
sw += w;
sd += w * src_disparity[nTile1];
}
}
}
}
if (sw > 0) { // should be, do nothing if not
disparity[nTile] = sd/sw;
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return weakOutlayers;
}
public void setSuperTiles(
double step_near,
double step_far,
double step_threshold,
double min_disparity,
double max_disparity,
double strength_floor,
double strength_pow,
double stBlurSigma)
{
this.superTiles = new SuperTiles(
this,
step_near,
step_far,
step_threshold,
min_disparity,
max_disparity,
strength_floor,
strength_pow,
stBlurSigma);
}
public double [] showDisparityHistogram()
{
if (this.superTiles == null){
return null;
}
return this.superTiles.showDisparityHistogram();
}
public double [] showDisparityHistogram(double [][] dispHist)
{
if (this.superTiles == null){
return null;
}
return this.superTiles.showDisparityHistogram(dispHist);
}
public int showDisparityHistogramWidth()
{
return this.superTiles.showDisparityHistogramWidth();
}
public double [][][] getMaxMinMax(){
if (this.superTiles == null){
return null;
}
return superTiles.getMaxMinMax();
}
public double [] showMaxMinMax(){
if (this.superTiles == null){
return null;
}
return this.superTiles.showMaxMinMax();
}
public int getNumBins(){
if (this.superTiles == null){
return 0;
}
return superTiles.numBins;
}
public double[] getSuperTileStrength()
{
if (this.superTiles == null){
return null;
}
return superTiles.stStrength;
}
public double [][] getBgDispStrength()
{
if ((bgTileDisparity == null) || (bgTileStrength == null)){
double [][] rslt = {bgTileDisparity,bgTileStrength};
return rslt;
}
return getBgDispStrength(
this.minBgDisparity,
this.minBgFract);
}
public double [][] getBgDispStrength(
final double minBgDisparity,
final double minBgFract)
{
if (superTiles == null){
return null;
}
if ((minBgDisparity != this.minBgDisparity) || (minBgFract != this.minBgFract)){
this.minBgDisparity = minBgDisparity;
this.minBgFract = minBgFract;
superTiles.bgDisparity = null; // per super-tile
superTiles.bgStrength = null; // per super-tile
bgTileDisparity = null; // per tile
bgTileStrength = null; // per tile
}
if ((superTiles.bgDisparity == null) || (superTiles.bgStrength == null)){
if (superTiles.getBgDispStrength(
minBgDisparity,
minBgFract) == null) {
superTiles.bgDisparity = null; // per super-tile
superTiles.bgStrength = null; // per super-tile
bgTileDisparity = null; // per tile
bgTileStrength = null; // per tile
return null; // failed
}
// now lap-combine supertiles, get this.* from superTiles.*
double [][] bgTileDispStrength = superTiles.getBgTileDispStrength();
bgTileDisparity = bgTileDispStrength[0];
bgTileStrength = bgTileDispStrength[1];
}
double [][] rslt = {bgTileDisparity,bgTileStrength};
return rslt;
}
public double [] getBgDisparity(){
return bgTileDisparity;
}
public double [] getBgStrength(){
return bgTileStrength;
}
} // end of class CLTPass3d
......@@ -257,6 +257,7 @@ public class DisparityProcessor {
final int threadsMax, // maximal number of threads to launch
final int debugLevel)
{
final int dbg_tile = -1; // 28643; // x=131, y=88
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
......@@ -299,11 +300,16 @@ public class DisparityProcessor {
final double [][] disp_data = {disparity, disparity.clone()};
// neighbors
final double [][] dbg_pull = new double [3][len];
if (debugLevel > 0) {
System.out.println("smoothDisparity()");
}
for (int pass = 0; (pass < num_passes) || (num_passes ==0); pass++) {
final int dbg_pass = pass;
System.arraycopy(zero_diffs, 0, rslt_diffs, 0, numThreads); // set all to 0
ai.set(0);
ai_numThread.set(0);
final int dbg_fpass = pass;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
......@@ -318,21 +324,38 @@ public class DisparityProcessor {
double [] dbg_disp_data = disp_data[0];
boolean [] dbg_selected = selected;
boolean [] dbg_border = border;
int [] dbg_neighbors = neighbors;
double neib_avg = 0.0, neib_weight = 0.0;
// if (tileY == 89){
// System.out.println("smoothDisparity() c: tileY="+tileY+", tileX="+tileX+" nTile="+nTile);
// }
if ((debugLevel > 0) &&(nTile == dbg_tile)) {
System.out.println("smoothDisparity() nTile = "+nTile+" tileX="+tileX+" tileY="+tileY);
}
for (int i = 0; i < dirs8.length; i++) if ((neighbors[nTile] & (1 << i)) !=0) {
double w = rigid8[i]; // no strength here strength[nTile + dirs8[i]]
int dbg_dirs8 = nTile + dirs8[i];
double dbg_d = disp_data[0][nTile + dirs8[i]];
if ((debugLevel > 0) &&(nTile == dbg_tile)) {
System.out.println("smoothDisparity(), neib_avg = "+neib_avg+", neib_weight="+neib_weight);
}
neib_weight += w;
neib_avg += w * disp_data[0][nTile + dirs8[i]];
int dbg_pass = dbg_fpass;
// if (((debugLevel > 0) &&(nTile == dbg_tile)) ||Double.isNaN(disp_data[0][nTile + dirs8[i]])) {
if (Double.isNaN(disp_data[0][nTile + dirs8[i]])) {
System.out.println("nTile="+nTile+": smoothDisparity(),dirs8["+i+"]="+ dirs8[i]+", disp_data[0]["+(nTile + dirs8[i])+"]="+disp_data[0][nTile + dirs8[i]]+", pass="+dbg_pass);
}
// if (nTile == 28967){// (tileY == 89) { // (nTile == 28964){
// System.out.println("smoothDisparity() c1: i = "+i+" w="+w+" dbg_dirs8="+dbg_dirs8+" dbg_d="+dbg_d);
// }
}
double new_disp = disp_data[0][nTile];
if ((debugLevel > 0) &&(nTile == dbg_tile)) {
System.out.println("smoothDisparity(), neib_avg = "+neib_avg+", neib_weight="+neib_weight);
}
if (neib_weight > 0.0){
neib_avg/= neib_weight;
// if (nTile == 28967){// (tileY == 89) { // (nTile == 28964){
......@@ -382,6 +405,9 @@ public class DisparityProcessor {
double [] tmp= disp_data[0]; // swap, new data will be in disp_data[0], disp_data[1] to be written to by threads in next run
disp_data[0] = disp_data[1];
disp_data[1] = tmp;
// if ((debugLevel > 0) && (dbg_tile >= 0)) {
// System.out.println("smoothDisparity() pass="+pass+", disp_data[0]["+dbg_tile+"] = "+disp_data[0][dbg_tile]+" disp_data[1]["+dbg_tile+"] = "+disp_data[1][dbg_tile]);
// }
if (maxDiff > 0){
double diff = 0.0;
......@@ -442,6 +468,7 @@ public class DisparityProcessor {
{
// showDoubleFloatArrays sdfa_instance = null;
// if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
final int dbg_tile = (debugLevel > -1) ? 27991 : -1; // x = 127, y = 86
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final int numThreads = threads.length;
if (debugLevel > -1) System.out.println("breakDisparity3(): using "+numThreads+" threads");
......@@ -480,6 +507,9 @@ public class DisparityProcessor {
// try break horizontally (always - to the right)
int b = (1 << 2); // "E" (right)
int rb = (1 << 6); // "W" (left)
if (nTile == dbg_tile) {
System.out.println("breakDisparity{}: nTile = "+nTile);
}
if ((neib & b) != 0){
hor_label:
{
......@@ -499,6 +529,10 @@ public class DisparityProcessor {
deriv *= Math.abs(disparity[nTile + 1]- disparity[nTile]); // 2-nd derivative * abs(1-st derivative)
default: // do nothing
}
double disp_avg = 0.5*(disparity[nTile + 1] + disparity[nTile]);
if ((clt_parameters.tiBreakNorm > 0.0) && (disp_avg > clt_parameters.tiBreakNorm )){
deriv *= clt_parameters.tiBreakNorm / disp_avg;
}
deriv3HV[0][nTile] = deriv;
}
}
......@@ -524,6 +558,11 @@ public class DisparityProcessor {
deriv *= Math.abs(disparity[nTile + tilesX]- disparity[nTile]); // 2-nd derivative * abs(1-st derivative)
default: // do nothing
}
double disp_avg = 0.5*(disparity[nTile + tilesX] + disparity[nTile]);
if ((clt_parameters.tiBreakNorm > 0.0) && (disp_avg > clt_parameters.tiBreakNorm )){
deriv *= clt_parameters.tiBreakNorm / disp_avg;
}
deriv3HV[1][nTile] = deriv; // vertical 4-th derivative
}
}
......@@ -543,6 +582,9 @@ public class DisparityProcessor {
int nTile = indices[iTile];
int tileY = nTile/tilesX;
int tileX = nTile - (tileY * tilesX);
if (nTile == dbg_tile) {
System.out.println("breakDisparity{}: nTile = "+nTile);
}
if (k_same !=0 ) {
// vertical "gradient" in the same horizontal row
if ((tileX > 0) && selected[nTile - 1]) deriv3HV[1][nTile] += k_same * deriv3HVCopy[1][nTile - 1];
......
......@@ -1978,6 +1978,7 @@ public class EyesisCorrectionParameters {
public double min_agree = 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
public boolean dust_remove = true; // Do not reduce average weight when only one image differes much from the average
public boolean black_back = true; // use Black for backdrop outside of the FOV
public boolean keep_weights = true; // add port weights to RGBA stack (debug feature)
public boolean sharp_alpha = false; // combining mode for alpha channel: false - treat as RGB, true - apply center 8x8 only
public double alpha0 = 0.6; // > .525 Alpha channel 0.0 thereshold (lower - transparent) (watch for far objects)
......@@ -2031,6 +2032,7 @@ public class EyesisCorrectionParameters {
public int bgnd_grow = 2; // number of tiles to grow (1 - hor/vert, 2 - hor/vert/diagonal)
// public double ortho_min = 0.09; // minimal strength of hor/vert correlation to be used instead of full 4-pair correlation
public boolean ortho_old = false; // use old ortho features processing (orth0_* parameters, false - use or_*)
public double ortho_min_hor = 0.07; // minimal strength of hor correlation to be used instead of full 4-pair correlation -
public double ortho_min_vert = 0.15; // minimal strength of vert correlation to be used instead of full 4-pair correlation
public double ortho_asym = 1.2; // vert/hor (or hor/vert) strength to be used instead of the full correlation
......@@ -2072,31 +2074,33 @@ public class EyesisCorrectionParameters {
public double shMinStrength = 0.2; // Minimal value of the shell maximum strength
// Thin ice parameters
public double tiRigidVertical = 3.0; // relative disparity rigidity in vertical direction
public double tiRigidHorizontal = 1.0; // relative disparity rigidity in horizontal direction
public double tiRigidDiagonal = 0.5; // relative disparity rigidity in diagonal direction
public double tiStrengthOffset = 0.1; // strength "floor" - subtract (limit 0) before applying
public double tiDispScale = 0.5; // divide actual (disparity*eff_Strength) by this before Math.pow and applying to T.I.
public double tiDispPow = 0.0; // apply pow to disparity (restore sign) for disparity difference pressure on ice
public double tiDispPull = .1; // tiDispPull: multiply strength*disparity difference to pull force
public double tiDispPullPreFinal= .1; // Scale tiDispPull for pre-final pass
public double tiDispPullFinal = .01; // Scale tiDispPull for final pass
public double tiBreak3 = 0.6; // TI break value of abs(d0-3d1+3d2-d3)
public double tiBreak31 = 0.1; // TI break value of (d0-3d1+3d2-d3) * (d1 - d2)
public double tiBreak21 = 0.1; // TI break value of (-d0+d1+d2-d3) * abs(d1 - d2)
public double tiBreakFar = 0.3; // TI disparity threshold to remove as too far tiles
public double tiBreakNear = 0.3; // TI disparity threshold to remove as too near tiles
public int tiBreakMode = 0; // TI break mode: +1: abs(3-rd derivative), +2: -(3-rd * 1-st), +4: -(2-nd * abs(1-st)) , +8 - remove far, +16 - remove near
public double tiBreakSame = 0.5; // Amplify colinear breaks in neighbor tiles
public double tiBreakTurn = 0.125; // Amplify 90-degree turnintg breaks in neighbor tiles
public double tiRigidVertical = 3.0; // 2.0 relative disparity rigidity in vertical direction
public double tiRigidHorizontal = 1.0; // 2.0 relative disparity rigidity in horizontal direction
public double tiRigidDiagonal = 0.5; // 0.5 relative disparity rigidity in diagonal direction
public double tiStrengthOffset = 0.1; // 0.1 strength "floor" - subtract (limit 0) before applying
public double tiDispScale = 0.5; // 0.5 divide actual (disparity*eff_Strength) by this before Math.pow and applying to T.I.
public double tiDispPow = 0.0; // 0.0 apply pow to disparity (restore sign) for disparity difference pressure on ice
public double tiDispPull = .1; // 10.0 tiDispPull: multiply strength*disparity difference to pull force
public double tiDispPullPreFinal= .1; // 5.0 Scale tiDispPull for pre-final pass
public double tiDispPullFinal = .01; // 2.0 Scale tiDispPull for final pass
public double tiHealPreLast = 0.1; // Heal disparity gap before pre-last smooth
public double tiHealLast = 0.05; // Heal disparity gap before last smooth
public int tiHealSame = 5; // Maximal length of an internal break in the cluster to heal
public double tiBreakNorm = .5; // Normalize stresses to average disparity if it is above threshold
public double tiBreak3 = 0.6; // 0.5 TI break value of abs(d0-3d1+3d2-d3)
public double tiBreak31 = 0.1; // 0.04 TI break value of (d0-3d1+3d2-d3) * (d1 - d2)
public double tiBreak21 = 0.1; // 0.1 TI break value of (-d0+d1+d2-d3) * abs(d1 - d2)
public double tiBreakFar = 0.3; // 0.3 TI disparity threshold to remove as too far tiles
public double tiBreakNear = 0.3; // 0.3 TI disparity threshold to remove as too near tiles
public int tiBreakMode = 0; // 1 TI break mode: +1: abs(3-rd derivative), +2: -(3-rd * 1-st), +4: -(2-nd * abs(1-st)) , +8 - remove far, +16 - remove near
public double tiBreakSame = 0.5; // 0.75 Amplify colinear breaks in neighbor tiles
public double tiBreakTurn = 0.125; // 0.125 Amplify 90-degree turnintg breaks in neighbor tiles
public int tiIterations = 1000; // maximal number of TI iterations for each step
public int tiPrecision = 6; // iteration maximal error (1/power of 10)
public int tiNumCycles = 5; // Number of cycles break-smooth (after the first smooth)
public double tiHealPreLast = 0.1; // 0.1 Heal disparity gap before pre-last smooth
public double tiHealLast = 0.05; // 0.05 Heal disparity gap before last smooth
public int tiHealSame = 5; // 10 Maximal length of an internal break in the cluster to heal
public int tiIterations = 1000; // 300 maximal number of TI iterations for each step
public int tiPrecision = 6; // 6 iteration maximal error (1/power of 10)
public int tiNumCycles = 5; // 5 Number of cycles break-smooth (after the first smooth)
// FG/BG separation
public boolean stUseRefine = false; // Apply super-tiles during refine passes
......@@ -2105,9 +2109,11 @@ public class EyesisCorrectionParameters {
public boolean stShow = false; // Calculate and show supertiles histograms
public int stSize = 8; // Super tile size (square, in tiles)
public double stStepDisparity = 0.1; // Disaprity histogram step
public double stStepFar = 0.1; // Disaprity histogram step for far objects
public double stStepNear = 0.5; // Disaprity histogram step for near objects
public double stStepThreshold = 1.0; // Disaprity threshold to switch cfrom linear to logarithmic steps
public double stMinDisparity = 0.0; // Minimal disparity (center of a bin)
public double stMaxDisparity = 10.0; // Maximal disparity (center of a bin)
public double stMaxDisparity = 50.0; // Maximal disparity (center of a bin)
public double stFloor = 0.15; // Subtract from strength, discard negative
public double stPow = 1.0; // raise strength to this power
public double stSigma = 1.5; // Blur disparity histogram (sigma in bins)
......@@ -2142,6 +2148,8 @@ public class EyesisCorrectionParameters {
public boolean show_filter_scan = false; // show 'FilterScan'
public boolean show_combined = false; // show 'combo_scan' (combined multiple scans)
public boolean show_unique = false; // show 'unique_scan' (removed already measured tiles with the same disparity)
public boolean show_init_refine = false; // show debug images during initial refinement
public boolean show_expand = false; // show debug images during disparity expansion
public boolean show_shells = false; // show 'shells'
public boolean show_neighbors = false; // show 'neighbors'
......@@ -2210,6 +2218,7 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"diff_gauss", this.diff_gauss+"");
properties.setProperty(prefix+"min_agree", this.min_agree +"");
properties.setProperty(prefix+"dust_remove", this.dust_remove+"");
properties.setProperty(prefix+"black_back", this.black_back+"");
properties.setProperty(prefix+"keep_weights", this.keep_weights+"");
properties.setProperty(prefix+"sharp_alpha", this.sharp_alpha+"");
......@@ -2259,6 +2268,8 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"fill_gaps", this.fill_gaps+"");
properties.setProperty(prefix+"min_clstr_block", this.min_clstr_block+"");
properties.setProperty(prefix+"bgnd_grow", this.bgnd_grow+"");
properties.setProperty(prefix+"ortho_old", this.ortho_old+"");
properties.setProperty(prefix+"ortho_min_hor", this.ortho_min_hor +"");
properties.setProperty(prefix+"ortho_min_vert", this.ortho_min_vert +"");
properties.setProperty(prefix+"ortho_asym", this.ortho_asym +"");
......@@ -2307,7 +2318,8 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"tiDispPow", this.tiDispPow +"");
properties.setProperty(prefix+"tiDispPull", this.tiDispPull +"");
properties.setProperty(prefix+"tiDispPullPreFinal",this.tiDispPullPreFinal +"");
properties.setProperty(prefix+"tiDispPullFinal", this.tiDispPullFinal +"");
properties.setProperty(prefix+"tiDispPullFinal", this.tiDispPullFinal +"");
properties.setProperty(prefix+"tiBreakNorm", this.tiBreakNorm +"");
properties.setProperty(prefix+"tiBreak3", this.tiBreak3 +"");
properties.setProperty(prefix+"tiBreak31", this.tiBreak31 +"");
properties.setProperty(prefix+"tiBreak21", this.tiBreak21 +"");
......@@ -2331,7 +2343,9 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"stShow", this.stShow+"");
properties.setProperty(prefix+"stSize", this.stSize+"");
properties.setProperty(prefix+"stStepDisparity", this.stStepDisparity +"");
properties.setProperty(prefix+"stStepFar", this.stStepFar +"");
properties.setProperty(prefix+"stStepNear", this.stStepNear +"");
properties.setProperty(prefix+"stStepThreshold", this.stStepThreshold +"");
properties.setProperty(prefix+"stMinDisparity", this.stMinDisparity +"");
properties.setProperty(prefix+"stMaxDisparity", this.stMaxDisparity +"");
properties.setProperty(prefix+"stFloor", this.stFloor +"");
......@@ -2364,6 +2378,8 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"show_filter_scan", this.show_filter_scan+"");
properties.setProperty(prefix+"show_combined", this.show_combined+"");
properties.setProperty(prefix+"show_unique", this.show_unique+"");
properties.setProperty(prefix+"show_init_refine", this.show_init_refine+"");
properties.setProperty(prefix+"show_expand", this.show_expand+"");
properties.setProperty(prefix+"show_shells", this.show_shells+"");
properties.setProperty(prefix+"show_neighbors", this.show_neighbors+"");
properties.setProperty(prefix+"show_flaps_dirs", this.show_flaps_dirs+"");
......@@ -2428,6 +2444,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"diff_gauss")!=null) this.diff_gauss=Boolean.parseBoolean(properties.getProperty(prefix+"diff_gauss"));
if (properties.getProperty(prefix+"min_agree")!=null) this.min_agree=Double.parseDouble(properties.getProperty(prefix+"min_agree"));
if (properties.getProperty(prefix+"dust_remove")!=null) this.dust_remove=Boolean.parseBoolean(properties.getProperty(prefix+"dust_remove"));
if (properties.getProperty(prefix+"black_back")!=null) this.black_back=Boolean.parseBoolean(properties.getProperty(prefix+"black_back"));
if (properties.getProperty(prefix+"keep_weights")!=null) this.keep_weights=Boolean.parseBoolean(properties.getProperty(prefix+"keep_weights"));
if (properties.getProperty(prefix+"sharp_alpha")!=null) this.sharp_alpha=Boolean.parseBoolean(properties.getProperty(prefix+"sharp_alpha"));
if (properties.getProperty(prefix+"alpha0")!=null) this.alpha0=Double.parseDouble(properties.getProperty(prefix+"alpha0"));
......@@ -2475,6 +2492,8 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"fill_gaps")!=null) this.fill_gaps=Integer.parseInt(properties.getProperty(prefix+"fill_gaps"));
if (properties.getProperty(prefix+"min_clstr_block")!=null) this.min_clstr_block=Integer.parseInt(properties.getProperty(prefix+"min_clstr_block"));
if (properties.getProperty(prefix+"bgnd_grow")!=null) this.bgnd_grow=Integer.parseInt(properties.getProperty(prefix+"bgnd_grow"));
if (properties.getProperty(prefix+"ortho_old")!=null) this.ortho_old=Boolean.parseBoolean(properties.getProperty(prefix+"ortho_old"));
if (properties.getProperty(prefix+"ortho_min_hor")!=null) this.ortho_min_hor=Double.parseDouble(properties.getProperty(prefix+"ortho_min_hor"));
if (properties.getProperty(prefix+"ortho_min_vert")!=null) this.ortho_min_vert=Double.parseDouble(properties.getProperty(prefix+"ortho_min_vert"));
if (properties.getProperty(prefix+"ortho_asym")!=null) this.ortho_asym=Double.parseDouble(properties.getProperty(prefix+"ortho_asym"));
......@@ -2521,6 +2540,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"tiDispPull")!=null) this.tiDispPull=Double.parseDouble(properties.getProperty(prefix+"tiDispPull"));
if (properties.getProperty(prefix+"tiDispPullPreFinal")!=null)this.tiDispPullPreFinal=Double.parseDouble(properties.getProperty(prefix+"tiDispPullPreFinal"));
if (properties.getProperty(prefix+"tiDispPullFinal")!=null) this.tiDispPullFinal=Double.parseDouble(properties.getProperty(prefix+"tiDispPullFinal"));
if (properties.getProperty(prefix+"tiBreakNorm")!=null) this.tiBreakNorm=Double.parseDouble(properties.getProperty(prefix+"tiBreakNorm"));
if (properties.getProperty(prefix+"tiBreak3")!=null) this.tiBreak3=Double.parseDouble(properties.getProperty(prefix+"tiBreak3"));
if (properties.getProperty(prefix+"tiBreak31")!=null) this.tiBreak31=Double.parseDouble(properties.getProperty(prefix+"tiBreak31"));
if (properties.getProperty(prefix+"tiBreak21")!=null) this.tiBreak21=Double.parseDouble(properties.getProperty(prefix+"tiBreak21"));
......@@ -2544,7 +2564,9 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"stShow")!=null) this.stShow=Boolean.parseBoolean(properties.getProperty(prefix+"stShow"));
if (properties.getProperty(prefix+"stSize")!=null) this.stSize=Integer.parseInt(properties.getProperty(prefix+"stSize"));
if (properties.getProperty(prefix+"stStepDisparity")!=null) this.stStepDisparity=Double.parseDouble(properties.getProperty(prefix+"stStepDisparity"));
if (properties.getProperty(prefix+"stStepFar")!=null) this.stStepFar=Double.parseDouble(properties.getProperty(prefix+"stStepFar"));
if (properties.getProperty(prefix+"stStepNear")!=null) this.stStepNear=Double.parseDouble(properties.getProperty(prefix+"stStepNear"));
if (properties.getProperty(prefix+"stStepThreshold")!=null) this.stStepThreshold=Double.parseDouble(properties.getProperty(prefix+"stStepThreshold"));
if (properties.getProperty(prefix+"stMinDisparity")!=null) this.stMinDisparity=Double.parseDouble(properties.getProperty(prefix+"stMinDisparity"));
if (properties.getProperty(prefix+"stMaxDisparity")!=null) this.stMaxDisparity=Double.parseDouble(properties.getProperty(prefix+"stMaxDisparity"));
if (properties.getProperty(prefix+"stFloor")!=null) this.stFloor=Double.parseDouble(properties.getProperty(prefix+"stFloor"));
......@@ -2577,11 +2599,12 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"show_filter_scan")!=null) this.show_filter_scan=Boolean.parseBoolean(properties.getProperty(prefix+"show_filter_scan"));
if (properties.getProperty(prefix+"show_combined")!=null) this.show_combined=Boolean.parseBoolean(properties.getProperty(prefix+"show_combined"));
if (properties.getProperty(prefix+"show_unique")!=null) this.show_unique=Boolean.parseBoolean(properties.getProperty(prefix+"show_unique"));
if (properties.getProperty(prefix+"show_init_refine")!=null) this.show_init_refine=Boolean.parseBoolean(properties.getProperty(prefix+"show_init_refine"));
if (properties.getProperty(prefix+"show_expand")!=null) this.show_expand=Boolean.parseBoolean(properties.getProperty(prefix+"show_expand"));
if (properties.getProperty(prefix+"show_shells")!=null) this.show_shells=Boolean.parseBoolean(properties.getProperty(prefix+"show_shells"));
if (properties.getProperty(prefix+"show_neighbors")!=null) this.show_neighbors=Boolean.parseBoolean(properties.getProperty(prefix+"show_neighbors"));
if (properties.getProperty(prefix+"show_flaps_dirs")!=null) this.show_flaps_dirs=Boolean.parseBoolean(properties.getProperty(prefix+"show_flaps_dirs"));
if (properties.getProperty(prefix+"show_first_clusters")!=null) this.show_first_clusters=Boolean.parseBoolean(properties.getProperty(prefix+"show_first_clusters"));
}
public boolean showDialog() {
......@@ -2654,6 +2677,7 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Gaussian as weight when averaging images (false - sharp all/nothing)", this.diff_gauss);
gd.addNumericField("Minimal number of channels to agree on a point (real number to work with fuzzy averages)", this.min_agree, 2);
gd.addCheckbox ("Do not reduce average weight when only one image differes much from the average", this.dust_remove);
gd.addCheckbox ("Use black for backdrop outside of the FOV", this.black_back);
gd.addCheckbox ("Add port weights to RGBA stack (debug feature)", this.keep_weights);
gd.addCheckbox ("Alpha channel: use center 8x8 (unchecked - treat same as RGB)", this.sharp_alpha);
gd.addNumericField("Alpha channel 0.0 thereshold (lower - transparent)", this.alpha0, 3);
......@@ -2704,6 +2728,8 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Number of tiles in a cluster to block (just non-background?)", this.min_clstr_block, 0);
gd.addNumericField("Number of tiles to grow tile selection (1 - hor/vert, 2 - hor/vert/diagonal)", this.bgnd_grow, 0);
gd.addCheckbox ("Use old ortho features processing (orth0_* parameters, false - use or_*)", this.ortho_old);
gd.addNumericField("Minimal strength of hor correlation to be used instead of full 4-pair correlation", this.ortho_min_hor, 3);
gd.addNumericField("Minimal strength of vert correlation to be used instead of full 4-pair correlation", this.ortho_min_vert, 3);
gd.addNumericField("Vert/hor (or hor/vert) strength to be used instead of the full correlation", this.ortho_asym, 3);
......@@ -2756,6 +2782,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("tiDispPull: multiply strength*disparity difference to pull force", this.tiDispPull, 6);
gd.addNumericField("Scale tiDispPull for pre-final pass", this.tiDispPullPreFinal, 6);
gd.addNumericField("Scale tiDispPull for final pass", this.tiDispPullFinal, 6);
gd.addNumericField("Normalize stresses to average disparity if it is above threshold", this.tiBreakNorm, 6);
gd.addNumericField("TI break value of abs(d0-3d1+3d2-d3)", this.tiBreak3, 6);
gd.addNumericField("TI break value of (d0-3d1+3d2-d3) * (d1 - d2)", this.tiBreak31, 6);
gd.addNumericField("TI break value of (-d0+d1+d2-d3) * abs(d1 - d2)", this.tiBreak21, 6);
......@@ -2779,7 +2806,9 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Show supertiles histograms", this.stShow);
gd.addNumericField("Super tile size (square, in tiles)", this.stSize, 0);
gd.addNumericField("Disaprity histogram step", this.stStepDisparity, 6);
gd.addNumericField("Disaprity histogram step for far objects", this.stStepFar, 6);
gd.addNumericField("Disaprity histogram step for near objects", this.stStepNear, 6);
gd.addNumericField("Disaprity threshold to switch cfrom linear to logarithmic steps", this.stStepThreshold, 6);
gd.addNumericField("Minimal disparity (center of a bin)", this.stMinDisparity, 6);
gd.addNumericField("Maximal disparity (center of a bin)", this.stMaxDisparity, 6);
gd.addNumericField("Subtract from strength, discard negative", this.stFloor, 6);
......@@ -2813,6 +2842,8 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Show 'FilterScan'", this.show_filter_scan);
gd.addCheckbox ("Show 'combo_scan' (combined multiple scans)", this.show_combined);
gd.addCheckbox ("Show 'unique_scan' (removed already measured tiles with the same disparity)", this.show_unique);
gd.addCheckbox ("Show debug images during initial refinement", this.show_init_refine);
gd.addCheckbox ("Show debug images during disparity expansion", this.show_expand);
gd.addCheckbox ("Show 'shells'", this.show_shells);
gd.addCheckbox ("show 'neighbors'", this.show_neighbors);
gd.addCheckbox ("Show 'flaps-dirs'", this.show_flaps_dirs);
......@@ -2885,6 +2916,7 @@ public class EyesisCorrectionParameters {
this.diff_gauss= gd.getNextBoolean();
this.min_agree= gd.getNextNumber();
this.dust_remove= gd.getNextBoolean();
this.black_back= gd.getNextBoolean();
this.keep_weights= gd.getNextBoolean();
this.sharp_alpha= gd.getNextBoolean();
this.alpha0= gd.getNextNumber();
......@@ -2930,6 +2962,8 @@ public class EyesisCorrectionParameters {
this.fill_gaps= (int) gd.getNextNumber();
this.min_clstr_block= (int) gd.getNextNumber();
this.bgnd_grow= (int) gd.getNextNumber();
this.ortho_old= gd.getNextBoolean();
this.ortho_min_hor= gd.getNextNumber();
this.ortho_min_vert= gd.getNextNumber();
this.ortho_asym= gd.getNextNumber();
......@@ -2977,6 +3011,7 @@ public class EyesisCorrectionParameters {
this.tiDispPull= gd.getNextNumber();
this.tiDispPullPreFinal= gd.getNextNumber();
this.tiDispPullFinal= gd.getNextNumber();
this.tiBreakNorm= gd.getNextNumber();
this.tiBreak3= gd.getNextNumber();
this.tiBreak31= gd.getNextNumber();
this.tiBreak21= gd.getNextNumber();
......@@ -3000,7 +3035,9 @@ public class EyesisCorrectionParameters {
this.stShow= gd.getNextBoolean();
this.stSize= (int) gd.getNextNumber();
this.stStepDisparity= gd.getNextNumber();
this.stStepFar= gd.getNextNumber();
this.stStepNear= gd.getNextNumber();
this.stStepThreshold= gd.getNextNumber();
this.stMinDisparity= gd.getNextNumber();
this.stMaxDisparity= gd.getNextNumber();
this.stFloor= gd.getNextNumber();
......@@ -3034,6 +3071,8 @@ public class EyesisCorrectionParameters {
this.show_filter_scan= gd.getNextBoolean(); // first on refine
this.show_combined= gd.getNextBoolean();
this.show_unique= gd.getNextBoolean();
this.show_init_refine= gd.getNextBoolean();
this.show_expand= gd.getNextBoolean();
this.show_shells= gd.getNextBoolean();
this.show_neighbors= gd.getNextBoolean();
this.show_flaps_dirs= gd.getNextBoolean();
......
......@@ -4698,8 +4698,8 @@ public class QuadCLT {
final boolean updateStatus,
final int debugLevel)
{
final boolean show_init_refine = true;
final boolean show_expand = true;
final boolean show_init_refine = clt_parameters.show_init_refine;
final boolean show_expand = clt_parameters.show_expand;
String name = (String) imp_quad[0].getProperty("name");
double [][][] image_data = new double [imp_quad.length][][];
......@@ -4722,7 +4722,8 @@ public class QuadCLT {
final int tilesY = tp.getTilesY();
TileProcessor.CLTPass3d bgnd_data = CLTBackgroundMeas( // measure background
/// CLTPass3d bgnd_data = CLTBackgroundMeas( // measure background
CLTPass3d bgnd_data = CLTBackgroundMeas( // measure background
image_data, //
clt_parameters,
threadsMax, // maximal number of threads to launch
......@@ -4739,7 +4740,8 @@ public class QuadCLT {
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
bgnd_data.texture = imp_bgnd.getTitle()+".png";
// bgnd_data.texture = imp_bgnd.getTitle()+".png";
bgnd_data.texture = imp_bgnd.getTitle()+ (clt_parameters.black_back? ".jpeg" : ".png");
// create x3d file
X3dOutput x3dOutput = new X3dOutput(
......@@ -4760,7 +4762,8 @@ public class QuadCLT {
// final boolean show_init_refine = true;
// final boolean show_expand = true;
if (show_init_refine) tp.showScan(
// if (show_init_refine)
tp.showScan(
tp.clt_3d_passes.get(bg_pass), // CLTPass3d scan,
"after_bg-"+tp.clt_3d_passes.size());
......@@ -4781,8 +4784,9 @@ public class QuadCLT {
geometryCorrection,
threadsMax, // maximal number of threads to launch
updateStatus,
2); // debugLevel);
tp.showScan(
debugLevel); //2);
if (debugLevel > 1)
tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
"before_makeUnique-"+refine_pass);
int [] numLeftRemoved = tp.makeUnique(
......@@ -4814,7 +4818,7 @@ public class QuadCLT {
"after_measure-"+tp.clt_3d_passes.size());
// if (clt_parameters.combine_refine){
TileProcessor.CLTPass3d combo_pass = tp.compositeScan(
CLTPass3d combo_pass = tp.compositeScan(
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,
bg_pass, // final int firstPass,
tp.clt_3d_passes.size(), // final int lastPassPlus1,
......@@ -4827,7 +4831,8 @@ public class QuadCLT {
false, // final boolean use_last, //
// TODO: when useCombo - pay attention to borders (disregard)
false, // final boolean usePoly) // use polynomial method to find max), valid if useCombo == false
true); // final boolean copyDebug)
true, // final boolean copyDebug)
debugLevel);
if (show_init_refine) tp.showScan(
combo_pass, // CLTPass3d scan,
......@@ -4838,18 +4843,16 @@ public class QuadCLT {
// }
}
// TEMPORARY EXIT
if (tp.clt_3d_passes.size() > 0) return null; // just to fool compiler
// TEMPORARY EXIT
// if (tp.clt_3d_passes.size() > 0) return null; // just to fool compiler
// above - multiple refinements (reduce, make conditional?)
int num_extended = -1;
int [] numLeftRemoved;
// process once more to try combining of processed
// for (int num_expand = 0; (num_expand < 4) && (num_extended != 0); num_expand++) {
for (int num_expand = 0; (num_expand < 1) && (num_extended != 0); num_expand++) {
for (int num_expand = 0; (num_expand < 10) && (num_extended != 0); num_expand++) {
// for (int num_expand = 0; (num_expand < 1) && (num_extended != 0); num_expand++) {
refine_pass = tp.clt_3d_passes.size(); // 1
tp.refinePassSetup( // prepare tile tasks for the refine pass (re-measure disparities)
// final double [][][] image_data, // first index - number of image in a quad
......@@ -4877,7 +4880,7 @@ public class QuadCLT {
refine_pass, // may add 1 to include current (for future?) // final int lastPassPlus1,
tp.clt_3d_passes.get(refine_pass)); // final int lastPassPlus1,
TileProcessor.CLTPass3d extended_pass = tp.compositeScan(
CLTPass3d extended_pass = tp.compositeScan(
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,
bg_pass, // final int firstPass,
tp.clt_3d_passes.size(), // final int lastPassPlus1,
......@@ -4890,7 +4893,8 @@ public class QuadCLT {
true, // false, // final boolean use_last, //
// TODO: when useCombo - pay attention to borders (disregard)
false, // final boolean usePoly) // use polynomial method to find max), valid if useCombo == false
true); // final boolean copyDebug)
true, // final boolean copyDebug)
debugLevel);
if (show_expand) tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
......@@ -4907,7 +4911,7 @@ public class QuadCLT {
clt_parameters.grow_min_diff, // = 0.5; // Grow more only if at least one channel has higher variance from others for the tile
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
geometryCorrection, // GeometryCorrection geometryCorrection,
true, // final boolean show_debug,
show_expand, // true, // final boolean show_debug,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
......@@ -4952,13 +4956,13 @@ public class QuadCLT {
if (debugLevel > -1){
System.out.println("extending: CLTMeasure("+refine_pass+")");
}
TileProcessor.CLTPass3d combo_pass = tp.compositeScan(
//num_expand == 9
CLTPass3d combo_pass = tp.compositeScan(
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,
bg_pass, // final int firstPass,
tp.clt_3d_passes.size(), // final int lastPassPlus1,
tp.getTrustedCorrelation(), // final double trustedCorrelation,
0.0, // clt_parameters.bgnd_range, // final double disp_far, // limit results to the disparity range
-0.5, // 0.0, // clt_parameters.bgnd_range, // final double disp_far, // limit results to the disparity range
clt_parameters.grow_disp_max, // final double disp_near,
clt_parameters.combine_min_strength, // final double minStrength,
clt_parameters.combine_min_hor, // final double minStrengthHor,
......@@ -4966,24 +4970,32 @@ public class QuadCLT {
false, // final boolean use_last, //
// TODO: when useCombo - pay attention to borders (disregard)
false, // final boolean usePoly) // use polynomial method to find max), valid if useCombo == false
true); // final boolean copyDebug)
true, // final boolean copyDebug)
// (num_expand == 9)? 2: debugLevel);
debugLevel);
tp.clt_3d_passes.add(combo_pass);
// refine_pass = tp.clt_3d_passes.size();
// }
if (show_expand) tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
"after_combo_pass-"+(tp.clt_3d_passes.size()-1)); //String title)
"after_combo_pass-"+(refine_pass)); //String title)
}
tp.showScan(
tp.clt_3d_passes.get(tp.clt_3d_passes.size()-2), // CLTPass3d scan,
"after_pre_last_combo_pass-"+(tp.clt_3d_passes.size()-2)); //String title)
tp.showScan(
tp.clt_3d_passes.get(tp.clt_3d_passes.size()-1), // CLTPass3d scan,
"after_last_combo_pass-"+(tp.clt_3d_passes.size()-1)); //String title)
// TEMPORARY EXIT
if (tp.clt_3d_passes.size() > 0) return null; // just to fool compiler
// if (tp.clt_3d_passes.size() > 0) return null; // just to fool compiler
refine_pass = tp.clt_3d_passes.size(); // 1
refine_pass = tp.clt_3d_passes.size(); // refinePassSetup() will add one
/*
// Refine after extension
tp.refinePassSetup( // prepare tile tasks for the refine pass (re-measure disparities)
// final double [][][] image_data, // first index - number of image in a quad
......@@ -4991,7 +5003,8 @@ public class QuadCLT {
clt_parameters.stUseRefine, // use supertiles
bg_pass,
// disparity range - differences from
clt_parameters.bgnd_range, // double disparity_far,
// clt_parameters.bgnd_range, // double disparity_far,
-0.5, // 0.0, // clt_parameters.bgnd_range, // final double disp_far, // limit results to the disparity range
clt_parameters.grow_disp_max, // other_range, //double disparity_near, //
clt_parameters.bgnd_sure, // double this_sure, // minimal strength to be considered definitely background
clt_parameters.bgnd_maybe, // double this_maybe, // maximal strength to ignore as non-background
......@@ -5011,25 +5024,33 @@ public class QuadCLT {
if (debugLevel > -1){
System.out.println("makeUnique("+refine_pass+") -> left: "+numLeftRemoved[0]+", removed:" + numLeftRemoved[1]);
}
tp.showScan(
tp.clt_3d_passes.get(refine_pass-1), // CLTPass3d scan,
"prev_after_last_refine-"+(refine_pass-1)); //String title)
tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
"after_last_refine-"+refine_pass); //String title)
// TEMPORARY EXIT
if (tp.clt_3d_passes.size() > 0) return null; // just to fool compiler
*/
// testing 2-nd pass
int next_pass = tp.clt_3d_passes.size(); // 2
// int next_pass = tp.clt_3d_passes.size() + 1; // Now secondPassSetup starts with generating a combo image?
int next_pass = tp.clt_3d_passes.size(); //
tp.secondPassSetup( // prepare tile tasks for the second pass based on the previous one(s)
// final double [][][] image_data, // first index - number of image in a quad
clt_parameters,
clt_parameters.stUsePass2, // use supertiles
bg_pass,
// disparity range - differences from
clt_parameters.bgnd_range, // double disparity_far,
clt_parameters.bgnd_range, // double disparity_far,
// -0.5, // 0.0, // clt_parameters.bgnd_range, // final double disp_far, // limit results to the disparity range
clt_parameters.grow_disp_max, // other_range, //double disparity_near, //
clt_parameters.bgnd_sure, // double this_sure, // minimal strength to be considered definitely background
clt_parameters.bgnd_maybe, // double this_maybe, // maximal strength to ignore as non-background
......@@ -5039,21 +5060,34 @@ public class QuadCLT {
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
// get images for predefined regions and dispariteies. First - with just fixed scans 1 .. list.size()
for (int scanIndex = next_pass; scanIndex < tp.clt_3d_passes.size(); scanIndex++){
if (debugLevel > 0){
System.out.println("FPGA processing scan #"+scanIndex);
}
TileProcessor.CLTPass3d scan = CLTMeasure( // perform single pass according to prepared tiles operations and disparity
image_data, // first index - number of image in a quad
clt_parameters,
scanIndex,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
// get images for predefined regions and disparities. First - with just fixed scans 1 .. list.size()
}
tp.showScan(
tp.clt_3d_passes.get(next_pass-1), // CLTPass3d scan,
"after_pass2-"+(next_pass-1)); //String title)
for (int scanIndex = next_pass; scanIndex < tp.clt_3d_passes.size(); scanIndex++){
if (debugLevel > 0){
System.out.println("FPGA processing scan #"+scanIndex);
}
CLTPass3d scan = CLTMeasure( // perform single pass according to prepared tiles operations and disparity
image_data, // first index - number of image in a quad
clt_parameters,
scanIndex,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
if ((scanIndex == 49) || (scanIndex == 54) ) tp.showScan(
scan, // tp.clt_3d_passes.get(scanIndex), // CLTPass3d scan,
"MEASURED-"+scanIndex);
}
// TEMPORARY EXIT
// if (tp.clt_3d_passes.size() > 0) return null; // just to fool compiler
// int scan_limit = 10;
for (int scanIndex = next_pass; (scanIndex < tp.clt_3d_passes.size()) && (scanIndex < clt_parameters.max_clusters); scanIndex++){ // just temporary limiting
if (debugLevel > -1){
......@@ -5070,12 +5104,22 @@ public class QuadCLT {
updateStatus,
debugLevel);
TileProcessor.CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
if ((scanIndex == 49) || (scanIndex == 54) ) {
tp.showScan(
tp.clt_3d_passes.get(scanIndex), // CLTPass3d scan,
"SELECTED-"+scanIndex);
}
// TODO: use new updated disparity, for now just what was forced for the picture
double [] scan_disparity = new double [tilesX * tilesY];
int indx = 0;
// boolean [] scan_selected = scan.getSelected();
for (int ty = 0; ty < tilesY; ty ++) for (int tx = 0; tx < tilesX; tx ++){
// scan_selected[indx] = scan.tile_op[ty][tx] != 0;
scan_disparity[indx++] = scan.disparity[ty][tx];
}
if (clt_parameters.avg_cluster_disp){
......@@ -5091,9 +5135,14 @@ public class QuadCLT {
for (int i = 0; i< scan_disparity.length; i++){
scan_disparity[i] = sdw;
}
}
if ((scanIndex == 49) || (scanIndex == 54) ) {
tp.showScan(
tp.clt_3d_passes.get(scanIndex), // CLTPass3d scan,
"X3D-"+scanIndex);
}
boolean showTri = ((scanIndex < next_pass + 1) && clt_parameters.show_triangles) ||(scanIndex == 49) || (scanIndex == 54);
generateClusterX3d(
x3dOutput,
texturePath,
......@@ -5102,10 +5151,12 @@ public class QuadCLT {
scan_disparity, // scan.disparity_map[ImageDtt.DISPARITY_INDEX_CM],
clt_parameters.transform_size,
clt_parameters.correct_distortions, // requires backdrop image to be corrected also
(scanIndex < next_pass + 1) && clt_parameters.show_triangles,
clt_parameters.bgnd_range,
clt_parameters.other_range,
clt_parameters.maxDispTriangle);
showTri, // (scanIndex < next_pass + 1) && clt_parameters.show_triangles,
clt_parameters.bgnd_range, // 0.3
clt_parameters.grow_disp_max, // other_range, // 2.0 'other_range - difference from the specified (*_CM)
clt_parameters.maxDispTriangle);
}
......@@ -5207,7 +5258,7 @@ public class QuadCLT {
if (clt_parameters.debug_filters && (debugLevel > -1)) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
TileProcessor.CLTPass3d bgnd_data = tp.clt_3d_passes.get(0);
CLTPass3d bgnd_data = tp.clt_3d_passes.get(0);
double [][][][] texture_tiles = bgnd_data.texture_tiles;
boolean [] bgnd_tiles = tp.getBackgroundMask( // which tiles do belong to the background
......@@ -5309,27 +5360,28 @@ public class QuadCLT {
// public double getFOVPix(){ // get ratio of 1 pixel X/Y to Z (distance to object)
ImagePlus imp_texture_bgnd_ext = resizeForBackdrop(
imp_texture_bgnd,
clt_parameters.black_back, // boolean fillBlack,
clt_parameters.black_back, // boolean noalpha,
debugLevel);
String path= correctionsParameters.selectX3dDirectory(
true, // smart,
true); //newAllowed, // save
// only show/save original size if debug or debug_filters)
// only show/save original size if debug or debug_filters)
int jpegQuality = clt_parameters.black_back ? 90: -1;
if (clt_parameters.debug_filters || (debugLevel > 0)) {
eyesisCorrections.saveAndShow(
imp_texture_bgnd,
path,
correctionsParameters.png,
correctionsParameters.png && !clt_parameters.black_back,
clt_parameters.show_textures,
-1); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
jpegQuality); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
}
eyesisCorrections.saveAndShow(
imp_texture_bgnd_ext,
path,
correctionsParameters.png,
correctionsParameters.png && !clt_parameters.black_back,
clt_parameters.show_textures,
-1); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
jpegQuality); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
return imp_texture_bgnd_ext;
}
......@@ -5352,7 +5404,8 @@ public class QuadCLT {
showDoubleFloatArrays sdfa_instance = null;
// if (clt_parameters.debug_filters && (debugLevel > -1)) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
TileProcessor.CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
/// CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
boolean [] borderTiles = scan.border_tiles;
double [][][][] texture_tiles = scan.texture_tiles;
scan.updateSelection(); // update .selected field (all selected, including border) and Rectangle bounds
......@@ -5470,7 +5523,12 @@ public class QuadCLT {
public ImagePlus resizeForBackdrop(ImagePlus imp, int debugLevel){
public ImagePlus resizeForBackdrop(
ImagePlus imp,
boolean fillBlack,
boolean noalpha, // only with fillBlack, otherwize ignored
int debugLevel)
{
double backdropPixels = 2.0/geometryCorrection.getFOVPix();
if (debugLevel > -1) {
System.out.println("backdropPixels = "+backdropPixels);
......@@ -5487,11 +5545,40 @@ public class QuadCLT {
}
int [] src_pixels = (int []) imp.getProcessor().getPixels();
int [] pixels = new int [width2* height2];
int black = noalpha ? 0 : 0xff000000;
int mask = noalpha ? 0xffffff : 0xffffffff;
if (fillBlack) {
for (int i = 0; i < pixels.length; i++){
pixels[i] = black;
}
}
int indx = 0;
int offset = v_margin * width2 + h_margin;
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
pixels[offset+ i * width2 + j] = src_pixels[indx++];
if (fillBlack) {
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
int a = (src_pixels[indx] >> 24) & 0xff;
if (a == 255) {
pixels[offset+ i * width2 + j] = src_pixels[indx] & mask;
} else if (a == 0) {
pixels[offset+ i * width2 + j] = black;
} else {
int r = (src_pixels[indx] >> 16) & 0xff; //' maybe - swap with b?
int g = (src_pixels[indx] >> 8) & 0xff;
int b = (src_pixels[indx] >> 0) & 0xff;
r = (r * a) / 255;
g = (g * a) / 255;
b = (b * a) / 255;
pixels[offset+ i * width2 + j] = black | (r << 16) | (g << 8) | b;
}
indx++;
}
}
} else {
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
pixels[offset+ i * width2 + j] = src_pixels[indx++];
}
}
}
ColorProcessor cp=new ColorProcessor(width2,height2);
......@@ -5503,7 +5590,7 @@ public class QuadCLT {
//[tp.tilesY][tp.tilesX]["RGBA".length()][]
//linearStackToColor
public TileProcessor.CLTPass3d CLTBackgroundMeas( // measure background
public CLTPass3d CLTBackgroundMeas( // measure background
final double [][][] image_data, // first index - number of image in a quad
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
......@@ -5512,7 +5599,8 @@ public class QuadCLT {
{
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
TileProcessor.CLTPass3d scan_rslt = tp.new CLTPass3d();
// CLTPass3d scan_rslt = tp.new CLTPass3d(tp);
CLTPass3d scan_rslt = new CLTPass3d(tp);
int d = ImageDtt.setImgMask(0, 0xf);
d = ImageDtt.setPairMask(d,0xf);
d = ImageDtt.setForcedDisparity(d,true);
......@@ -5597,7 +5685,7 @@ public class QuadCLT {
return scan_rslt;
}
public TileProcessor.CLTPass3d CLTMeasure( // perform single pass according to prepared tiles operations and disparity
public CLTPass3d CLTMeasure( // perform single pass according to prepared tiles operations and disparity
final double [][][] image_data, // first index - number of image in a quad
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int scanIndex,
......@@ -5607,12 +5695,20 @@ public class QuadCLT {
{
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
TileProcessor.CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
int [][] tile_op = scan.tile_op;
double [][] disparity_array = scan.disparity;
// undecided, so 2 modes of combining alpha - same as rgb, or use center tile only
double [][][][] clt_corr_combo = new double [ImageDtt.TCORR_TITLES.length][tilesY][tilesX][]; // will only be used inside?
if (debugLevel > -1){
int numTiles = 0;
for (int ty = 0; ty < tile_op.length; ty ++) for (int tx = 0; tx < tile_op[ty].length; tx ++){
if (tile_op[ty][tx] != 0) numTiles ++;
}
System.out.println("CLTMeasure("+scanIndex+"): numTiles = "+numTiles);
}
double min_corr_selected = clt_parameters.min_corr;
double [][] disparity_map = new double [ImageDtt.DISPARITY_TITLES.length][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
......
/**
**
** SuperTiles - Process tiles resulted from quad image sets
**
** Copyright (C) 2017 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** SuperTiles.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
import java.util.concurrent.atomic.AtomicInteger;
public class SuperTiles{
TileProcessor tileProcessor;
double step_near;
double step_far;
double step_threshold;
double min_disparity;
double max_disparity;
double strength_floor;
double strength_pow;
double stBlurSigma;
int numBins;
double [][] disparityHistograms = null;
double [] stStrength = null; // per super-tile correlation strength
double [][][] maxMinMax = null;
double [] bgDisparity = null;
double [] bgStrength = null;
// TileProcessor.CLTPass3d cltPass3d;
CLTPass3d cltPass3d;
public SuperTiles(
// TileProcessor.CLTPass3d cltPass3d,
CLTPass3d cltPass3d,
double step_near,
double step_far,
double step_threshold,
double min_disparity,
double max_disparity,
double strength_floor,
double strength_pow,
double stBlurSigma)
{
this.cltPass3d = cltPass3d;
this.tileProcessor = cltPass3d.getTileProcessor();
this.step_near = step_near;
this.step_far = step_far;
this.step_threshold = step_threshold;
this.min_disparity = min_disparity;
this.max_disparity = max_disparity;
this.strength_floor = strength_floor;
this.strength_pow = strength_pow;
this.stBlurSigma = stBlurSigma;
// this.numBins = (int) ((max_disparity - min_disparity)/step_disparity) + 1;
this.numBins = (int) ((max_disparity - min_disparity)/step_far) + 1;
// getDisparityHistograms(); // calculate and blur supertileas
getDisparityHistograms(null); // calculate and blur supertileas (for all, not just selected?)
}
private double [][] getLapWeights(){
final int superTileSize = tileProcessor.superTileSize;
final double [][] lapWeight = new double [2 * superTileSize][2 * superTileSize];
final double [] lapWeight1d = new double [superTileSize];
final int superTileSize2 = 2 * superTileSize;
for (int i = 0; i < superTileSize; i++){
lapWeight1d[i] = 0.5*(1.0 - Math.cos((i + 0.5)* Math.PI/superTileSize));
}
for (int i = 0; i < superTileSize; i++){
for (int j = 0; j < superTileSize; j++){
lapWeight[i] [ j] = lapWeight1d[i]*lapWeight1d[j];
lapWeight[superTileSize2 - 1 - i][ j] = lapWeight[i][j];
lapWeight[i] [superTileSize2 - 1 - j] = lapWeight[i][j];
lapWeight[superTileSize2 - 1 - i][superTileSize2 - 1 - j] = lapWeight[i][j];
}
}
double s = 0.0;
for (int i = 0; i < superTileSize2; i++){
for (int j = 0; j < superTileSize2; j++){
s+=lapWeight[i][j];
}
}
System.out.println("getLapWeights: sum = "+s);
return lapWeight;
}
// updates disparityHistograms
public double [][] getDisparityHistograms()
{
return getDisparityHistograms(cltPass3d.selected, tileProcessor.globalDebugLevel);
}
// updates disparityHistograms
public double [][] getDisparityHistograms(final boolean [] selected) // null)
{
return getDisparityHistograms(selected, tileProcessor.globalDebugLevel);
}
public double [][] getDisparityHistograms(
final boolean [] selected, // or null
final int debugLevel)
{
if (this.disparityHistograms != null) return this.disparityHistograms;
final double step_disparity = step_near; // TODO: implement
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.superTileSize;
final double [] disparity = cltPass3d.getDisparity();
final double [] strength = cltPass3d.getStrength();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
// final int numBins = (int) ((max_disparity - min_disparity)/step_disparity) + 1;
final double dMin = min_disparity - step_disparity/2;
final double dMax = dMin + numBins * step_disparity;
// final double [][] dispHist = new double [nStiles][numBins];
final double [][] dispHist = new double [nStiles][]; // now it will be sparse
final double [] strengthHist = new double [nStiles];
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final int st_start = - superTileSize/2;
// final int st_end = st_start + superTileSize;
final int superTileSize2 = 2 * superTileSize;
final double [][] lapWeight = getLapWeights();
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nsTile = ai.getAndIncrement(); nsTile < nStiles; nsTile = ai.getAndIncrement()) {
int stileY = nsTile / stilesX;
int stileX = nsTile % stilesX;
double sw = 0.0; // sum weights
double [] hist = new double [numBins];
// for (int tileY = stileY * superTileSize + st_start; tileY < stileY * superTileSize + st_end; tileY++){
int tY0 = stileY * superTileSize + st_start;
int tX0 = stileX * superTileSize + st_start;
for (int tY = 0; tY < superTileSize2; tY++){
int tileY = tY0 +tY;
if ((tileY >= 0) && (tileY < tilesY)) {
// for (int tileX = stileX * superTileSize + st_start; tileX < stileX * superTileSize + st_end; tileX++){
for (int tX = 0; tX < superTileSize2; tX++){
int tileX = tX0 +tX;
if ((tileX >= 0) && (tileX < tilesX)) {
int indx = tileY*tilesX + tileX;
double d = disparity[indx];
if (!Double.isNaN(d) && ((selected == null) || selected[indx])){
double w = strength[indx] - strength_floor;
if (w > 0.0){
if (strength_pow != 1.0) w = Math.pow(w, strength_pow);
w *= lapWeight[tY][tX];
int bin = (int) ((d-dMin)/step_disparity);
if ((bin >= 0) && (bin < numBins)){ // maybe collect below min and above max somewhere?
hist[bin] += w; // +1]
sw +=w;
}
}
}
}
}
}
}
strengthHist[nsTile] = sw / superTileSize / superTileSize; // average strength per tile in the super-tile
if (sw > 0){
for (int i = 0; i<numBins; i++){
hist[i] /= sw;
}
dispHist[nsTile] = hist;
} else {
dispHist[nsTile] = null;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
this.disparityHistograms = dispHist;
this.stStrength = strengthHist;
if (this.stBlurSigma > 0.0) {
blurDisparityHistogram(debugLevel);
}
return this.disparityHistograms; // dispHist;
}
public void blurDisparityHistogram( // in-place
final int debugLevel)
{
final double [][] dispHist = this.disparityHistograms;
final double sigma = this.stBlurSigma;
final int sTiles = dispHist.length;
// final int numBins = dispHist[0].length;
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() {
public void run() {
DoubleGaussianBlur gb=new DoubleGaussianBlur();
for (int nsTile = ai.getAndIncrement(); nsTile < sTiles; nsTile = ai.getAndIncrement()) {
if (dispHist[nsTile] != null) {
gb.blur1Direction(dispHist[nsTile], numBins, 1, sigma, 0.01,true);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
// returns odd-length array of max/min (x, strength) pairs
public double [][][] getMaxMinMax(){
// first find all integer maximums, and if the top is flat - use the middle. If not flat - use 2-nd degree polynomial
if (disparityHistograms == null) getDisparityHistograms();
final int globalDebugLevel = tileProcessor.globalDebugLevel;
maxMinMax = new double [disparityHistograms.length][][];
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() {
public void run() {
DoubleGaussianBlur gb=new DoubleGaussianBlur();
for (int nsTile = ai.getAndIncrement(); nsTile < maxMinMax.length; nsTile = ai.getAndIncrement()) {
if (disparityHistograms[nsTile] != null) {
double [] dh = disparityHistograms[nsTile];
double [][] mmm = new double [numBins][2]; // will definitely be shorter
int numMax = 0;
int lo = 0;
int hi = 1;
if ((globalDebugLevel > -1 ) && (nsTile == 359)) {
System.out.println(nsTile);
}
while (hi < numBins) {
// looking for next max
while ((hi < numBins) && (dh[hi] >= dh[hi - 1])) hi++; // flat or higher - continue
if (hi == numBins){ // last
if (dh[hi - 1] == dh[lo]) break; // no maximums till the very end
if (dh[hi - 1] > dh[hi-2]) {// and is higher than previus
mmm[numMax * 2][0] = hi - 1;
} else { // flat top, but higher than [lo]
int i = hi - 3;
while (dh[i] == dh[hi - 1]) i --;
mmm[numMax * 2][0] = 0.5 * (hi + i); // middle
}
mmm[numMax * 2][1] = dh[hi - 1];
numMax++;
break;
} else { // d[hi] < d[hi-1] // can be 2-nd after higher first, has sharp max at hi-1, have flat max (including from start)
if ((dh[hi - 1] == dh[lo]) || (dh[hi - 1] == dh[hi-2])){ // just a second with higher 1-st, or a flat initial top
// flat top
while (dh[lo] < dh[hi - 1]) lo++;
mmm[numMax * 2][0] = 0.5 *(hi - 1 + lo);
mmm[numMax * 2][1] = dh[hi - 1];
} else { // normal max, use parabola for approximation and max
double a = 0.5*(dh[hi] -2*dh[hi-1] + dh[hi-2]);
double b = 0.5*(dh[hi] - dh[hi-2]);
double dx = - b/(2*a);
// protect agains very low a,b
if (dx > 1.0){
dx = 1.0;
mmm[numMax * 2][1] = dh[hi];
System.out.println("Max: insufficient precision, dx = "+dx+" > 1.0");
} else if (dx < -1.0){
dx = -1.0;
mmm[numMax * 2][1] = dh[hi - 2];
System.out.println("Max: insufficient precision, dx = "+dx+" < -1.0");
} else {
mmm[numMax * 2][1] = dh[hi-1] - b*b / (4*a);
}
mmm[numMax * 2][0] = (hi -1) + dx;
}
lo = hi-1;
numMax++;
}
// look for next minimum after maximum
while ((hi < numBins) && (dh[hi] <= dh[hi - 1])) hi++; // flat or lower - continue
if (hi == numBins){ // last
break;// do not need to register minimum after maximum
} else if (dh[hi - 1] == dh[hi-2]) { // flat top
while (dh[lo] > dh[hi - 1]) lo++;
mmm[numMax * 2 - 1][0] = 0.5 *(hi - 1 + lo);
mmm[numMax * 2 - 1][1] = dh[hi - 1];
} else { // normal min - use parabola
double a = 0.5*(dh[hi] -2*dh[hi-1] + dh[hi-2]);
double b = 0.5*(dh[hi] - dh[hi-2]);
double dx = - b/(2*a);
// protect agains very low a,b
if (dx > 1.0){
dx = 1.0;
mmm[numMax * 2 - 1][1] = dh[hi];
System.out.println("Min: insufficient precision, dx = "+dx+" > 1.0");
} else if (dx < -1.0){
dx = -1.0;
mmm[numMax * 2 - 1][1] = dh[hi - 2];
System.out.println("Min: insufficient precision, dx = "+dx+" < -1.0");
} else {
mmm[numMax * 2 -1][1] = dh[hi-1] - b*b / (4*a);
}
mmm[numMax * 2 - 1][0] = (hi -1) + dx;
lo = hi -1;
}
}
if (numMax > 0) {
maxMinMax[nsTile] = new double[numMax * 2 - 1][2];
for (int i = 0; i < maxMinMax[nsTile].length; i++){
maxMinMax[nsTile][i][0] = mmm[i][0];
maxMinMax[nsTile][i][1] = mmm[i][1] * stStrength[nsTile];
}
if (globalDebugLevel > -1 ) {
System.out.println(nsTile+": "+dh[0]+" "+dh[1]+" "+dh[2]+" "+dh[3]+" "+dh[4]+" "+
dh[5]+" "+dh[6]+" "+dh[7]+" "+dh[8]+" "+dh[9]+ " "+dh[10]+" "+dh[11]+" "+dh[12]+" "+dh[13]+" "+dh[14]+" "+
dh[15]+" "+dh[16]+" "+dh[17]+" "+dh[18]+" "+dh[19]+ " "+dh[20]);
String dbg_str = ""+nsTile+": ";
for (int i = 0; i < maxMinMax[nsTile].length; i++){
dbg_str += " "+maxMinMax[nsTile][i][0]+":"+maxMinMax[nsTile][i][1];
}
System.out.println(dbg_str);
}
} else {
maxMinMax[nsTile] = null;
}
} else {
maxMinMax[nsTile] = null;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return maxMinMax;
}
public int showDisparityHistogramWidth()
{
final int superTileSize = tileProcessor.superTileSize;
int sTilesX = (tileProcessor.getTilesX() + superTileSize -1)/superTileSize;
return sTilesX * (numBins + 1) + 1;
}
public double [] showDisparityHistogram()
{
if (disparityHistograms == null){
getDisparityHistograms(); // calculate and blur with the current settings, specified at instantiation
}
return showDisparityHistogram(disparityHistograms);
}
public double [] showDisparityHistogram(final double [][] dispHist){
final int superTileSize = tileProcessor.superTileSize;
int sTileHeight0 = 0; // vertical pixels for each histogram (excluding borders). if <= 0 make square cells
final double [] strengthHist = stStrength;
final int sTilesX = (tileProcessor.getTilesX() + superTileSize -1)/superTileSize;
final int sTiles = dispHist.length;
final int sTilesY = sTiles / sTilesX;
// final int numBins = dispHist[0].length; // [0] - weight
final int sTileHeight = (sTileHeight0 > 0)? sTileHeight0 : numBins;
final double [] maxHist = new double [sTiles];
final int width = sTilesX * (numBins + 1) + 1;
final int height = sTilesY * (sTileHeight + 1) +1;
double [] rslt = new double [width*height];
double maxW = 0.0; // use for borders between cells
for (int i = 0; i < sTiles; i++){
if (maxW < strengthHist[i]) maxW = strengthHist[i];
if (dispHist[i] != null) {
for (int j = 0; j< numBins; j++){
if (!Double.isNaN( dispHist[i][j]) && (maxHist[i] < dispHist[i][j])) maxHist[i] = dispHist[i][j];
}
}
}
for (int nsTile = 0; nsTile < sTiles; nsTile++){
int stileY = nsTile / sTilesX;
int stileX = nsTile % sTilesX;
int x0 = stileX * (numBins + 1);
int y0 = stileY * (numBins + 1);
int indx0 = x0 + y0*width;
// draw rectangular frame - horisontal dotted lines
for (int j = 0; j < numBins + 2; j+=2) {
rslt [indx0 + j] = maxW;
rslt [indx0 + (sTileHeight + 1) * width+ j] = maxW;
}
// vertical dotted lines
for (int j = 0; j < sTileHeight + 2; j+=2) {
rslt [indx0 + j * width] = maxW;
rslt [indx0 + (numBins + 1)+ j * width] = maxW;
}
// draw normalized histograms, using overall weight as intensity
if (dispHist[nsTile] != null) {
for (int bin = 0; bin <numBins; bin ++){
int h = (int) (sTileHeight * dispHist[nsTile][bin] / maxHist[nsTile]);
int x = bin + 1;
for (int j = 0; j <= h; j++) {
int y = sTileHeight + 1 - j;
rslt [indx0 + y * width + x] = strengthHist[nsTile];
}
}
}
}
return rslt;
}
public double [] showMaxMinMax(){
if (maxMinMax == null){
getMaxMinMax(); // calculate and blur with the current settings, specified at instantiation
}
final int superTileSize = tileProcessor.superTileSize;
int sTileHeight0 = 0; // vertical pixels for each histogram (excluding borders). if <= 0 make square cells
final double [] strengthHist = stStrength;
final int sTilesX = (tileProcessor.getTilesX() + superTileSize -1)/superTileSize;
// final int sTiles = disparityHistograms.length;
final int sTiles = maxMinMax.length;
final int sTilesY = sTiles / sTilesX;
// final int numBins = dispHist[0].length; // [0] - weight
final int sTileHeight = (sTileHeight0 > 0)? sTileHeight0 : numBins;
final double [] maxHist = new double [sTiles];
final int width = sTilesX * (numBins + 1) + 1;
final int height = sTilesY * (sTileHeight + 1) +1;
final boolean [] isMax = new boolean [numBins];
final boolean [] isMin = new boolean [numBins];
double [] rslt = new double [width*height];
double maxW = 0.0; // use for borders between cells
for (int i = 0; i < sTiles; i++){
if (maxW < strengthHist[i]) maxW = strengthHist[i];
if (disparityHistograms[i] != null) {
for (int j = 0; j< numBins; j++){
if (!Double.isNaN( disparityHistograms[i][j]) && (maxHist[i] < disparityHistograms[i][j])) maxHist[i] = disparityHistograms[i][j];
}
}
}
for (int nsTile = 0; nsTile < sTiles; nsTile++){
int stileY = nsTile / sTilesX;
int stileX = nsTile % sTilesX;
int x0 = stileX * (numBins + 1);
int y0 = stileY * (numBins + 1);
int indx0 = x0 + y0*width;
// draw rectangular frame - horisontal dotted lines
for (int j = 0; j < numBins + 2; j+=2) {
rslt [indx0 + j] = maxW;
rslt [indx0 + (sTileHeight + 1) * width+ j] = maxW;
}
// vertical dotted lines
for (int j = 0; j < sTileHeight + 2; j+=2) {
rslt [indx0 + j * width] = maxW;
rslt [indx0 + (numBins + 1)+ j * width] = maxW;
}
// draw normalized histograms, using overall weight as intensity
if ((disparityHistograms[nsTile] != null) && (maxMinMax[nsTile] != null)) {
for (int bin = 0; bin <numBins; bin ++){
isMax[bin] = false;
isMin[bin] = false;
}
for (int i = 0; i <maxMinMax[nsTile].length; i++){
int imm = (int) Math.round(maxMinMax[nsTile][i][0]);
if (imm <0 ) imm = 0;
else if (imm >= numBins) imm = numBins - 1;
if ((i & 1) == 0) isMax[imm] = true;
else isMin[imm] = true;
}
for (int bin = 0; bin <numBins; bin ++){
int h = (int) (sTileHeight * disparityHistograms[nsTile][bin] / maxHist[nsTile]);
int x = bin + 1;
int jMin = isMin[bin] ? h : 0;
int jMax = isMax[bin] ? h : sTileHeight;
if (isMax[bin] || isMin[bin]) {
for (int j = jMin; j <= jMax; j++) {
int y = sTileHeight + 1 - j;
rslt [indx0 + y * width + x] = strengthHist[nsTile];
}
}
}
}
}
return rslt;
}
// updates bgDisparity, bgStrength
public double [][] getBgDispStrength(
final double minBgDisparity,
final double minBgFract)
{
final double step_disparity = step_near; // TODO: implement
if (maxMinMax == null) return null;
final int superTileSize = tileProcessor.superTileSize;
final int globalDebugLevel = tileProcessor.globalDebugLevel;
final int sTiles = maxMinMax.length;
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
bgDisparity = new double[sTiles];
bgStrength = new double[sTiles];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nsTile = ai.getAndIncrement(); nsTile < sTiles; nsTile = ai.getAndIncrement()) {
if (nsTile == 49) { // 414){ // 331){
System.out.println("getBgDispStrength(); nsTIle="+nsTile);
}
double [][] mmm = maxMinMax[nsTile];
bgDisparity[nsTile] = Double.NaN;
bgStrength[nsTile] = 0.0;
if (mmm != null){
int maxNum = 0;
int numMax = (maxMinMax[nsTile].length + 1) / 2;
double selStrenth = 0.0;
int startIndex = 0;
for (maxNum = 0; maxNum < numMax; maxNum++){
if (mmm[2 * maxNum][0] >= minBgDisparity){
if (selStrenth == 0.0) startIndex = maxNum; // will keep first non-zero maximum number
selStrenth += mmm[2 * maxNum][1];
}
}
if (selStrenth > 0.0){
selStrenth *= minBgFract;
double accumStrength = 0.0;
for (maxNum = startIndex; maxNum < numMax; maxNum++){
accumStrength += mmm[2 * maxNum][1];
if (accumStrength >= selStrenth){
break;
}
}
if (maxNum >= numMax){
maxNum = numMax - 1; // probably just wrong fraction (>1.0)
}
// if unlikely there are several maximums before minBgFract - use the strongest
int maxIndex = startIndex;
if (startIndex < maxNum){
for (startIndex++; startIndex < numMax ;startIndex++){
if (mmm[2 * startIndex][1] > mmm[2 * maxIndex][1]) maxIndex = startIndex;
}
}
//maxIndex is what we need. Which strength to use - individual or accumulated? Use individual.
bgDisparity[nsTile] = min_disparity + mmm[2 * maxIndex][0] * step_disparity;
bgStrength[nsTile] = mmm[2 * maxIndex][1];
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
final double [][] bgDispStrength = {bgDisparity, bgStrength};
if (globalDebugLevel > 0) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
final int stilesX = (tileProcessor.getTilesX() + superTileSize -1)/superTileSize;
final int stilesY = (tileProcessor.getTilesY() + superTileSize -1)/superTileSize;
sdfa_instance.showArrays(bgDispStrength, stilesX, stilesY, true, "bgDispStrength");
}
return bgDispStrength;
}
// from per-super-tile disparity/strength interpolate per-tile disparity/strength using same sine-based window
public double [][] getBgTileDispStrength()
{
if ((this.bgDisparity == null) || (this.bgStrength == null)) return null;
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.superTileSize;
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
// final int numBins = (int) ((max_disparity - min_disparity)/step_disparity) + 1;
// final double [][] dispHist = new double [nStiles][numBins];
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
// final int st_end = st_start + superTileSize;
final int superTileSize2 = 2 * superTileSize;
final double [][] lapWeight = getLapWeights();
final double [] tileDisparity = new double [tilesY * tilesX]; // assuming all 0.0
final double [] tileStrength = new double [tilesY * tilesX]; // assuming all 0.0
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nsTile = ai.getAndIncrement(); nsTile < nStiles; nsTile = ai.getAndIncrement()) {
int stileY = nsTile / stilesX;
int stileX = nsTile % stilesX;
int tY0 = stileY * superTileSize;
int tX0 = stileX * superTileSize;
double [][] lapWeight_dbg = lapWeight;
if (nsTile == 414) { //317) { // 755){
System.out.println("getBgTileDispStrength(x): stileY="+stileY+", stileX="+stileX+" lapWeight_dbg.length="+lapWeight_dbg.length);
}
for (int tY = 0; tY < superTileSize; tY++){
int tileY = tY0 +tY;
if (tileY < tilesY) {
for (int tX = 0; tX < superTileSize; tX++){
int tileX = tX0 +tX;
if (tileX < tilesX) {
int tIndex = tileY * tilesX + tileX;
// iterate for +/- 1 supterile around current, acummulate disparity/strength
double sd = 0.0, sw = 0.0;
for (int stDY = -1; stDY <=1; stDY ++){
int stY = stileY + stDY;
int dtY =tY + superTileSize/2 -superTileSize * stDY;
if ((stY >= 0) && (stY < stilesY) && (dtY >= 0) && (dtY < superTileSize2)){
for (int stDX = -1; stDX <=1; stDX ++){
int stX = stileX + stDX;
int dtX =tX + superTileSize/2 -superTileSize * stDX;
if ((stX >= 0) && (stX < stilesX) && (dtX >= 0) && (dtX < superTileSize2)){
int stIndex = stY * stilesX + stX;
double w = bgStrength[stIndex] * lapWeight[dtY][dtX];
if (nsTile == 415) {
System.out.println("tX="+tX+", tY="+tY+", tileX="+tileX+", tileY="+tileY+" stDX="+stDX+" stDY="+stDY+
", bgStrength["+stIndex+"] = "+bgStrength[stIndex]+
", lapWeight["+dtY+"]["+dtX+"]="+lapWeight[dtY][dtX]+" stY="+stY+" stX="+stX+" w="+w);
}
sw += w;
if (w >0.0) sd += w * bgDisparity[stIndex]; // so NaN will be OK
}
}
}
}
tileStrength[tIndex] = sw;
if (sw > 0.0) {
tileDisparity[tIndex] = sd/sw;
} else {
tileDisparity[tIndex] = Double.NaN;
}
if (nsTile == 415) {
System.out.println("sw= "+sw+", sd="+sd);
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
final double [][] bgTileDispStrength = {tileDisparity, tileStrength};
return bgTileDispStrength;
}
} // end of class SuperTiles
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -43,7 +43,7 @@ import org.w3c.dom.Element;
public class X3dOutput {
GeometryCorrection geometry_correction;
public ArrayList <TileProcessor.CLTPass3d> clt_3d_passes;
public ArrayList <CLTPass3d> clt_3d_passes;
public EyesisCorrectionParameters.CLTParameters clt_parameters;
public EyesisCorrectionParameters.CorrectionParameters correctionsParameters;
public int debugLevel = 1;
......@@ -57,7 +57,7 @@ public class X3dOutput {
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
GeometryCorrection geometry_correction,
ArrayList <TileProcessor.CLTPass3d> clt_3d_passes){
ArrayList <CLTPass3d> clt_3d_passes){
this.clt_parameters = clt_parameters;
this.correctionsParameters = correctionsParameters;
this.geometry_correction = geometry_correction;
......@@ -93,7 +93,7 @@ public class X3dOutput {
el_Scene.appendChild(el_TopGroup);
TileProcessor.CLTPass3d bgnd_pass = clt_3d_passes.get(0);
CLTPass3d bgnd_pass = clt_3d_passes.get(0);
Element el_Bgnd = x3dDoc.createElement("Background");
el_Bgnd.setAttribute("class","Background");
......
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