Commit f25142a1 authored by Andrey Filippov's avatar Andrey Filippov

Fixing sensor geometric corrections

parent 484ec936
......@@ -4042,7 +4042,7 @@ public class ImageDtt {
public double data_y = 0.0; // kernel data is relative to this displacement Y (0.5 pixel increments)
public double center_x = 0.0; // actual center X (use to find derivatives)
public double center_y = 0.0; // actual center X (use to find derivatives)
public double dxc_dx = 0.0; // add this to data_x per each pixel X-shift relative to the kernel centger location
public double dxc_dx = 0.0; // add this to data_x per each pixel X-shift relative to the kernel center location
public double dxc_dy = 0.0; // same per each Y-shift pixel
public double dyc_dx = 0.0;
public double dyc_dy = 0.0;
......@@ -4075,6 +4075,17 @@ public class ImageDtt {
}
}
public void offsetKernelSensor(
double [][] clt_tile, // clt tile, including [4] - metadata
double dx,
double dy) {
CltExtra ce = new CltExtra (clt_tile[4]);
ce.center_x += dx;
ce.center_y += dy;
ce.data_x += dx;
ce.data_y += dy;
clt_tile[4] = ce.getArray();
}
public void clt_fill_coord_corr(
final int kern_step, // distance between kernel centers, in pixels.
final double [][][][][] clt_data,
......@@ -4201,6 +4212,8 @@ public class ImageDtt {
// same with extra shift
px = centerX - transform_size - (ce.data_x + ce.dxc_dx * kdx + ce.dxc_dy * kdy) ; // fractional left corner
py = centerY - transform_size - (ce.data_y + ce.dyc_dx * kdx + ce.dyc_dy * kdy) ; // fractional top corner
}else {
System.out.println("Skipping kernels!!!");
}
if (bdebug0){
System.out.print(px+"\t"+py+"\t");
......
......@@ -37,9 +37,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.SwingUtilities;
import loci.common.services.DependencyException;
import loci.common.services.ServiceException;
import loci.formats.FormatException;
import Jama.Matrix;
import ij.IJ;
import ij.ImagePlus;
......@@ -50,6 +47,9 @@ import ij.io.FileSaver;
import ij.io.Opener;
import ij.process.ColorProcessor;
import ij.text.TextWindow;
import loci.common.services.DependencyException;
import loci.common.services.ServiceException;
import loci.formats.FormatException;
public class PixelMapping {
......@@ -494,6 +494,7 @@ public class PixelMapping {
IJ.showStatus("Warping image channel "+channel);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int opy=opyAtomic.getAndIncrement(); opy<erm.mapWOI.height;opy=opyAtomic.getAndIncrement()){
......@@ -561,6 +562,7 @@ public class PixelMapping {
final int numFinished=opyDoneAtomic.getAndIncrement();
// IJ.showProgress(progressValues[numFinished]);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
......@@ -618,6 +620,7 @@ public class PixelMapping {
IJ.showStatus("Warping image channel "+channel);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int opy=opyAtomic.getAndIncrement(); opy<erm.mapWOI.height;opy=opyAtomic.getAndIncrement()){
......@@ -666,6 +669,7 @@ public class PixelMapping {
final int numFinished=opyDoneAtomic.getAndIncrement();
// IJ.showProgress(progressValues[numFinished]);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
......@@ -2499,6 +2503,7 @@ public class PixelMapping {
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
DoubleFHT doubleFHT=new DoubleFHT();
for (int row=rowNum.getAndIncrement(); row<numTileRows;row=rowNum.getAndIncrement()) {
......@@ -2523,6 +2528,7 @@ public class PixelMapping {
debugLevel);
final int numFinished=rowsFinished.getAndIncrement();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(numFinished,numTileRows);
}
......@@ -3649,6 +3655,7 @@ public class PixelMapping {
final AtomicInteger numNonEmpty = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
DoubleFHT doubleFHT=new DoubleFHT();
double [] tilePlot;
......@@ -3706,6 +3713,7 @@ public class PixelMapping {
}
final int numFinished=tilesFinished.getAndIncrement();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(numFinished,numTiles);
}
......@@ -3951,6 +3959,7 @@ public class PixelMapping {
final double [][][] result=new double[numTileRows][numTileColumns][];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
DoubleFHT doubleFHT=new DoubleFHT();
for (int tile=tileNum.getAndIncrement(); tile<numTiles;tile=tileNum.getAndIncrement()) {
......@@ -3980,6 +3989,7 @@ public class PixelMapping {
debugLevel);
final int numFinished=tilesFinished.getAndIncrement();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(numFinished,numTiles);
}
......@@ -5206,6 +5216,7 @@ public class PixelMapping {
if (showProgress) IJ.showStatus("Centering correlation data...");
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
// common for the tread
double [][] partial=new double [imagePairIndices.length][];
......@@ -5254,6 +5265,7 @@ public class PixelMapping {
if (showProgress){
final int fTile=tile;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
......@@ -5313,6 +5325,7 @@ public class PixelMapping {
if (showProgress) IJ.showStatus("Re-centering correlation data...");
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int tile=tileIndexAtomic.getAndIncrement(); tile<tiles;tile=tileIndexAtomic.getAndIncrement()){
int nImage=tile/tilesPerImage;
......@@ -5342,6 +5355,7 @@ public class PixelMapping {
if (showProgress){
final int fTile=tile;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
......@@ -5765,6 +5779,7 @@ public class PixelMapping {
final AtomicInteger numberUpdated = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int tile=tileIndexAtomic.getAndIncrement(); tile<tiles;tile=tileIndexAtomic.getAndIncrement()){
if (fillForegroundTile(
......@@ -5778,6 +5793,7 @@ public class PixelMapping {
if (showProgress){
final int finalTile=tile;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(finalTile,tiles);
}
......@@ -5938,6 +5954,7 @@ public class PixelMapping {
refineWindow[0]=Double.NaN;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
DoubleFHT doubleFHT = new DoubleFHT();
DoubleFHT refineFHT= new DoubleFHT();
......@@ -5980,6 +5997,7 @@ public class PixelMapping {
if (showProgress){
final int finalTile=tile;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(finalTile,tiles);
}
......@@ -6613,6 +6631,7 @@ public class PixelMapping {
refineWindow[0]=Double.NaN;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
DoubleFHT doubleFHT = new DoubleFHT();
DoubleFHT refineFHT= new DoubleFHT();
......@@ -6654,6 +6673,7 @@ public class PixelMapping {
if (showProgress){
final int finalTile=tile;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(finalTile,tiles);
}
......@@ -7052,6 +7072,7 @@ public class PixelMapping {
final int size=2*this.overlapStep;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
DoubleFHT doubleFHT = new DoubleFHT();
final double [] window=new double [size*size];
......@@ -7106,6 +7127,7 @@ public class PixelMapping {
if (showProgress){
final int finalTile=tile;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(finalTile,tiles);
}
......@@ -7706,6 +7728,7 @@ public class PixelMapping {
final int size=2*this.overlapStep;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
DoubleFHT doubleFHT = new DoubleFHT();
final double [] window=new double [size*size];
......@@ -7766,6 +7789,7 @@ public class PixelMapping {
if (showProgress){
final int finalTile=tile;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(finalTile,tiles);
}
......@@ -9147,7 +9171,7 @@ public class PixelMapping {
if (debugLevel>2) System.out.println("setupZMap() zMapWOI.x="+zMapWOI.x+" zMapWOI.y="+zMapWOI.y+
" zMapWOI.width="+zMapWOI.width+" zMapWOI.height="+zMapWOI.height);
this.paddedSize=this.overlapStep+2*overlap;
this.innerMask=(BitSet) new BitSet(this.paddedSize*this.paddedSize);
this.innerMask=new BitSet(this.paddedSize*this.paddedSize);
for (int i=0;i<this.overlapStep;i++) for (int j=0;j<this.overlapStep;j++){
this.innerMask.set((overlap+i)*this.paddedSize+overlap+j);
}
......@@ -9165,6 +9189,7 @@ public class PixelMapping {
if (showProgress) IJ.showStatus("Setting up zMap for image "+nImg+" ("+(nImg+1)+" of "+this.disparityScales.length+") ...");
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int tile=tileIndexAtomic.getAndIncrement(); tile<tiles;tile=tileIndexAtomic.getAndIncrement()){
setupZMapTile(
......@@ -9183,6 +9208,7 @@ public class PixelMapping {
if (showProgress){
final int finalTile=tile;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(finalTile,tiles);
}
......@@ -10502,6 +10528,7 @@ public class PixelMapping {
final AtomicInteger rsltTileAtomic = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
DoubleFHT doubleFHT=new DoubleFHT();
DoubleFHT interpolationFHT=null; // will be initialized if needed
......@@ -10959,6 +10986,7 @@ public class PixelMapping {
final AtomicInteger tileXAtomic = new AtomicInteger(tileXMin);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
double [] alphaSlice=new double[length];
double [] channelSlice=new double[length];
......@@ -12533,14 +12561,14 @@ public class PixelMapping {
int index=pixelX[i]+pixelY[i]*imageWidth;
dbgImage[0][index]=(float) speed[i]; // same as source image, just masked
dbgImage[1][index]=(float) timeToReach[i]; //
dbgImage[2][index]=(float) pathArea[i]; //
dbgImage[3][index]=(float) pathLength[i]; //
dbgImage[2][index]=pathArea[i]; //
dbgImage[3][index]=pathLength[i]; //
if (node[i]!=null){
int numParents=0;
for (int dir=0;dir<8;dir++) if ((parents[i]& (1<<dir))!=0) numParents++;
dbgImage[4][index]=numParents;
}
dbgImage[6][index]=(float) parents[i]; //
dbgImage[6][index]=parents[i]; //
}
......@@ -15498,6 +15526,7 @@ public class PixelMapping {
IJ.showStatus("Warping image channel "+channel);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int opy=opyAtomic.getAndIncrement(); opy<mapHeight;opy=opyAtomic.getAndIncrement()){
......@@ -15546,6 +15575,7 @@ public class PixelMapping {
final int numFinished=opyDoneAtomic.getAndIncrement();
// IJ.showProgress(progressValues[numFinished]);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
......@@ -15805,6 +15835,7 @@ public class PixelMapping {
/**
* Interpolate (bi-linear) X/Y corrections and flat-field data for the sensor
* @param rgbOnly - only flat field, no geometry
* @param px - pixel X coordinate (non-decimated)
* @param py - pixel Y coordinate (non-decimated)
* @return - vector of {corrX, corrY, alpha, flatfield_red, flatfield_green, flatfield_blue}
......@@ -16540,6 +16571,7 @@ public class PixelMapping {
// for (int iLat=0;iLat<equirectangularMap.pixelsVertical;iLat++){
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int iLat=ipLatAtomic.getAndIncrement(); iLat<equirectangularMap.pixelsVertical;iLat=ipLatAtomic.getAndIncrement()){
double [] a={distortionC,distortionB,distortionA,distortionA5,distortionA6,distortionA7,distortionA8};
......@@ -16657,6 +16689,7 @@ public class PixelMapping {
final int numFinished=ipLatDoneAtomic.getAndIncrement();
// IJ.showProgress(progressValues[numFinished]);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
......@@ -16734,6 +16767,7 @@ public class PixelMapping {
// for (int iLat=0;iLat<equirectangularMap.pixelsVertical;iLat++){
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int iLat=ipLatAtomic.getAndIncrement(); iLat<equirectangularMap.pixelsVertical;iLat=ipLatAtomic.getAndIncrement()){
......@@ -16826,6 +16860,7 @@ public class PixelMapping {
final int numFinished=ipLatDoneAtomic.getAndIncrement();
// IJ.showProgress(progressValues[numFinished]);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
......
......@@ -250,6 +250,7 @@ public class QuadCLT {
//GeometryCorrection
public double [][][][][] calculateCLTKernel ( // per color/per tileY/ per tileX/per quadrant (plus offset as 5-th)/per pixel
final PixelMapping.SensorData sensor, // to calculate extra shift
final ImageStack kernelStack, // first stack with 3 colors/slices convolution kernels
final int kernelSize, // 64
final EyesisCorrectionParameters.CLTParameters clt_parameters,
......@@ -294,6 +295,7 @@ public class QuadCLT {
System.out.println("calculateCLTKernel():numberOfKernels="+numberOfKernels);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
float [] kernelPixels= null; // will be initialized at first use NOT yet?
double [] kernel= new double[kernelSize*kernelSize];
......@@ -328,7 +330,7 @@ public class QuadCLT {
double s =0.0;
for (int i=0;i<kernel.length;i++) s+=kernel[i];
System.out.println("calculateCLTKernel(): sum(kernel_raw)="+s);
sdfa_instance.showArrays(
if (globalDebugLevel > 1) sdfa_instance.showArrays(
kernel,
size,
size,
......@@ -350,7 +352,7 @@ public class QuadCLT {
int klen = (2*dtt_size-1) * (2*dtt_size-1);
for (int i = 0; i < klen; i++) s += kernel_centered[i];
System.out.println("calculateCLTKernel(): sum(kernel_centered)="+s);
sdfa_instance.showArrays(
if (globalDebugLevel > 1) sdfa_instance.showArrays(
kernel_centered,
size,
size,
......@@ -370,7 +372,7 @@ public class QuadCLT {
int klen = (2*dtt_size-1) * (2*dtt_size-1);
for (int i = 0; i < klen; i++) s += kernel_centered[i];
System.out.println("calculateCLTKernel(): sum(kernel_normalized)="+s);
sdfa_instance.showArrays(
if (globalDebugLevel > 1) sdfa_instance.showArrays(
kernel_centered,
size,
size,
......@@ -394,7 +396,7 @@ public class QuadCLT {
String [] titles = {"CC", "SC", "CS", "SS"};
int length=dbg_clt[0].length;
int size=(int) Math.sqrt(length);
sdfa_instance.showArrays(
if (globalDebugLevel > 1) sdfa_instance.showArrays(
dbg_clt,
size,
size,
......@@ -406,6 +408,43 @@ public class QuadCLT {
clt_kernels[chn][tileY][tileX], // double [][] kernels, // set of 4 SS, AS, SA, AA kdernels, each dtt_size * dtt_size (may have 5-th with center shift
dtt_size, // 8
dtt);
if ((globalDebugLevel > 0) && (tileY == clt_parameters.tileY/2) && (tileX == clt_parameters.tileX/2)) {
System.out.println("calculateCLTKernel() - before corr: chn="+chn+" "+
"tileX = "+clt_parameters.tileX+" ("+(clt_parameters.tileX/2)+") "+
"tileY = "+clt_parameters.tileY+" ("+(clt_parameters.tileY/2)+") "+
"center_x = "+clt_kernels[chn][tileY][tileX][4][0]+", "+
"center_y = "+clt_kernels[chn][tileY][tileX][4][1]+", "+
"full_dx = "+clt_kernels[chn][tileY][tileX][4][2]+", "+
"full_dy = "+clt_kernels[chn][tileY][tileX][4][3]);
}
// Add sensor geometry correction (optional?)
// Kernel center in pixels
double kpx0 = (tileX -1 +0.5) * clt_parameters.kernel_step;
double kpy0 = (tileY -1 +0.5) * clt_parameters.kernel_step;
double [] corrPxPy = sensor.interpolateCorrectionVector(false, kpx0, kpy0);
image_dtt.offsetKernelSensor(
clt_kernels[chn][tileY][tileX], // double [][] clt_tile, // clt tile, including [4] - metadata
// (corrPxPy[0] - kpx0), // double dx,
// (corrPxPy[1] - kpy0)); // double dy)
-corrPxPy[0], // double dx,
-corrPxPy[1]); // double dy)
if ((globalDebugLevel > 0) && (tileY == clt_parameters.tileY/2) && (tileX == clt_parameters.tileX/2)) {
System.out.println("calculateCLTKernel() - after corr: chn="+chn+" "+
"tileX = "+clt_parameters.tileX+" ("+(clt_parameters.tileX/2)+") "+
"tileY = "+clt_parameters.tileY+" ("+(clt_parameters.tileY/2)+") "+
"center_x = "+clt_kernels[chn][tileY][tileX][4][0]+", "+
"center_y = "+clt_kernels[chn][tileY][tileX][4][1]+", "+
"full_dx = "+clt_kernels[chn][tileY][tileX][4][2]+", "+
"full_dy = "+clt_kernels[chn][tileY][tileX][4][3]);
System.out.println("calculateCLTKernel() - after corr: chn="+chn+" "+
"kpx0 = "+kpx0+
"kpy0 = "+kpy0+
"corrPxPy[0] = "+corrPxPy[0]+
"corrPxPy[1] = "+corrPxPy[1]);
}
if ((globalDebugLevel > 0) && (tileY == clt_parameters.tileY/2) && (tileX == clt_parameters.tileX/2)) {
double [][] dbg_clt = {
clt_kernels[chn][tileY][tileX][0],
......@@ -415,7 +454,7 @@ public class QuadCLT {
String [] titles = {"CC", "SC", "CS", "SS"};
int length=dbg_clt[0].length;
int size=(int) Math.sqrt(length);
sdfa_instance.showArrays(
if (globalDebugLevel > 1) sdfa_instance.showArrays(
dbg_clt,
size,
size,
......@@ -474,6 +513,7 @@ public class QuadCLT {
System.out.println("flattenCLTKernels():numberOfKernels="+numberOfKernels);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
int chn,tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < numberOfKernels; nTile = ai.getAndIncrement()) {
......@@ -604,6 +644,7 @@ public class QuadCLT {
System.out.println("flattenCLTKernels():numberOfKernels="+numberOfKernels);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
int chn,tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < numberOfKernels; nTile = ai.getAndIncrement()) {
......@@ -642,6 +683,9 @@ public class QuadCLT {
boolean updateStatus,
int debugLevel
){
// get sensor geometry correction to apply to kernels as extra shifts
PixelMapping.SensorData [] sensors = eyesisCorrections.pixelMapping.sensors;
String [] sharpKernelPaths= correctionsParameters.selectKernelChannelFiles(
0, // 0 - sharp, 1 - smooth
eyesisCorrections.usedChannels.length, // numChannels, // number of channels
......@@ -671,6 +715,7 @@ public class QuadCLT {
" kernel_sharp_stack.getHeight() = "+kernel_sharp_stack.getHeight());
double [][][][][] kernels = calculateCLTKernel ( // per color/per tileY/ per tileX/per quadrant (plus offset as 5-th)/per pixel
sensors[chn], // to calculate extra shift (kernels are centered around green)
kernel_sharp_stack, // final ImageStack kernelStack, // first stack with 3 colors/slices convolution kernels
srcKernelSize, // final int kernelSize, // 64
clt_parameters, // final EyesisCorrectionParameters.CLTParameters clt_parameters,
......
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