Commit 4125cbb1 authored by Andrey Filippov's avatar Andrey Filippov

Fixing conversion from calibration to correction.

parent 4bbac7dc
......@@ -84,6 +84,7 @@ public class CLTParameters {
public double scale_b = 1.0;
public double vignetting_max = 0.4; // value in vignetting data to correspond to 1x in the kernel
public double vignetting_range = 5.0; // do not try to correct vignetting less than vignetting_max/vignetting_range
// NOT used !
public int kernel_step = 16; // source kernels step in pixels (have 1 kernel margin on each side)
public double disparity = 0.0; // nominal disparity between side of square cameras (pix)
public double z_correction = 0.0; // Inverse distance to infinity (misalignment correction)
......
......@@ -14,6 +14,7 @@ public class ColorProcParameters {
public boolean lwir_autorange = true;
public double lwir_too_cold = 100.0; // discard this number of pixels too cold
public double lwir_too_hot = 3.0; // discard this number of pixels too hot
public boolean lwir_pseudocolor = true;
public int lwir_palette = 0; // 0 - white - hot, 1 - black - hot, 2+ - colored
public boolean lwir_subtract_dc = false;
public boolean lwir_eq_chn = true; // adjust average temperature between channels
......@@ -84,7 +85,7 @@ public class ColorProcParameters {
boolean lwir_autorange, // true;
double lwir_too_cold, // 100.0; // discard this number of pixels too cold
double lwir_too_hot, // 3.0; // discard this number of pixels too hot
boolean lwir_pseudocolor,
int lwir_palette, // 0 - white - hot, 1 - black - hot, 2+ - colored
boolean lwir_subtract_dc, // = false;
boolean lwir_eq_chn, // true
......@@ -144,6 +145,7 @@ public class ColorProcParameters {
this.lwir_too_cold = lwir_too_cold;
this.lwir_too_hot = lwir_too_hot;
this.lwir_pseudocolor = lwir_pseudocolor;
this.lwir_palette = lwir_palette;
this.lwir_subtract_dc = lwir_subtract_dc;
this.lwir_eq_chn =lwir_eq_chn;
......@@ -204,6 +206,7 @@ public class ColorProcParameters {
properties.setProperty(prefix+"lwir_too_cold", this.lwir_too_cold+"");
properties.setProperty(prefix+"lwir_too_hot", this.lwir_too_hot+"");
properties.setProperty(prefix+"lwir_pseudocolor", this.lwir_pseudocolor+"");
properties.setProperty(prefix+"lwir_palette", this.lwir_palette+"");
properties.setProperty(prefix+"lwir_subtract_dc", this.lwir_subtract_dc+"");
properties.setProperty(prefix+"lwir_eq_chn", this.lwir_eq_chn+"");
......@@ -273,6 +276,7 @@ public class ColorProcParameters {
if (properties.getProperty(prefix+"lwir_too_cold")!=null) this.lwir_too_cold=Double.parseDouble(properties.getProperty(prefix+"lwir_too_cold"));
if (properties.getProperty(prefix+"lwir_too_hot")!=null) this.lwir_too_hot=Double.parseDouble(properties.getProperty(prefix+"lwir_too_hot"));
if (properties.getProperty(prefix+"lwir_pseudocolor")!=null) this.lwir_pseudocolor=Boolean.parseBoolean(properties.getProperty(prefix+"lwir_pseudocolor"));
if (properties.getProperty(prefix+"lwir_palette")!=null) this.lwir_palette=Integer.parseInt(properties.getProperty(prefix+"lwir_palette"));
if (properties.getProperty(prefix+"lwir_subtract_dc")!=null) this.lwir_subtract_dc=Boolean.parseBoolean(properties.getProperty(prefix+"lwir_subtract_dc"));
if (properties.getProperty(prefix+"lwir_eq_chn")!=null) this.lwir_eq_chn=Boolean.parseBoolean(properties.getProperty(prefix+"lwir_eq_chn"));
......@@ -349,7 +353,8 @@ public class ColorProcParameters {
gd.addNumericField("Number of too cold pixels/image to ignore during autorange", this.lwir_too_cold, 4); // 100.0
gd.addNumericField("Number of too hot pixels/image to ignore during autorange", this.lwir_too_hot, 4); // 0.53
gd.addNumericField("LWIR pallet (0-white hot, 1-black hot, 2+ - pseudo colors ", this.lwir_palette, 0);
gd.addCheckbox ("Use pseudocolors for LWIR (unchecked - floating point monochrome)", this.lwir_pseudocolor);
gd.addNumericField("LWIR pallete (0-white hot, 1-black hot, 2+ - pseudo colors ", this.lwir_palette, 0);
gd.addCheckbox ("Subtract each image DC when conditioning", this.lwir_subtract_dc);
gd.addCheckbox ("Adjust average temperature between cameras", this.lwir_eq_chn);
......@@ -437,6 +442,7 @@ public class ColorProcParameters {
this.lwir_too_cold= gd.getNextNumber();
this.lwir_too_hot= gd.getNextNumber();
this.lwir_pseudocolor= gd.getNextBoolean();
this.lwir_palette= (int) gd.getNextNumber();
this.lwir_subtract_dc= gd.getNextBoolean();
this.lwir_eq_chn= gd.getNextBoolean();
......@@ -503,6 +509,7 @@ public class ColorProcParameters {
cp.lwir_too_cold = this.lwir_too_cold;
cp.lwir_too_hot = this.lwir_too_hot;
cp.lwir_pseudocolor = this.lwir_pseudocolor;
cp.lwir_palette = this.lwir_palette;
cp.lwir_subtract_dc = this.lwir_subtract_dc;
cp.lwir_eq_chn = this.lwir_eq_chn;
......@@ -567,6 +574,7 @@ public class ColorProcParameters {
this.lwir_too_cold = cp.lwir_too_cold;
this.lwir_too_hot = cp.lwir_too_hot;
this.lwir_pseudocolor = cp.lwir_pseudocolor;
this.lwir_palette = cp.lwir_palette;
this.lwir_subtract_dc = cp.lwir_subtract_dc;
this.lwir_eq_chn = cp.lwir_eq_chn;
......
......@@ -145,6 +145,9 @@ import ij.process.ImageProcessor;
public void showArrays(float[][] pixels, int width, int height, boolean asStack, String title, String [] titles) {
int i,j;
if (pixels == null) {
return;
}
if (asStack) {
float [] fpixels;
ImageStack array_stack=new ImageStack(width,height);
......
......@@ -276,6 +276,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
true, // boolean lwir_autorange, // true;
100.0, // double lwir_too_cold, // 100.0; // discard this number of pixels too cold
3.0, // double lwir_too_hot, // 3.0; // discard this number of pixels too hot
true, // lwir_pseudocolor,
1, // int lwir_palette, // 0 - white - hot, 1 - black - hot, 2+ - pseudocolored
false, // boolean lwir_subtract_dc, // = false;
true, // boolean lwir_eq_chn = true; // adjust average temperature between channels
......@@ -7381,6 +7382,9 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
*/
public boolean adjustLYSeries(boolean use_aux) {
MultisceneLY.MSLY_MODE adjust_mode = MultisceneLY.MSLY_MODE.INF_NOINF;
if (CLT_PARAMETERS.ofp.pattern_mode) {
adjust_mode = MultisceneLY.MSLY_MODE.NOINF_ONLY;
}
long startTime = System.nanoTime();
// load needed sensor and kernels files
if (!prepareRigImages())
......
......@@ -116,7 +116,7 @@ public class GPUTileProcessor {
// public static int IMG_HEIGHT = 1936;
static int KERNELS_HOR = 164;
static int KERNELS_VERT = 123;
static int KERNELS_LSTEP = 4;
static int KERNELS_LSTEP = 3; // 4;// FIXME: Make it dynamic: 3 for LWIR, 4 - for RGB?)
static int THREADS_PER_TILE = 8;
static int TILES_PER_BLOCK = 4; // 8 - slower
static int CORR_THREADS_PER_TILE = 8;
......
......@@ -3190,6 +3190,41 @@ public class GpuQuad{ // quad camera description
}
public float [][] getRBG (int ncam){
int gpu_height = (img_height + GPUTileProcessor.DTT_SIZE);
int gpu_width = (img_width + GPUTileProcessor.DTT_SIZE);
int gpu_img_size = gpu_width * gpu_height;
int rslt_img_size = img_height * img_width; // width * height;
float [] cpu_corr_image = new float [ num_colors * gpu_img_size];
int gpu_width_in_bytes = gpu_width *Sizeof.FLOAT;
// for copying results to host
CUDA_MEMCPY2D copyD2H = new CUDA_MEMCPY2D();
copyD2H.srcMemoryType = CUmemorytype.CU_MEMORYTYPE_DEVICE;
copyD2H.srcDevice = gpu_corr_images_h[ncam]; // ((test & 1) ==0) ? src_dpointer : dst_dpointer; // copy same data
copyD2H.srcPitch = imclt_stride*Sizeof.FLOAT;
copyD2H.dstMemoryType = CUmemorytype.CU_MEMORYTYPE_HOST;
copyD2H.dstHost = Pointer.to(cpu_corr_image);
copyD2H.dstPitch = gpu_width_in_bytes;
copyD2H.WidthInBytes = gpu_width_in_bytes;
copyD2H.Height = num_colors * gpu_height; // /2;
cuMemcpy2D(copyD2H); // run copy
float [][] fimg = new float [num_colors][ rslt_img_size];
for (int ncol = 0; ncol < num_colors; ncol++) {
int tl_offset = (GPUTileProcessor.DTT_SIZE/2) * (gpu_width + 1) + ncol*gpu_img_size;
for (int nrow=0; nrow < img_height; nrow++) {
// System.arraycopy(cpu_corr_image, ncol*gpu_img_size, fimg[ncol], 0, rslt_img_size);
System.arraycopy(cpu_corr_image, tl_offset + (gpu_width * nrow), fimg[ncol], img_width * nrow, img_width);
}
}
return fimg;
}
@Deprecated
public float [][] getRBGuntrimmed (int ncam){
int height = (img_height + GPUTileProcessor.DTT_SIZE);
int width = (img_width + GPUTileProcessor.DTT_SIZE);
int rslt_img_size = width * height;
......@@ -3207,7 +3242,6 @@ public class GpuQuad{ // quad camera description
copyD2H.dstPitch = width_in_bytes;
copyD2H.WidthInBytes = width_in_bytes;
// copyD2H.Height = 3 * height; // /2;
copyD2H.Height = num_colors * height; // /2;
cuMemcpy2D(copyD2H); // run copy
......@@ -3218,7 +3252,9 @@ public class GpuQuad{ // quad camera description
}
return fimg;
}
@Deprecated
public void getTileSubcamOffsets(
final TpTask[] tp_tasks, // will use // modify to have offsets for 8 cameras
......
......@@ -326,6 +326,9 @@ public class ElphelTiffReader extends TiffReader{ // BaseTiffReader {
throw new ServiceException("Could not read EXIF data", e);
}
}
if (directory==null) { // trying to read ImageJ file 640x512
return;
}
Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
if (date != null) {
......
......@@ -31,6 +31,7 @@ package com.elphel.imagej.readers;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
......@@ -46,9 +47,17 @@ import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.compress.utils.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.tileprocessor.TileNeibs;
......@@ -213,6 +222,11 @@ public class ImagejJp4Tiff {
ImagePlus imp= null;
bytes = reader.openBytes(0);
int bpp = reader.getBitsPerPixel();
if (bpp == 32) { // already ImageJ file - just read it and decode properties
imp = new ImagePlus(content_fileName);
decodeProperiesFromInfo(imp);
return imp;
}
boolean is_le = reader.isLittleEndian();
int bytes_per_pixel = (bpp + 7) / 9;
......@@ -350,6 +364,43 @@ public class ImagejJp4Tiff {
imp.setProperty("Info", info);
return imp;
}
public static boolean decodeProperiesFromInfo(ImagePlus imp){
if (imp.getProperty("Info")==null) return false;
String xml= (String) imp.getProperty("Info");
DocumentBuilder db=null;
try {
db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (ParserConfigurationException e) {
return false;
}
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
Document doc = null;
try {
doc = db.parse(is);
} catch (SAXException e) {
return false;
} catch (IOException e) {
return false;
}
NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*");
for (int i=0;i<allNodes.getLength();i++) {
String name= allNodes.item(i).getNodeName();
String value="";
try {
value=allNodes.item(i).getFirstChild().getNodeValue();
} catch(Exception e) {
}
imp.setProperty(name, value);
}
return true;
}
public float [] deGammaScale(float [] pixels, int width, Hashtable<String, Object> meta_hash, boolean degamma, boolean scale) {
int height = pixels.length/width;
......
......@@ -621,6 +621,10 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)?
return toString(false);
}
public double getTiltAzPerPixel() {
return 1.0/1000.0*geometryCorrection.focalLength/geometryCorrection.pixelSize;
}
public String toString(boolean short_out) {
String s;
double [] sym_vect = toSymArray(null);
......
......@@ -360,7 +360,7 @@ public class ImageDtt extends ImageDttCPU {
if (iclt_fimg != null) {
gpuQuad.execImcltRbgAll(isMonochrome()); // execute GPU kernel
for (int ncam = 0; ncam < iclt_fimg.length; ncam++) {
iclt_fimg[ncam] = gpuQuad.getRBG(ncam); // retrieve data from GPU
iclt_fimg[ncam] = gpuQuad.getRBG(ncam); // retrieve data from GPU (not used !)
}
} else {gpuQuad.execImcltRbgAll(isMonochrome());} // just for testing
// does it need texture tiles to be output?
......@@ -1554,7 +1554,7 @@ public class ImageDtt extends ImageDttCPU {
if (iclt_fimg != null) {
gpuQuad.execImcltRbgAll(isMonochrome()); // execute GPU kernel
for (int ncam = 0; ncam < iclt_fimg.length; ncam++) {
iclt_fimg[ncam] = gpuQuad.getRBG(ncam); // retrieve data from GPU
iclt_fimg[ncam] = gpuQuad.getRBG(ncam); // retrieve data from GPU not used, but now width/height are nominal, not increased
}
} else {gpuQuad.execImcltRbgAll(isMonochrome());} // just for testing
// does it need texture tiles to be output?
......
......@@ -93,18 +93,31 @@ public class IntersceneLma {
}
public String [] printOldNew(boolean allvectors, int w, int d) {
String fmt1 = String.format("%%%d.%df", w,d);
ArrayList<String> lines = new ArrayList<String>();
for (int n = ErsCorrection.DP_DVAZ; n < ErsCorrection.DP_NUM_PARS; n+=3) {
boolean adj = false;
for (int i = 0; i <3; i++) adj |= par_mask[n+i];
if (allvectors || adj) {
String line = printNameV3(n, false, w,d)+" (was "+printNameV3(n, true, w,d)+")";
line += ", diff="+String.format(fmt1, getV3Diff(n));
lines.add(line);
}
}
return lines.toArray(new String[lines.size()]);
}
public double getV3Diff(int indx) {
double [] v_new = new double[3], v_old = new double[3];
System.arraycopy(getFullVector(parameters_vector), indx, v_new, 0, 3);
System.arraycopy(backup_parameters_full, indx, v_old, 0, 3);
double l2 = 0;
for (int i = 0; i < 3; i++) {
l2 += (v_new[i]-v_old[i]) * (v_new[i]-v_old[i]);
}
return Math.sqrt(l2);
}
public String printNameV3(int indx, boolean initial, int w, int d) {
double [] full_vector = initial? backup_parameters_full: getFullVector(parameters_vector);
double [] vector = new double[3];
......@@ -283,6 +296,11 @@ public class IntersceneLma {
if (show_intermediate && (debug_level > 0)) {
System.out.println("LMA: full RMS="+last_rms[0]+" ("+initial_rms[0]+"), pure RMS="+last_rms[1]+" ("+initial_rms[1]+") + lambda="+lambda);
}
String [] lines1 = printOldNew(false); // boolean allvectors)
System.out.print("iteration="+iter);
for (String line : lines1) {
System.out.println(line);
}
if (debug_level > 0) {
if ((debug_level > 1) || (iter == 1) || last_run) {
if (!show_intermediate) {
......
......@@ -339,7 +339,7 @@ public class MacroCorrelation {
geometryCorrection, // final GeometryCorrection geometryCorrection,
null, // final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
null, // clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
clt_parameters.kernel_step,
// clt_parameters.kernel_step,
/// clt_parameters.transform_size,
clt_parameters.clt_window,
shiftXY, //
......
......@@ -2080,8 +2080,8 @@ public class QuadCLT extends QuadCLTCPU {
iclt_fimg[ncam] = gpuQuad.getRBG(ncam);
}
int out_width = gpuQuad.getImageWidth() + gpuQuad.getDttSize();
int out_height = gpuQuad.getImageHeight() + gpuQuad.getDttSize();
int out_width = gpuQuad.getImageWidth();// + gpuQuad.getDttSize(); // 2022/05/12 removed margins from gpuQuad.getRBG(ncam);
int out_height = gpuQuad.getImageHeight(); // + gpuQuad.getDttSize(); // 2022/05/12 removed margins from gpuQuad.getRBG(ncam);
if (isLwir() && colorProcParameters.lwir_autorange) {
double rel_low = colorProcParameters.lwir_low;
double rel_high = colorProcParameters.lwir_high;
......@@ -2145,7 +2145,7 @@ public class QuadCLT extends QuadCLTCPU {
/// array_stack.addSlice("port_"+slice_seq[i], results[slice_seq[i]].getProcessor().getPixels());
/// }
}
ImagePlus imp_stack = new ImagePlus(image_name+sAux()+"-SHIFTED-D"+clt_parameters.disparity, array_stack);
ImagePlus imp_stack = new ImagePlus(image_name+sAux()+"GPU-SHIFTED-D"+clt_parameters.disparity, array_stack);
imp_stack.getProcessor().resetMinAndMax();
if (only4slice) {
return imp_stack;
......@@ -2691,8 +2691,8 @@ public class QuadCLT extends QuadCLTCPU {
iclt_fimg[ncam] = quadCLT_main.getGPU().getRBG(ncam);
}
int out_width = quadCLT_main.getGPU().getImageWidth() + quadCLT_main.getGPU().getDttSize();
int out_height = quadCLT_main.getGPU().getImageHeight() + quadCLT_main.getGPU().getDttSize();
int out_width = quadCLT_main.getGPU().getImageWidth(); // + quadCLT_main.getGPU().getDttSize(); // 2022/05/12 removed margins from gpuQuad.getRBG(ncam);
int out_height = quadCLT_main.getGPU().getImageHeight(); // + quadCLT_main.getGPU().getDttSize();// 2022/05/12 removed margins from gpuQuad.getRBG(ncam);
int tilesX = quadCLT_main.getGPU().getImageWidth() / quadCLT_main.getGPU().getDttSize();
int tilesY = quadCLT_main.getGPU().getImageHeight() / quadCLT_main.getGPU().getDttSize();
......@@ -2861,7 +2861,7 @@ public class QuadCLT extends QuadCLTCPU {
array_stack.addSlice("port_"+slice_seq[i], results[slice_seq[i]].getProcessor().getPixels());
}
}
ImagePlus imp_stack = new ImagePlus(name+"-SHIFTED-D"+clt_parameters.disparity, array_stack);
ImagePlus imp_stack = new ImagePlus(name+"GPU-SHIFTED-D"+clt_parameters.disparity, array_stack);
imp_stack.getProcessor().resetMinAndMax();
if (!batch_mode) {
imp_stack.updateAndDraw();
......@@ -5338,7 +5338,7 @@ public class QuadCLT extends QuadCLTCPU {
geometryCorrection, // final GeometryCorrection geometryCorrection,
null, // final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
clt_parameters.kernel_step, // final int kernel_step,
// clt_parameters.kernel_step, // final int kernel_step,
clt_parameters.clt_window, // final int window_type,
shiftXY, // final double [][] shiftXY, // [port]{shiftX,shiftY}
disparity_corr, // final double disparity_corr, // disparity at infinity
......
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