Commit c5431a27 authored by Andrey Filippov's avatar Andrey Filippov

Refactoring, incompatible data file

parent 32292d3b
package com.elphel.imagej.orthomosaic; package com.elphel.imagej.orthomosaic;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.common.PolynomialApproximation; import com.elphel.imagej.common.PolynomialApproximation;
import com.elphel.imagej.readers.ElphelTiffReader;
import com.elphel.imagej.tileprocessor.ImageDtt; import com.elphel.imagej.tileprocessor.ImageDtt;
public class FloatImageData { import ij.ImagePlus;
public int width;
public int height; public class FloatImageData implements Serializable {
public int zoom_lev; private static final long serialVersionUID = 1L;
private double [] vert = new double[2]; // x,y offset (in meters) of the point under the camera public static boolean FIX_VERT_Y = false; // true; // temporarily fix vertical Y coordinate bug (use -GCORR in the filename?)
public float[] data; public int width;
public int height;
public int zoom_lev;
private boolean zoom_valid;
public String path;
public Properties properties; // serializable
private double [] lla; // lat/long/alt
public LocalDateTime dt;
private double [] vert = new double[2]; // x,y offset (in meters) of the point under the camera
private double pix_meters;
private double averagePixel=Double.NaN;
private transient float[] data; // make transient
public FloatImageData ( public FloatImageData (
int width, String path) {
int height, this.path = path;
int zoom_lev, try {
double [] vert, // x,y pixel offset of the point under the camera properties = ElphelTiffReader.getTiffMeta(path);
float[] data) { } catch (IOException e) {
this.width = width; // TODO Auto-generated catch block
this.height = height; e.printStackTrace();
this.zoom_lev = zoom_lev; }
this.vert = vert.clone(); try {
this.data = data; lla = ElphelTiffReader.getLLA(properties);
} catch (NullPointerException e) {
System.out.println("No GPS data in "+path);
// TODO Auto-generated catch block
e.printStackTrace();
}
dt = ElphelTiffReader.getLocalDateTime(properties);
vert = ElphelTiffReader.getXYOffsetMeters(properties);
pix_meters = ElphelTiffReader.getPixelSize(properties)[0];
if (FIX_VERT_Y) {
int height_pix = ElphelTiffReader.getHeight(properties);
double height_meters = height_pix * pix_meters;
vert[1] = height_meters-vert[1];
}
width = ElphelTiffReader.getWidth(properties);
height = ElphelTiffReader.getHeight(properties);
zoom_lev = getZoomLevel(pix_meters);
zoom_valid = isZoomValid(pix_meters);
} }
public int getWidth() { private void writeObject(ObjectOutputStream oos) throws IOException {
return width; oos.defaultWriteObject();
} }
public int getHeight() {
return height; private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
data = null;
}
public void updateLLA() {
try {
properties = ElphelTiffReader.getTiffMeta(path);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
lla = ElphelTiffReader.getLLA(properties);
} catch (NullPointerException e) {
System.out.println("No GPS data in "+path);
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
public double[] getVertMeters() { float [] readFData() {
return vert; if (data == null) {
ImagePlus imp = new ImagePlus(path);
int width = imp.getWidth();
int height = imp.getHeight();
if ((width != this.width) || (height != this.height)) {
throw new IllegalArgumentException (String.format("IJ image size does not match Exif one: (%d,%d) != (%d,%d)",
width,height, this.width,this.height));
}
data = (float[]) (imp.getProcessor().getPixels());
}
return data;
} }
public double [] getDData() { public double [] getDData() {
if (data==null) {
readFData();
if (data== null) {
return null;
}
}
final double [] ddata = new double [data.length]; final double [] ddata = new double [data.length];
final Thread[] threads = ImageDtt.newThreadArray(); final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
...@@ -53,6 +124,103 @@ public class FloatImageData { ...@@ -53,6 +124,103 @@ public class FloatImageData {
return ddata; return ddata;
} }
public double [] getLLA() {
return lla; // null if does not exist, saved with data file
}
public LocalDateTime getDT() {
return dt;
}
public boolean isZoomValid() {
if (!zoom_valid) {
System.out.println("Original zoom level is invalid, need_extra_zoom = "+needZoomIn(pix_meters));
}
return zoom_valid;
}
/**
* Get vertical point offset from the top-left corner of the original orthoimage in pixels
* of the original resolution
* @return vertical point X,Y offset in pixels from the top-left image corner in original resolution
*/
public int [] getVertPixels() {
double [] vm = getVertMeters();
return new int [] {
(int) Math.round(vm[0]/pix_meters),
(int) Math.round(vm[1]/pix_meters)};
}
public double getPixMeters() {
return pix_meters;
}
public FloatImageData (
FloatImageData master,
int zoom_level,
float[] data) {
this.width = master.width;
this.height = master.height;
this.zoom_valid = master.zoom_valid;
this.path = master.path;
this.properties = master.properties;
this.lla = master.lla;
this.dt = master.dt;
this.vert = master.vert;
this.pix_meters = master.pix_meters;
this.averagePixel = master.averagePixel;
this.zoom_lev = zoom_level;
this.data = data;
}
public double getAveragePixel() {
if (Double.isNaN(averagePixel)) {
final float [] pixels = readFData();
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger ati = new AtomicInteger(0);
final double [] avg_arr = new double [threads.length];
final double [] npix_arr = new double [threads.length];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int thread_num = ati.getAndIncrement();
for (int ipix = ai.getAndIncrement(); ipix < pixels.length; ipix = ai.getAndIncrement()) {
float p = pixels[ipix];
if (!Float.isNaN(p)) {
avg_arr[thread_num] += p;
npix_arr[thread_num] +=1;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
double avg=0, num=0;
for (int i = 0; i < avg_arr.length; i++) {
avg+=avg_arr[i]; // *npix_arr[i];
num+=npix_arr[i];
}
averagePixel = avg/num;
}
return averagePixel;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public double[] getVertMeters() {
return vert;
}
public static int getZoomLevel( public static int getZoomLevel(
double pix_in_meters) { double pix_in_meters) {
return getZoomLevel (pix_in_meters, null, null); return getZoomLevel (pix_in_meters, null, null);
...@@ -70,6 +238,10 @@ public class FloatImageData { ...@@ -70,6 +238,10 @@ public class FloatImageData {
return extra_zoom[0]; return extra_zoom[0];
} }
public int getZoomLevel() {
return zoom_lev;
}
/** /**
* Find scale level (0: 1pix/cm, 1 - 2pix/cm, -1 - 0.5 pix/cm) from pixel size in meters * Find scale level (0: 1pix/cm, 1 - 2pix/cm, -1 - 0.5 pix/cm) from pixel size in meters
* If scale does not match, provide false in optional valid_zoom[0] * If scale does not match, provide false in optional valid_zoom[0]
......
...@@ -49,7 +49,7 @@ public class ObjectLocation { ...@@ -49,7 +49,7 @@ public class ObjectLocation {
OrthoMap [] ortho_maps=maps_collection.getMaps(); OrthoMap [] ortho_maps=maps_collection.getMaps();
final int width = ortho_maps[nmap].getImageData().width; final int width = ortho_maps[nmap].getImageData().width;
final int height = ortho_maps[nmap].getImageData().height; final int height = ortho_maps[nmap].getImageData().height;
final float [] src_img = ortho_maps[nmap].getImageData().data; final float [] src_img = ortho_maps[nmap].getImageData().readFData();
double [] dcrop = new double [size*size]; double [] dcrop = new double [size*size];
Arrays.fill(dcrop, Double.NaN); Arrays.fill(dcrop, Double.NaN);
int hsize = size/2; int hsize = size/2;
......
...@@ -845,7 +845,7 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -845,7 +845,7 @@ public class OrthoMapsCollection implements Serializable{
scaled_out_center[0], // double px0, // in render pixels scaled_out_center[0], // double px0, // in render pixels
scaled_out_center[1]); // // double py0); scaled_out_center[1]); // // double py0);
} }
final float [] src_img = use_alt? ortho_maps[nmap].getAltData().data : ortho_maps[nmap].getImageData().data; final float [] src_img = use_alt? ortho_maps[nmap].getAltData().readFData() : ortho_maps[nmap].getImageData().readFData();
final Rectangle warp_woi =((indx==1) && (warp != null))? warp.getRenderWOI():null; final Rectangle warp_woi =((indx==1) && (warp != null))? warp.getRenderWOI():null;
final Thread[] threads = ImageDtt.newThreadArray(); final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
...@@ -1011,8 +1011,8 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -1011,8 +1011,8 @@ public class OrthoMapsCollection implements Serializable{
} }
boolean tilt_alt = (ground_planes != null) && (ground_planes[indx] != null); boolean tilt_alt = (ground_planes != null) && (ground_planes[indx] != null);
final float [] src_img = use_alt? final float [] src_img = use_alt?
(tilt_alt? ortho_maps[nmap].getAltData().data.clone(): ortho_maps[nmap].getAltData().data) : (tilt_alt? ortho_maps[nmap].getAltData().readFData().clone(): ortho_maps[nmap].getAltData().readFData()) :
ortho_maps[nmap].getImageData().data; ortho_maps[nmap].getImageData().readFData();
final Rectangle warp_woi =((indx==1) && (warp != null))? warp.getRenderWOI():null; final Rectangle warp_woi =((indx==1) && (warp != null))? warp.getRenderWOI():null;
final Thread[] threads = ImageDtt.newThreadArray(); final Thread[] threads = ImageDtt.newThreadArray();
......
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