Commit 4aec6d1f authored by Andrey Filippov's avatar Andrey Filippov

Before trying to fix GEO output

parent bc9e1a60
......@@ -1609,6 +1609,7 @@ public class EyesisCorrectionParameters {
e.printStackTrace();
return null;
}
System.out.println("First line: "+lines.get(0)+"\n");
Path base_path = seq_path.getParent();
// first - scan all file and set sourceDirectory, x3dDirectory, linkedModels,videoDirectory,resultsDirectory
HashMap<String,String> dir_map = new HashMap<String,String>();
......
......@@ -177,7 +177,7 @@ public class ComboMatch {
boolean use_saved_collection = true; // false;
boolean save_collection = false; // true;
boolean save_collection = true;
boolean process_correlation = true; // use false to save new version of data
int num_tries_fit = 10;
boolean update_match = true; // use false to save new version of data
......
......@@ -26,6 +26,23 @@ public class FloatImageData {
this.data = data;
}
public double [] getDData() {
final double [] ddata = new double [data.length];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int ipix = ai.getAndIncrement(); ipix < data.length; ipix = ai.getAndIncrement()) {
ddata[ipix] = data[ipix];
}
}
};
}
ImageDtt.startAndJoin(threads);
return ddata;
}
public static int getZoomLevel(
double pix_in_meters) {
return getZoomLevel (pix_in_meters, null, null);
......
......@@ -52,6 +52,15 @@ public class OrientationSceneLMA {
public int debug_width = 12;
public int debug_decimals = 9;
public double [][] getOrientationQuaternions(){
double [][] qorient = new double [num_scenes][4];
for (int nscene = 0; nscene < num_scenes; nscene++) {
for (int i = 0; i < 4; i++) {
qorient[nscene][i] = parameters_vector[4*nscene + i];
}
}
return qorient;
}
public int prepareLMA(
int [] indices, // should all be used
......@@ -81,7 +90,7 @@ public class OrientationSceneLMA {
double [] pull4 = {pull_scales, pull_tilts/2, pull_tilts/2, pull_rots};
double sum_pull4 = 0;
for (double w: weights4) sum_pull4+= w;
for (double w: pull4) sum_pull4+= w;
if (sum_pull4 <= 0) {
pull = 0;
}
......
......@@ -76,7 +76,7 @@ public class OrthoAltitudeMatch {
boolean invert_y = true; // only for tilts->affines
boolean show_details =false;
boolean do_not_save = true;
boolean do_not_save = false;
// OrientationSceneLMA.testGetPairErrQuaternion ();
// OrientationSceneLMA.testGetPairPairScaleDirError();
......@@ -890,7 +890,7 @@ public class OrthoAltitudeMatch {
}
// double tilt_err_threshold = 0.01; // reduce weight if larger
//overlop_pow = 2.0
/*
for (int npair = 0; npair <quat_pairs.length; npair++ ) {
System.out.println("quat_pairs["+npair+"]="+QuatUtils.toString(quat_pairs[npair],use_degrees));
}
......@@ -923,7 +923,7 @@ public class OrthoAltitudeMatch {
SingularValueDecomposition svd = SingularValueDecomposition.singularValueDecomposeScaleTiltGamma(affine_pairs[npair], y_down_ccw); // boolean y_down_ccw)
System.out.println("svd_affine["+npair+"]=" + svd.toString(use_degrees));
}
*/
double max_flat_err = 0; // tilt_err_threshold
for (int npair = 0; npair < num_pairs; npair++) {
......@@ -964,17 +964,23 @@ public class OrthoAltitudeMatch {
last_run, // boolean last_run,
null, // String dbg_prefix,
debugLevel); // int debug_level)
System.out.println("LMA -> "+lma_rslt);
if (lma_rslt >= 0) {
if (debugLevel > -3) {
//ersTiltLMA.printSceneResults(use_degrees, use_percents);
//ersTiltLMA.printPairsResults(use_degrees, use_percents);
System.out.println("LMA -> "+lma_rslt);
double [][] qorients = orientationSceneLMA.getOrientationQuaternions();
for (int nscene = 0; nscene < indices.length; nscene++) {
ortho_maps[indices[nscene]].setQOrient(qorients[nscene]);
}
for (int npair = 0; npair < quat_pairs.length; npair++) {
int [] cpair = condensed_pairs[npair]; // index alt_multi
int [] ipair = {indices[cpair[0]], indices[cpair[1]]};
PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[ipair[0]].getMatch(ortho_maps[ipair[1]].getName(), true); // ?
pairwiseOrthoMatch.setQuaternion(quat_pairs[npair]);
}
}
System.out.println();
/*
ERSTiltLMA ersTiltLMA = new ERSTiltLMA();
ersTiltLMA.prepareLMA(
......@@ -986,15 +992,6 @@ public class OrthoAltitudeMatch {
scene_tilts_pairs, // double [][][] tilts, // [pair][scene(2)][tilt(2)]
affine_pairs, // double [][][] affine_pairs,
debugLevel); // int debug_level)
/*
double lambda = 0.1;
double lambda_scale_good = 0.5;
double lambda_scale_bad = 8.0;
double lambda_max = 1000;
boolean last_run = false;
double rms_diff = 0.0001;
int num_iter = 100;
*/
lma_rslt=ersTiltLMA.runLma( // <0 - failed, >=0 iteration number (1 - immediately)
lambda, // double lambda, // 0.1
lambda_scale_good,// double lambda_scale_good,// 0.5
......@@ -1027,6 +1024,8 @@ public class OrthoAltitudeMatch {
}
*/
//printResults(boolean degrees)
if (orthoMapsCollection_path != null) {
try {
......
......@@ -135,7 +135,7 @@ public class OrthoEqualizeLMA {
int [] indices = maps_collection.getScenesSelection(
null, // boolean select_all,
clt_parameters, // CLTParameters clt_parameters,
" to build a map"); // String purpose)
OrthoEqualizeLMA oel = new OrthoEqualizeLMA();
oel.prepareLMA (
......
......@@ -160,6 +160,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
oos.writeObject(num_scenes);
oos.writeObject(sfm_gain);
oos.writeObject(equalize);
oos.writeObject(qorient);
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
......@@ -185,6 +186,11 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
sfm_gain = (double) ois.readObject();
// equalize = new double[] {1,0};
equalize = (double []) ois.readObject();
if (OrthoMapsCollection.CURRENT_VERSION >= OrthoMapsCollection.VERSION_POST_ORIENT) {
qorient = (double[]) ois.readObject();
}
images = new HashMap <Integer, FloatImageData>(); // field images was not saved
averageImagePixel = Double.NaN; // average image pixel value (to combine with raw)
......
......@@ -59,8 +59,13 @@ public class OrthoMapsCollection implements Serializable{
public static final int MODE_IMAGE = 0;
public static final int MODE_ALT = 1;
public static final int MODE_MASK = 2;
public static int LATEST_VERSION = 100; // use when read from .list
public transient int current_version = LATEST_VERSION;
public static final int VERSION_PRE_ORIENT = 100;
public static final int VERSION_POST_ORIENT = 101;
public static int LATEST_VERSION = VERSION_POST_ORIENT; // 100; // use when read from .list
/// public transient int current_version = LATEST_VERSION;
public static int CURRENT_VERSION = LATEST_VERSION;
/*
public static final int PAIR_NONE = 0;
......@@ -2252,7 +2257,13 @@ public class OrthoMapsCollection implements Serializable{
/**
* Start with this when reading from saved data
* @param path
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static OrthoMapsCollection readOrthoMapsCollection (
String path) throws IOException, ClassNotFoundException {
// try reading current_version, if fails - restart without it (for older formats)
......@@ -2280,14 +2291,14 @@ public class OrthoMapsCollection implements Serializable{
System.out.println("readOrthoMapsCollection(): got old version, using current_version="+current_version);
} else {
current_version = (int) obj;
OrthoMapsCollection.CURRENT_VERSION = current_version; // trying here 08.29.2024 - before orthoMapsCollection exists
System.out.println("readOrthoMapsCollection(): got current_version="+current_version);
PairwiseOrthoMatch.READ_NO_ALT = false; // reading new version
orthoMapsCollection = (OrthoMapsCollection) objectInputStream.readObject();
}
// OrthoMapsCollection orthoMapsCollection = (OrthoMapsCollection) objectInputStream.readObject();
objectInputStream.close();
orthoMapsCollection.current_version = current_version;
/// orthoMapsCollection.current_version = current_version;
System.out.println("readOrthoMapsCollection(): got orthoMapsCollection, current_version="+current_version);
return orthoMapsCollection;
}
......@@ -2296,8 +2307,8 @@ public class OrthoMapsCollection implements Serializable{
FileOutputStream fileOutputStream = new FileOutputStream(path);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
current_version = LATEST_VERSION;
objectOutputStream.writeObject(current_version);
/// current_version = LATEST_VERSION;
objectOutputStream.writeObject(LATEST_VERSION); // current_version);
objectOutputStream.writeObject(this);
objectOutputStream.flush();
......@@ -4060,11 +4071,18 @@ public class OrthoMapsCollection implements Serializable{
public String [] getScenesList() {
String [] lines = new String [ortho_maps.length];
public String [] getScenesList(int [] indices) {
if (indices == null) {
indices = new int [ortho_maps.length];
for (int indx = 0; indx < ortho_maps.length; indx++) {
indices[indx] = indx;
}
}
String [] lines = new String [indices.length];
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss.SS zzz");// may be VV instead of zzz
int dbg_indx = -530;
for (int indx = 0; indx < ortho_maps.length; indx++) {
for (int i = 0; i < indices.length; i++) {
int indx = indices[i];
if (indx == dbg_indx) {
System.out.println("indx="+indx);
}
......@@ -4075,16 +4093,110 @@ public class OrthoMapsCollection implements Serializable{
String sdt = zonedDateTime.format(formatter);
String name = map.getName();
double agl = map.getAGL();
lines[indx]=String.format(
lines[i]=String.format(
"%3d %17s %26s %6.2f",indx, name, sdt, agl);
}
return lines;
}
public int [] getScenesSelection(
CLTParameters clt_parameters,
String purpose) { // " to generate stats", " to generate images"
boolean filter_scenes = true;
boolean select_scenes = true;
double flt_min_sfm = clt_parameters.imp.flt_min_sfm;
double flt_max_sfm = clt_parameters.imp.flt_max_sfm;
// int flt_alt = clt_parameters.imp.flt_alt;
int flt_orient = clt_parameters.imp.flt_orient;
boolean flt_update_config = false;
GenericJTabbedDialog gd = new GenericJTabbedDialog("Select scenes filter",800,400);
gd.addCheckbox ("Filter scenes", filter_scenes, "Filter scenes.");
gd.addCheckbox ("Select scenes", select_scenes, "Select scenes manually.");
gd.addNumericField("Minimal SfM gain", flt_min_sfm, 3,7,"","Minimal SfM gain of the scenes.");
gd.addNumericField("Maximal SfM gain", flt_max_sfm, 3,7,"","Maximal SfM gain of the scenes.");
// gd. addChoice("Filter by pairwise ALT availability",IntersceneMatchParameters.FLT_ALT_MODES, IntersceneMatchParameters.FLT_ALT_MODES[flt_alt],"Filter by pairwise ALT availability.");
gd. addChoice("Filter by orientation availability",IntersceneMatchParameters.FLT_ORIENT_MODES, IntersceneMatchParameters.FLT_ORIENT_MODES[flt_orient],"Filter by the scene orientation availability.");
gd.addCheckbox ("Update configuration", flt_update_config, "Update matching configuration parameters to be saved as defaults.");
gd.showDialog();
if (gd.wasCanceled()) return null;
filter_scenes = gd.getNextBoolean();
select_scenes = gd.getNextBoolean();
flt_min_sfm = gd.getNextNumber();
flt_max_sfm = gd.getNextNumber();
// flt_alt = gd.getNextChoiceIndex();
flt_orient = gd.getNextChoiceIndex();
flt_update_config = gd.getNextBoolean();
if (flt_update_config) {
clt_parameters.imp.flt_min_sfm = flt_min_sfm;
clt_parameters.imp.flt_max_sfm = flt_max_sfm;
// clt_parameters.imp.flt_alt = flt_alt;
clt_parameters.imp.flt_orient = flt_orient;
}
int [] indices = new int [ortho_maps.length];
for (int indx = 0; indx < ortho_maps.length; indx++) {
indices[indx] = indx;
}
if (filter_scenes) {
boolean [] selection = new boolean [ortho_maps.length];
int num_selected = 0;
for (int indx = 0; indx < ortho_maps.length; indx++) {
if ((ortho_maps[indx].getSfmGain()<flt_min_sfm) || (ortho_maps[indx].getSfmGain()>flt_max_sfm)) {
selection[indx]=false;
continue;
}
if ((ortho_maps[indx].getQOrinet()==null) && (flt_orient == 1)) {
selection[indx]=false;
continue;
}
if ((ortho_maps[indx].getQOrinet()!=null) && (flt_orient == 2)) {
selection[indx]=false;
continue;
}
selection[indx]=true;
num_selected++;
}
int [] selected_indices = new int [num_selected];
int indx = 0;
for (int i = 0; i < ortho_maps.length; i++) if (selection[i]){
selected_indices[indx++] = i;
}
indices = selected_indices;
}
if (select_scenes) {
String [] lines = getScenesList(indices);
boolean [] selection = new boolean [indices.length];
gd = new GenericJTabbedDialog("Select scenes",1200,1000);
gd.addCheckbox ("Select all", false, "Select all scenes listed");
for (int i = 0; i < lines.length; i++) {
gd.addCheckbox (lines[i], false, "Select scene number "+indices[i]);
}
gd.showDialog();
if (gd.wasCanceled()) return null;
boolean sel_all = gd.getNextBoolean();
int num_selected = 0;
for (int i = 0; i < lines.length; i++) {
selection[i] = gd.getNextBoolean();
if (selection[i]) num_selected++;
}
if (sel_all) {
Arrays.fill(selection, true);
} else {
int [] sel_indices = new int [num_selected];
int indx=0;
for (int i = 0; i < lines.length; i++) if (selection[i]) {
sel_indices[indx++] = indices[i];
}
indices = sel_indices;
}
}
return indices;
}
public int [] getScenesSelection(
boolean [] pre_selects,
String purpose) { // " to generate stats", " to generate images"
String [] lines = getScenesList();
String [] lines = getScenesList(null);
int [] sel_50 = {125,126,127,129,135,136,137,138,139,140,141,144,145,146,147,148,155,156,157,158};
int [] sel_75 = {170,177,178,183,187,188,189,192,193,199,200,204};
int [] sel_100 = {207,208,212,213,214,215,218,220};
......@@ -4165,7 +4277,7 @@ public class OrthoMapsCollection implements Serializable{
String orthoMapsCollection_path) {
boolean use_inv = false;
int [] indices = getScenesSelection(
null, // boolean select_all,
clt_parameters, // CLTParameters clt_parameters,
" to build a equalize intensities"); // String purpose)
PairwiseOrthoMatch [][] matches = new PairwiseOrthoMatch[indices.length][indices.length];
ArrayList<Point> pairs_list = new ArrayList<Point>();
......@@ -4340,7 +4452,7 @@ public class OrthoMapsCollection implements Serializable{
String orthoMapsCollection_path) {
int [] indices = getScenesSelection(
null, // boolean select_all,
clt_parameters, // CLTParameters clt_parameters,
" to find intersects"); // String purpose)
if (indices == null) {
return false;
......@@ -4480,7 +4592,7 @@ public class OrthoMapsCollection implements Serializable{
String orthoMapsCollection_path) {
int [] indices = getScenesSelection(
null, // boolean select_all,
clt_parameters, // CLTParameters clt_parameters,
" to find intersects"); // String purpose)
if (indices == null) {
return false;
......@@ -5418,7 +5530,7 @@ public class OrthoMapsCollection implements Serializable{
CLTParameters clt_parameters,
String orthoMapsCollection_path) {
int [] indices = getScenesSelection(
null, // boolean select_all,
clt_parameters, // CLTParameters clt_parameters,
" to find intersects"); // String purpose)
if ((indices == null) || (indices.length < 2)) {
System.out.println ("generatePairwiseAffines(): indices[] is null or too short, exiting");
......@@ -6747,7 +6859,7 @@ public class OrthoMapsCollection implements Serializable{
CLTParameters clt_parameters,
int debugLevel) {
int [] indices = getScenesSelection(
null, // boolean select_all,
clt_parameters, // CLTParameters clt_parameters,
" to process/display"); // String purpose)
if (indices == null) {
return false;
......@@ -6767,7 +6879,7 @@ public class OrthoMapsCollection implements Serializable{
int [] indices,
int debugLevel) {
boolean show_map_stats = false;
boolean show_combo_map = true; // false; // true;
boolean show_combo_map = false; // true; // false; // true;
boolean show_alt_map = false;
boolean show_combo_mask = false; // generate image mas (where it is defined)
boolean show_frames = false;
......@@ -6782,6 +6894,10 @@ public class OrthoMapsCollection implements Serializable{
boolean merge_layers = false; // instead of individuals
boolean ignore_affines = false;
boolean ignore_equalize = false;
boolean use_orientations = true;
boolean keep_window = true;
double scale_tilt = 1.0;
// String save_top_dir = "/media/elphel/NVME/lwir16-proc/ortho_videos/debug/sept12-13/pattern_match/";
// String sub_dir = "combo_maps";
......@@ -6812,6 +6928,9 @@ public class OrthoMapsCollection implements Serializable{
gd.addCheckbox ("Ignore affines", ignore_affines, "Ignore available affines, use unity.");
gd.addCheckbox ("Ignore equalization", ignore_equalize, "Ignore available intensity equalization, use unity.");
gd.addCheckbox ("Use scene orientations", use_orientations, "Do not resize window to accomodate transformed image.");
gd.addCheckbox ("Keep sorce window", keep_window, "Use scenes scales/orientations.");
gd.addNumericField("Scale tilt", scale_tilt, 3,7,"pix","Blur frames for anti-aliasing.");
......@@ -6839,6 +6958,10 @@ public class OrthoMapsCollection implements Serializable{
merge_layers = gd.getNextBoolean();
ignore_affines = gd.getNextBoolean();
ignore_equalize = gd.getNextBoolean();
use_orientations = gd.getNextBoolean();
keep_window = gd.getNextBoolean();
scale_tilt = gd.getNextNumber();
save_top_dir= gd.getNextString();
sub_dir= gd.getNextString();
show_images= gd.getNextBoolean();
......@@ -6881,6 +7004,94 @@ public class OrthoMapsCollection implements Serializable{
}
double pix_m = OrthoMap.getPixelSizeMeters (zoom_lev);
if (use_orientations) {
System.out.println("using orientations");
for (int nscene=0; nscene<indices.length; nscene++) {
int indx = indices[nscene];
System.out.println("Scene="+indx+", agl="+ortho_maps[indx].getAGL());
double [] qorient = ortho_maps[indx].getQOrinet(); // QuatUtils.invert(ortho_maps[indx].getQOrinet());
final int src_width = ortho_maps[indx].getImageData().width; // assuming same image size for alt and texture
final int src_height = ortho_maps[indx].getImageData().height; // assuming same image size for alt and texture
final double [] image_data = ortho_maps[indx].getImageData().getDData();
final double [] alt_data = ortho_maps[indx].getAltData().getDData();
double pix_size_meters = OrthoMap.getPixelSizeMeters(ortho_maps[indx].getOriginalZoomLevel());
//ortho_maps[indx]
int hwidth = src_width/2;
int hheight = src_height/2;
double [] xyz_center = {hwidth, hheight, alt_data[hheight*src_width + hwidth]/ pix_size_meters}; // in "pixels"
Rectangle owoi = new Rectangle();
int stride = 4; // >2, 3 - OK
double rfz = 0.3; // w= 1/(x^2+y^2+rfz^2)
double [][] rotation_map_notilt = rotateAltCenter(
qorient, // final double [] quat_in,
xyz_center, // final double [] xyz_center,
alt_data, // final double [] alt_in,
src_width, // final int width,
pix_size_meters, // final double pix_size_meters,
owoi, // final Rectangle owoi, // should not be null - will provide offset and new size
stride, // final int stride, // >=2, use 4?
rfz, // final double rfz, // 0.3 w= 1/(x^2+y^2+rfz^2)
keep_window, // final boolean keep_window,
0, // scale_tilt, // final double scale_tilt,
debugLevel); // final int debugLevel)
double [] image_out_notilt = applySceneRotation(
image_data, // final double [] texture_in,
src_width, // final int width_in,
rotation_map_notilt, // final double [][] rotation_map,
debugLevel); // final int debugLevel)
double [] alt_out_notilt = getRotatedAlt(
rotation_map_notilt);// final double [][] rotation_map)
double [][] rotation_map = rotateAltCenter(
qorient, // final double [] quat_in,
xyz_center, // final double [] xyz_center,
alt_data, // final double [] alt_in,
src_width, // final int width,
pix_size_meters, // final double pix_size_meters,
owoi, // final Rectangle owoi, // should not be null - will provide offset and new size
stride, // final int stride, // >=2, use 4?
rfz, // final double rfz, // 0.3 w= 1/(x^2+y^2+rfz^2)
keep_window, // final boolean keep_window,
scale_tilt, // final double scale_tilt,
debugLevel); // final int debugLevel)
final double [] xy_center_out = {xyz_center[0]-owoi.x, xyz_center[1]-owoi.y}; // do outside by caller - new rotation center
double [] image_out = applySceneRotation(
image_data, // final double [] texture_in,
src_width, // final int width_in,
rotation_map, // final double [][] rotation_map,
debugLevel); // final int debugLevel)
double [] alt_out = getRotatedAlt(
rotation_map);// final double [][] rotation_map)
double [] image_data_padded = debugPadInToOut(
image_data, // final double [] texture_in,
src_width, // final int width_in,
owoi); // final Rectangle woi)
double [] alt_data_padded = debugPadInToOut(
alt_data, // final double [] texture_in,
src_width, // final int width_in,
owoi); // final Rectangle woi)
String [] titles= {"img_src","img_rot","img_out","alt_src","alt_rot","alt_out"};
double [][] dbg_img = {image_data_padded,image_out_notilt,image_out,alt_data_padded, alt_out_notilt, alt_out};
String title = String.format("%03d-%s", indx, ortho_maps[indx].getName()+"-ROTATION_DBG");
ImageStack stack = ShowDoubleFloatArrays.makeStack(
dbg_img,
owoi.width,
owoi.height,
titles,
false);
ImagePlus imp = new ImagePlus(title, stack);
if (show_centers) {
PointRoi roi = new PointRoi();
roi.addPoint(xy_center_out[0], xy_center_out[1], 0+1);
roi.setOptions("label");
imp.setRoi(roi);
}
imp.show(); // debugging
}
}
if (show_combo_map) {
int [] wh = new int[2];
int [] origin = new int[2];
......@@ -7215,12 +7426,11 @@ public class OrthoMapsCollection implements Serializable{
return merged;
}
/*
public boolean showScenesStats() {
String time_zone_name = "Europe/Kyiv";
int [] indices = getScenesSelection(
null, // boolean select_all,
" to generate stats"); // String purpose)
if (indices == null) {
......@@ -7230,6 +7440,7 @@ public class OrthoMapsCollection implements Serializable{
new TextWindow("Ortho_images_stats", stats[0], stats[1], 1250,1000);
return true;
}
*/
public String[] getScenesStats(int [] indices, String time_zone_name) {
if (indices == null) {
......@@ -7646,5 +7857,325 @@ public class OrthoMapsCollection implements Serializable{
return text_pairs;
}
public static double [][] rotateAltCenter(
final double [] quat_in,
final double [] xyz_center,
final double [] alt_in,
final int width,
final double pix_size_meters,
final Rectangle owoi, // should not be null - will provide offset and new size
final int stride, // >=2, use 4?
final double rfz, // 0.3 w= 1/(x^2+y^2+rfz^2)
final boolean keep_window,
final double scale_tilt,
final int debugLevel) {
final double discard_frac = 0.1; // discard interpolation if it is extrapolation more than this
final int len_in = alt_in.length;
final int height = len_in/width;
final double r2fz = rfz*rfz;
final double x0=xyz_center[0], y0=xyz_center[1],z0=xyz_center[2]; // xyz_center[2] now in "pixels"
final double scale = QuatUtils.norm(quat_in);
System.out.println("scale = "+scale+", NOT USED - set to k=1.0");
final double k = 1.0;
final double [] quat = QuatUtils.normalize(quat_in);
quat[2]*= -1; // y is down
quat[3]*= -1; // rotation does not match tilts
quat[1]*=scale_tilt;
quat[2]*=scale_tilt;
QuatUtils.normalizeInPlace(quat);
final double [][] xyz1 = new double [alt_in.length][];
final Thread[] threads = ImageDtt.newThreadArray();
final double [][][] xy_mn_mx_thread= new double [threads.length][2][2];
final double [] pos_neg_inf = {Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY};
final double [][] xy_mn_mx= {pos_neg_inf.clone(),pos_neg_inf.clone()};
for (int nthread=0; nthread < threads.length; nthread++) {
xy_mn_mx_thread[nthread] = new double [][] {pos_neg_inf.clone(),pos_neg_inf.clone()};
}
// Arrays.fill(xy_mn_mx_thread,xy_mn_mx);
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger ati = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int nthread = ati.getAndIncrement();
double [] xyz = new double[3];
double [] xyz_out = new double[3];
for (int ipix = ai.getAndIncrement(); ipix < alt_in.length; ipix = ai.getAndIncrement()) if (!Double.isNaN(alt_in[ipix])){
xyz[0] = ipix % width - x0;
xyz[1] = ipix/ width - y0;
xyz[2] = alt_in[ipix]/ pix_size_meters - z0 ; // meters -> pix
QuatUtils.applyTo(
k, // final double k, // scale
quat, // final double [] q,
xyz, // final double [] in,
xyz_out); // final double [] out)
xyz1[ipix]= new double[3];
xyz1[ipix][0]=xyz_out[0]+x0;
xyz1[ipix][1]=xyz_out[1]+y0;
xyz1[ipix][2]=xyz_out[2]+z0;
xy_mn_mx_thread[nthread][0][0] = Math.min(xy_mn_mx_thread[nthread][0][0], xyz1[ipix][0]);
xy_mn_mx_thread[nthread][0][1] = Math.max(xy_mn_mx_thread[nthread][0][1], xyz1[ipix][0]);
xy_mn_mx_thread[nthread][1][0] = Math.min(xy_mn_mx_thread[nthread][1][0], xyz1[ipix][1]);
xy_mn_mx_thread[nthread][1][1] = Math.max(xy_mn_mx_thread[nthread][1][1], xyz1[ipix][1]);
}
}
};
}
ImageDtt.startAndJoin(threads);
for (int i = 0; i < xy_mn_mx_thread.length; i++) {
xy_mn_mx[0][0]=Math.min(xy_mn_mx[0][0], xy_mn_mx_thread[i][0][0]);
xy_mn_mx[0][1]=Math.max(xy_mn_mx[0][1], xy_mn_mx_thread[i][0][1]);
xy_mn_mx[1][0]=Math.min(xy_mn_mx[1][0], xy_mn_mx_thread[i][1][0]);
xy_mn_mx[1][1]=Math.max(xy_mn_mx[1][1], xy_mn_mx_thread[i][1][1]);
}
int x_min = keep_window ? 0: ((int) Math.floor(xy_mn_mx[0][0])-1);
int y_min = keep_window ? 0: ((int) Math.floor(xy_mn_mx[1][0])-1);
int x_max = keep_window ? width: ((int) Math.ceil(xy_mn_mx[0][1]) +1);
int y_max = keep_window ? height: ((int) Math.ceil(xy_mn_mx[1][1]) +1);
//final Rectangle
owoi.x = x_min;
owoi.y = y_min;
owoi.width= x_max-x_min;
owoi.height=y_max-y_min;
final int olen = owoi.width*owoi.height;
final double [][] alt_out = new double [olen][]; // from rectified to alt_in, each element - {x,y,z}
final double [] xyz_center_out = {xyz_center[0]-x_min, xyz_center[1]-y_min}; // do outside by caller - new rotation center
// shift x,y in xyz1 to match new window
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int ipix = ai.getAndIncrement(); ipix < alt_in.length; ipix = ai.getAndIncrement()) if (xyz1[ipix] != null){
xyz1[ipix][0] -= owoi.x;
xyz1[ipix][1] -= owoi.y;
}
}
};
}
ImageDtt.startAndJoin(threads);
final double [] weights = new double [owoi.width*owoi.height]; // when mixing same result from multiple sources
final int stride_w = (width -1) / stride + 1;
final int stride_h = (height -1) / stride + 1;
final int stride_l = stride_w * stride_h;
final int [] neib_oindices = { 0, 1, owoi.width, owoi.width+1}; // output indices, Z-order
final int [] neib_in_indices = { 0, 1, width, width+1}; // input indices, Z-order
final int [][] neib2_indices = { // Z-shape
{-width-1, -width, -1, 0}, // top-left (each also in Z-order)
{-width, -width+1, 0, 1}, // top-right (each also in Z-order)
{ -1, 0, width-1, width }, // bottom-left (each also in Z-order)
{ 0, 1, width, width+1} // bottom-right (each also in Z-order)
};
for (int offs_y = 0; offs_y < stride; offs_y++) {
for (int offs_x = 0; offs_x < stride; offs_x++) {
final int foffs_y = offs_y, foffs_x=offs_x;
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [] vh = new double[2], vv=new double[2], v=new double[2], o=new double[2];
double [] xyz = new double[3];
double [][] oxyz4 = new double[4][];
double [][] ixyz4 = new double[4][3];
for (int ipix = ai.getAndIncrement(); ipix < stride_l; ipix = ai.getAndIncrement()) {
int pix_y = (ipix/stride_w)*stride + foffs_y;
int pix_x = (ipix%stride_w)*stride + foffs_x;
if ((pix_x < width) && (pix_y < height)) {
int pix = pix_y * width + pix_x;
double [] xyz1p = xyz1[pix];
// int x1 = (int) xyz1p[0];
// int y1 = (int) xyz1p[1];
if (xyz1p != null) {
int x1 = (int) Math.floor(xyz1p[0]);
int y1 = (int) Math.floor(xyz1p[1]);
int x2 = (int) Math.ceil(xyz1p[0]);
int y2 = (int) Math.ceil(xyz1p[1]);
// accumulate 4 corners around the fractional
int [][] xy_dir= {{x1,y1},{x2,y1},{x1,y2},{x2,y2}};
for (int dir = 0; dir < 4; dir++) {
int [] indices_in = neib2_indices[dir]; // input indices (presumably) around output
// make sure all defined and surround an output node
boolean defined4 = true;
// double [][] oxyz4 = new double[4][];
// double [][] ixyz4 = new double[4][];
for (int i = 0; i < 4; i++) {
int indx= pix+indices_in[i];
if ((indx < 0) || (indx >= len_in) || (xyz1[indx] == null)) {
defined4 = false;
break;
}
oxyz4[i] = xyz1[indx];
ixyz4[i][0]= indx%width;
ixyz4[i][1]= indx/width;
ixyz4[i][2]= xyz1[indx][2]; // Z same as in in oxyz4
}
if (!defined4) {
continue;
}
int oindx = neib_oindices[dir]+ (y1*owoi.width + x1);
if ((oindx < 0) || (oindx >= olen)) {
continue;
}
o[0] = oindx % owoi.width; // output integer coordinates that should be inside oxyz4
o[1] = oindx / owoi.width;
// average horizontal and vertical vectors
for (int i = 0; i < 2; i++) {
vh[i] = (oxyz4[1][i]-oxyz4[0][i]+oxyz4[3][i]-oxyz4[2][i])/2;
vv[i] = (oxyz4[2][i]-oxyz4[0][i]+oxyz4[3][i]-oxyz4[1][i])/2;
v[i]= o[i] - oxyz4[0][i];
}
// find ax, ay for bilinear interpolation
double lvh = Math.sqrt(vh[0]*vh[0]+vh[1]*vh[1]);
double lvv = Math.sqrt(vv[0]*vv[0]+vv[1]*vv[1]);
double lv = Math.sqrt( v[0]* v[0]+ v[1]* v[1]);
double ax = (v[0]*vh[0]+v[1]*vh[1])/lv/lvh;
double ay = (v[0]*vv[0]+v[1]*vv[1])/lv/lvv;
// discard interpolation if it is extrapolation by more than discard_frac
if ((ax < -discard_frac) || (ay < -discard_frac) || (ax > 1 + discard_frac) || (ax > 1 + discard_frac)) {
continue;
}
//xyz = new double[3];
for (int i = 0; i <3; i++) {
xyz[i] = (1-ax)*(1-ay)*ixyz4[0][i]+
( ax)*(1-ay)*ixyz4[1][i]+
(1-ax)*( ay)*ixyz4[2][i]+
( ax)*( ay)*ixyz4[3][i];
}
xyz[2] *= pix_size_meters; // pix-> meters
double dax = (ax > 0.5) ? (1-ax) : ax;
double day = (ay > 0.5) ? (1-ay) : ay;
double w =r2fz / (dax*dax+day*day+r2fz);
//weights[]
if (alt_out[oindx] == null) {
alt_out[oindx] = xyz.clone();
weights[oindx] = w;
} else {
double w_new = (weights[oindx]+ w);
double w0 = weights[oindx]/w_new;
double w1 = w /w_new;
for (int i = 0; i < xyz.length; i++) {
alt_out[oindx][i] = w0 * alt_out[oindx][i] + w1 * xyz[i];
}
weights[oindx] = w_new;
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
}
return alt_out;
}
public static double [] applySceneRotation(
final double [] texture_in,
final int width_in,
final double [][] rotation_map,
// final int width_out,
final int debugLevel) {
final int height_in = texture_in.length/width_in;
final double [] texture_out = new double[rotation_map.length];
Arrays.fill(texture_out, Double.NaN);
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int opix = ai.getAndIncrement(); opix < rotation_map.length; opix = ai.getAndIncrement()) if (rotation_map[opix] != null){
// int x = opix % width_out;
// int y = opix / width_out;
double [] xyz = rotation_map[opix];
int ipx0 = (int) Math.floor(xyz[0]);
int ipy0 = (int) Math.floor(xyz[1]);
if ((ipx0 >= width_in) || (ipy0 >= height_in)) {
continue;
}
int ipx1 = ipx0 + 1;
if (ipx1 >= width_in) ipx1 = width_in-1;
int ipy1 = ipy0 + 1;
if (ipy1 >= height_in) ipy1 = height_in-1;
if ((ipx1 < 0) || (ipy1 < 0)) {
continue;
}
if (ipx0 < 0) ipx0 = ipx1;
if (ipy0 < 0) ipy0 = ipy1;
double fx = xyz[0] - ipx0;
double fy = xyz[1] - ipy0;
texture_out[opix] =
(1-fx) * (1-fy) * texture_in[ipy0 * width_in + ipx0] +
( fx) * (1-fy) * texture_in[ipy0 * width_in + ipx1] +
(1-fx) * ( fy) * texture_in[ipy1 * width_in + ipx0] +
( fx) * ( fy) * texture_in[ipy1 * width_in + ipx1];
}
}
};
}
ImageDtt.startAndJoin(threads);
return texture_out;
}
public static double [] getRotatedAlt(
final double [][] rotation_map) {
final double [] alt_out = new double[rotation_map.length];
Arrays.fill(alt_out, Double.NaN);
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int opix = ai.getAndIncrement(); opix < rotation_map.length; opix = ai.getAndIncrement()) if (rotation_map[opix] != null){
alt_out[opix] = rotation_map[opix][2];
}
}
};
}
ImageDtt.startAndJoin(threads);
return alt_out;
}
public static double [] debugPadInToOut(
final double [] texture_in,
final int width_in,
final Rectangle woi) {
final int height_in = texture_in.length/width_in;
final double [] texture_out = new double[woi.width*woi.height];
Arrays.fill(texture_out, Double.NaN);
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int opix = ai.getAndIncrement(); opix < texture_out.length; opix = ai.getAndIncrement()) {
int x_out = opix % woi.width;
int y_out = opix / woi.width;
int x_in = x_out+woi.x;
int y_in = y_out+woi.y;
if ((x_in >=0) && (y_in >= 0) && (x_in < width_in) && (y_in < height_in)) {
texture_out[opix] = texture_in[y_in * width_in + x_in];
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return texture_out;
}
}
......@@ -308,6 +308,8 @@ public class PairwiseOrthoMatch implements Serializable {
oos.writeObject(overlap);
oos.writeObject(equalize1to0);
oos.writeObject(alt_data);
oos.writeObject(quat);
oos.writeObject(qaffine);
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
......@@ -327,6 +329,11 @@ public class PairwiseOrthoMatch implements Serializable {
if (!READ_NO_ALT) {
alt_data = (double[]) ois.readObject();
}
if (OrthoMapsCollection.CURRENT_VERSION >= OrthoMapsCollection.VERSION_POST_ORIENT) {
quat= (double[]) ois.readObject();
qaffine = (double[][]) ois.readObject();
}
}
//private void readObjectNoData() throws ObjectStreamException; // used to modify default values
}
......@@ -1840,5 +1840,43 @@ q11 - q22 = c3
return;
}
public static void applyTo(
final double [] q,
final double [] in,
final double [] out) {
final double q0= q[0];
final double q1= q[1];
final double q2= q[2];
final double q3= q[3];
final double x = in[0];
final double y = in[1];
final double z = in[2];
final double s = q1 * x + q2 * y + q3 * z;
out[0] = 2 * (q0 * (x * q0 - (q2 * z - q3 * y)) + s * q1) - x;
out[1] = 2 * (q0 * (y * q0 - (q3 * x - q1 * z)) + s * q2) - y;
out[2] = 2 * (q0 * (z * q0 - (q1 * y - q2 * x)) + s * q3) - z;
}
public static void applyTo(
final double k, // scale
final double [] q,
final double [] in,
final double [] out) {
final double q0= q[0];
final double q1= q[1];
final double q2= q[2];
final double q3= q[3];
final double x = in[0];
final double y = in[1];
final double z = in[2];
final double s = q1 * x + q2 * y + q3 * z;
out[0] = k * (2 * (q0 * (x * q0 - (q2 * z - q3 * y)) + s * q1) - x);
out[1] = k * (2 * (q0 * (y * q0 - (q3 * x - q1 * z)) + s * q2) - y);
out[2] = k * (2 * (q0 * (z * q0 - (q1 * y - q2 * x)) + s * q3) - z);
}
}
......@@ -35,6 +35,7 @@ public class IntersceneMatchParameters {
public static String [] MODES3D = {"RAW", "INF", "FG", "BG"}; // RAW:-1
public static String [] MODES_AVI = {"RAW", "JPEG", "PNG"};
public static String [] FLT_ALT_MODES = {"--- (no ALT filter)", "ALT only", "no ALT only"};
public static String [] FLT_ORIENT_MODES = {"--- (no ORIENT filter)", "ORIENT only", "no ORIENT only"};
// Maybe add parameters to make sure there is enough data? Enough in each zone? Enough spread?
public boolean ims_use = true; // use IMS data
......@@ -223,6 +224,7 @@ public class IntersceneMatchParameters {
public double flt_min_sfm = 0.0; // minimal minimal SfM gain of a pair
public double flt_max_sfm = 1000.0; // maximal minimal SfM gain of a pair
public int flt_alt = 0; // 0 - do not filter, 1 - keep only with alt data, 2 - keep only without alt data
public int flt_orient = 0; // 0 - do not filter, 1 - keep only with orientation data, 2 - keep only without orientation data
public boolean flt_show_names = true;
public boolean flt_show_overlaps = true;
......@@ -987,6 +989,7 @@ min_str_neib_fpn 0.35
gd.addNumericField("Minimal SfM gain", this.flt_min_sfm, 3,7,"","Minimal SfM gain of the minimum in the scene pair.");
gd.addNumericField("Maximal SfM gain", this.flt_max_sfm, 3,7,"","Maximal SfM gain of the minimum in the scene pair.");
gd. addChoice("Filter by pairwise ALT availability",FLT_ALT_MODES, FLT_ALT_MODES[this.flt_alt],"Filter by pairwise ALT availability.");
gd. addChoice("Filter by orientation availability",FLT_ORIENT_MODES, FLT_ORIENT_MODES[this.flt_orient],"Filter by the scene orientation availability.");
gd.addCheckbox ("Show scene names", this.flt_show_names, "Show scene full names (timestamps) in selection drop-down list.");
gd.addCheckbox ("Show scene overlaps", this.flt_show_overlaps, "Show scene overlaps (in percents) in selection drop-down list.");
......@@ -1997,6 +2000,7 @@ min_str_neib_fpn 0.35
this.flt_max_sfm = gd.getNextNumber();
this.flt_alt = gd.getNextChoiceIndex();
this.flt_orient = gd.getNextChoiceIndex();
this.flt_show_names = gd.getNextBoolean();
this.flt_show_overlaps = gd.getNextBoolean();
this.flt_show_rms = gd.getNextBoolean();
......@@ -2598,6 +2602,7 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"flt_min_sfm", this.flt_min_sfm + ""); // double
properties.setProperty(prefix+"flt_max_sfm", this.flt_max_sfm + ""); // double
properties.setProperty(prefix+"flt_alt", this.flt_alt + ""); // int
properties.setProperty(prefix+"flt_orient", this.flt_orient + ""); // int
properties.setProperty(prefix+"flt_show_names", this.flt_show_names + ""); // boolean
properties.setProperty(prefix+"flt_show_overlaps", this.flt_show_overlaps + ""); // boolean
properties.setProperty(prefix+"flt_show_rms", this.flt_show_rms + ""); // boolean
......@@ -3165,6 +3170,7 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"flt_min_sfm")!= null) this.flt_min_sfm= Double.parseDouble(properties.getProperty(prefix+ "flt_min_sfm"));
if (properties.getProperty(prefix+"flt_max_sfm")!= null) this.flt_max_sfm= Double.parseDouble(properties.getProperty(prefix+ "flt_max_sfm"));
if (properties.getProperty(prefix+"flt_alt")!= null) this.flt_alt= Integer.parseInt(properties.getProperty(prefix+ "flt_alt"));
if (properties.getProperty(prefix+"flt_orient")!= null) this.flt_orient= Integer.parseInt(properties.getProperty(prefix+ "flt_orient"));
if (properties.getProperty(prefix+"flt_show_names")!= null) this.flt_show_names= Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_names"));
if (properties.getProperty(prefix+"flt_show_overlaps")!=null) this.flt_show_overlaps=Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_overlaps"));
if (properties.getProperty(prefix+"flt_show_rms")!= null) this.flt_show_rms= Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_rms"));
......@@ -3753,9 +3759,8 @@ min_str_neib_fpn 0.35
imp.flt_min_sfm = this.flt_min_sfm;
imp.flt_max_sfm = this.flt_max_sfm;
imp.flt_alt = this.flt_alt;
imp.flt_orient = this.flt_orient;
imp.flt_show_names = this.flt_show_names;
imp.flt_show_overlaps = this.flt_show_overlaps;
imp.flt_show_rms = this.flt_show_rms;
......
......@@ -8556,6 +8556,7 @@ if (debugLevel > -100) return true; // temporarily !
EyesisCorrectionParameters.CorrectionParameters.PathFirstLast[] pathFirstLast = null;
int num_seq = 1;
if (quadCLT_main.correctionsParameters.useSourceList) {
System.out.println("\nReading source list from file: "+quadCLT_main.correctionsParameters.sourceSequencesList);
pathFirstLast = quadCLT_main.correctionsParameters.getSourceSets(
quadCLT_main.correctionsParameters.sourceSequencesList);
if (pathFirstLast != null) {
......
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