Commit 6d24709c authored by Andrey Filippov's avatar Andrey Filippov

Merge branch 'dct' of git@git.elphel.com:Elphel/imagej-elphel.git into dct

parents 79eb3283 a91b3ac6
...@@ -51,6 +51,17 @@ public class DttRad2 { ...@@ -51,6 +51,17 @@ public class DttRad2 {
int [] unfold_index = null; // index for each element of idct(2nx2n) int [] unfold_index = null; // index for each element of idct(2nx2n)
double [][] unfold_k = null; // First index - mode: 0 - CC 1: SC, 2: CS, 3: SS. Other indices matching unfold_index items. Each is a product of 2 window coefficients and sign double [][] unfold_k = null; // First index - mode: 0 - CC 1: SC, 2: CS, 3: SS. Other indices matching unfold_index items. Each is a product of 2 window coefficients and sign
public int [][] getFoldIndex(){
return fold_index;
}
public int [] getUnfoldIndex(){
return unfold_index;
}
public double [][][] getFoldK(){
return fold_k;
}
public DttRad2 (int maxN){ // n - maximal public DttRad2 (int maxN){ // n - maximal
setup_arrays(maxN); // always setup arrays for fast calculations setup_arrays(maxN); // always setup arrays for fast calculations
} }
...@@ -175,6 +186,18 @@ public class DttRad2 { ...@@ -175,6 +186,18 @@ public class DttRad2 {
fi[0][0],fi[0][1],fi[0][2],fi[0][3], fi[0][0],fi[0][1],fi[0][2],fi[0][3],
fi[1][0],fi[1][1],fi[1][2],fi[1][3], hwindow[fi[0][1]], hwindow[fi[1][1]])); fi[1][0],fi[1][1],fi[1][2],fi[1][3], hwindow[fi[0][1]], hwindow[fi[1][1]]));
} }
for (int i = 0; i < n*n; i++){
System.out.println(String.format("%3x: %6x %6x %6x %6x",i,fold_index[i][0],fold_index[i][1],fold_index[i][2],fold_index[i][3]));
// System.out.println(String.format(" : %8.5f %8.5f %8.5f %8.5f", fold_k[0][i][0], fold_k[0][i][1], fold_k[0][i][2], fold_k[0][i][3]));
// System.out.println(String.format(" : %8.5f %8.5f %8.5f %8.5f", fold_k[1][i][0], fold_k[1][i][1], fold_k[1][i][2], fold_k[1][i][3]));
// System.out.println(String.format(" : %8.5f %8.5f %8.5f %8.5f", fold_k[2][i][0], fold_k[2][i][1], fold_k[2][i][2], fold_k[2][i][3]));
// System.out.println(String.format(" : %8.5f %8.5f %8.5f %8.5f", fold_k[3][i][0], fold_k[3][i][1], fold_k[3][i][2], fold_k[3][i][3]));
System.out.println(String.format(" : %2d %2d %2d %2d", (fold_k[0][i][0]<0)?-1:1, (fold_k[0][i][1]<0)?-1:1, (fold_k[0][i][2]<0)?-1:1, (fold_k[0][i][3]<0)?-1:1));
System.out.println(String.format(" : %2d %2d %2d %2d", (fold_k[1][i][0]<0)?-1:1, (fold_k[1][i][1]<0)?-1:1, (fold_k[1][i][2]<0)?-1:1, (fold_k[1][i][3]<0)?-1:1));
System.out.println(String.format(" : %2d %2d %2d %2d", (fold_k[2][i][0]<0)?-1:1, (fold_k[2][i][1]<0)?-1:1, (fold_k[2][i][2]<0)?-1:1, (fold_k[2][i][3]<0)?-1:1));
System.out.println(String.format(" : %2d %2d %2d %2d", (fold_k[3][i][0]<0)?-1:1, (fold_k[3][i][1]<0)?-1:1, (fold_k[3][i][2]<0)?-1:1, (fold_k[3][i][3]<0)?-1:1));
}
} }
} }
...@@ -239,18 +262,19 @@ public class DttRad2 { ...@@ -239,18 +262,19 @@ public class DttRad2 {
public double [][][] get_shifted_fold_2d( public double [][][] get_shifted_fold_2d(
int n, int n,
double shift_hor, double shift_hor,
double shift_vert) double shift_vert,
int debugLevel)
{ // n - DCT and window size { // n - DCT and window size
int n2 = 2* n;
double [][][] fold_sk = new double[4][n*n][4]; double [][][] fold_sk = new double[4][n*n][4];
int [] vert_ind = new int[2]; int [] vert_ind = new int[2];
double [][] vert_k = new double[2][2]; double [][] vert_k = new double[2][2];
int [] hor_ind = new int[2]; int [] hor_ind = new int[2];
double [][] hor_k = new double[2][2]; double [][] hor_k = new double[2][2];
double ahc = Math.cos(Math.PI/16*shift_hor); double ahc = Math.cos(Math.PI/n2*shift_hor);
double ahs = Math.sin(Math.PI/16*shift_hor); double ahs = Math.sin(Math.PI/n2*shift_hor);
double avc = Math.cos(Math.PI/16*shift_vert); double avc = Math.cos(Math.PI/n2*shift_vert);
double avs = Math.sin(Math.PI/16*shift_vert); double avs = Math.sin(Math.PI/n2*shift_vert);
int [][] fi; int [][] fi;
for (int i = 0; i < n; i++ ){ for (int i = 0; i < n; i++ ){
...@@ -288,6 +312,79 @@ public class DttRad2 { ...@@ -288,6 +312,79 @@ public class DttRad2 {
return fold_sk; return fold_sk;
} }
// Generate (slightly - up to +/- 0.5) shifted window for standard sin window (derivative uses same table)
// only for mode=1 (sin window)
public double [][][] get_shifted_fold_2d_direct(
int n,
double shift_hor,
double shift_vert,
int debugLevel) // fpga scale (1 << 17 -1)
{ // n - DCT and window size
int n2 = 2 * n;
double [][][] fold_sk = new double[4][n*n][4];
int [] vert_ind = new int[2];
double [][] vert_k = new double[2][2];
int [] hor_ind = new int[2];
double [][] hor_k = new double[2][2];
// double ahc = Math.cos(Math.PI/n2*shift_hor);
// double ahs = Math.sin(Math.PI/n2*shift_hor);
// double avc = Math.cos(Math.PI/n2*shift_vert);
// double avs = Math.sin(Math.PI/n2*shift_vert);
double [] wnd_hor = new double[n2];
double [] wnd_vert = new double[n2];
double f = Math.PI/n2;
for (int i = 0; i < n2; i++ ){
wnd_hor[i] = Math.sin(f * (i+ 0.5 +shift_hor));
wnd_vert[i] = Math.sin(f * (i+ 0.5 +shift_vert));
}
if (debugLevel > 0){
System.out.println("Window (index,hor,vert) ");
for (int i = 0; i <16; i++) System.out.print(String.format("%5x ", i)); System.out.println();
for (int i = 0; i <16; i++) System.out.print(String.format("%5x ", (int) Math.round(debugLevel * wnd_hor[i]))); System.out.println();
for (int i = 0; i <16; i++) System.out.print(String.format("%5x ", (int) Math.round(debugLevel * wnd_vert[i]))); System.out.println();
System.out.println();
}
int [][] fi;
for (int i = 0; i < n; i++ ){
fi = get_fold_indices(i,n);
vert_ind[0] = fi[0][0];
vert_ind[1] = fi[1][0];
// double vw0 = avc*hwindow[fi[0][1]] + avs*hwindow[fi[0][4]]*fi[0][5];
// double vw1 = avc*hwindow[fi[1][1]] + avs*hwindow[fi[1][4]]*fi[1][5];
double vw0 = wnd_vert[vert_ind[0]];
double vw1 = wnd_vert[vert_ind[1]];
vert_k[0][0] = fi[0][2] * vw0; // use cosine sign
vert_k[0][1] = fi[1][2] * vw1; // use cosine sign
vert_k[1][0] = fi[0][3] * vw0; // use sine sign
vert_k[1][1] = fi[1][3] * vw1; // use sine sign
for (int j = 0; j < n; j++ ){
fi = get_fold_indices(j,n);
hor_ind[0] = fi[0][0];
hor_ind[1] = fi[1][0];
// double hw0 = ahc*hwindow[fi[0][1]] + ahs*hwindow[fi[0][4]]*fi[0][5];
// double hw1 = ahc*hwindow[fi[1][1]] + ahs*hwindow[fi[1][4]]*fi[1][5];
double hw0 = wnd_hor[hor_ind[0]];
double hw1 = wnd_hor[hor_ind[1]];
hor_k[0][0] = fi[0][2] * hw0; // use cosine sign
hor_k[0][1] = fi[1][2] * hw1; // use cosine sign
hor_k[1][0] = fi[0][3] * hw0; // use sine sign
hor_k[1][1] = fi[1][3] * hw1; // use sine sign
int indx = n*i + j;
for (int mode = 0; mode<4; mode++){
for (int k = 0; k<4;k++) {
fold_sk[mode][indx][k] = vert_k[(mode>>1) &1][(k>>1) & 1] * hor_k[mode &1][k & 1];
}
}
}
}
return fold_sk;
}
// return index and two signs (c,s) for 1-d imdct. x is index (0..2*n-1) of the imdct array, value is sign * (idct_index+1), // return index and two signs (c,s) for 1-d imdct. x is index (0..2*n-1) of the imdct array, value is sign * (idct_index+1),
// where idct_index (0..n-1) is index in the dct-iv array // where idct_index (0..n-1) is index in the dct-iv array
...@@ -360,6 +457,51 @@ public class DttRad2 { ...@@ -360,6 +457,51 @@ public class DttRad2 {
return y; return y;
} }
public double [] dttt_iv(double [] x, int mode, int n, double scale, int mask){ // mode 0 - dct,dct 1:dst,dct, 2: dct, dst, 3: dst,dst
double [] y = new double [n*n];
double [] line = new double[n];
// first (horizontal) pass
System.out.println("dttt_iv, mode="+mode);
System.out.println("horizontal pass "+(((mode & 1)!=0)? "dst_iv":"dct_iv"));
for (int i = 0; i<n; i++){
System.arraycopy(x, n*i, line, 0, n);
line = ((mode & 1)!=0)? dst_iv(line):dct_iv(line);
System.out.print(String.format("%02x: ", i));
for (int j=0; j < n;j++) {
int di = ((int) Math.round(x[n*i+j]*scale)) & mask;
System.out.print(String.format("%07x ", di));
}
System.out.print(" ");
for (int j=0; j < n;j++) {
int di = ((int) Math.round(line[j] * scale)) & mask;
System.out.print(String.format("%07x ", di));
}
System.out.println();
for (int j=0; j < n;j++) y[j*n+i] =line[j]; // transpose
}
// second (vertical) pass
System.out.println("vertical pass "+(((mode & 2)!=0)? "dst_iv":"dct_iv")+" (after transpose)");
for (int i = 0; i<n; i++){
System.arraycopy(y, n*i, line, 0, n);
line = ((mode & 2)!=0)? dst_iv(line):dct_iv(line);
System.out.print(String.format("%02x: ", i));
for (int j=0; j < n;j++) {
int di = ((int) Math.round(y[n*i+j]*scale*0.5)) & mask;
System.out.print(String.format("%07x ", di));
}
System.out.print(" ");
for (int j=0; j < n;j++) {
int di = ((int) Math.round(line[j] * scale)) & mask;
System.out.print(String.format("%07x ", di));
}
System.out.println();
System.arraycopy(line, 0, y, n*i, n);
}
return y;
}
public double [] dttt_ii(double [] x){ public double [] dttt_ii(double [] x){
return dttt_ii(x, 1 << (ilog2(x.length)/2)); return dttt_ii(x, 1 << (ilog2(x.length)/2));
} }
...@@ -468,7 +610,8 @@ public class DttRad2 { ...@@ -468,7 +610,8 @@ public class DttRad2 {
public void set_window(int mode){ public void set_window(int mode){
set_window(mode, N); set_window(mode, N);
} }
public void set_window(int mode, int len){ public void set_window(int mode, int len){ // using mode==1
// for N=8: sin (pi/32), sin (3*pi/32), sin (5*pi/32), sin (7*pi/32), sin (9*pi/32), sin (11*pi/32), sin (13*pi/32), sin (15*pi/32)
hwindow = new double[len]; hwindow = new double[len];
double f = Math.PI/(2.0*len); double f = Math.PI/(2.0*len);
double sqrt1_2=Math.sqrt(0.5); double sqrt1_2=Math.sqrt(0.5);
...@@ -533,6 +676,28 @@ public class DttRad2 { ...@@ -533,6 +676,28 @@ public class DttRad2 {
return y; return y;
} }
public double [] fold_tile_debug(
double [] x,
int n,
int mode, //////
double [][][] fold_k
) { // x should be 2n*2n
System.out.println("fold_tile_debug, mode = "+mode);
double [] y = new double [n*n];
for (int i = 0; i<y.length;i++) {
y[i] = 0;
System.out.print(String.format("%2d: ",i));
for (int k = 0; k < 4; k++){
y[i] += x[fold_index[i][k]] * fold_k[mode][i][k];
System.out.print(String.format("(%f * %f) ", x[fold_index[i][k]], fold_k[mode][i][k]));
if (k < 3) System.out.print("+ ");
}
System.out.println(String.format("= %f", y[i]));
}
return y;
}
public double [] unfold_tile( public double [] unfold_tile(
double [] x, // x should be n*n double [] x, // x should be n*n
......
...@@ -118,101 +118,6 @@ public class EyesisDCT { ...@@ -118,101 +118,6 @@ public class EyesisDCT {
return kernels != null; return kernels != null;
} }
/// public boolean CLTKernelsAvailable(){
/// return clt_kernels != null;
/// }
/// public boolean geometryCorrectionAvailable(){
/// return geometryCorrection != null;
/// }
/***
public boolean initGeometryCorrection(int debugLevel){
geometryCorrection = new GeometryCorrection();
PixelMapping.SensorData [] sensors = eyesisCorrections.pixelMapping.sensors;
// verify that all sensors have the same distortion parameters
int numSensors = sensors.length;
for (int i = 1; i < numSensors; i++){
if ( (sensors[0].focalLength != sensors[i].focalLength) ||
(sensors[0].distortionC != sensors[i].distortionC) ||
(sensors[0].distortionB != sensors[i].distortionB) ||
(sensors[0].distortionA != sensors[i].distortionA) ||
(sensors[0].distortionA5 != sensors[i].distortionA5) ||
(sensors[0].distortionA6 != sensors[i].distortionA6) ||
(sensors[0].distortionA7 != sensors[i].distortionA7) ||
(sensors[0].distortionA8 != sensors[i].distortionA8) ||
(sensors[0].distortionRadius != sensors[i].distortionRadius) ||
(sensors[0].pixelCorrectionWidth != sensors[i].pixelCorrectionWidth) ||
(sensors[0].pixelCorrectionHeight != sensors[i].pixelCorrectionHeight) ||
(sensors[0].pixelSize != sensors[i].pixelSize)){
System.out.println("initGeometryCorrection(): All sensors have to have the same distortion model, but channels 0 and "+i+" mismatch");
return false;
}
}
// set common distportion parameters
geometryCorrection.setDistortion(
sensors[0].focalLength,
sensors[0].distortionC,
sensors[0].distortionB,
sensors[0].distortionA,
sensors[0].distortionA5,
sensors[0].distortionA6,
sensors[0].distortionA7,
sensors[0].distortionA8,
sensors[0].distortionRadius,
sensors[0].pixelCorrectionWidth, // virtual camera center is at (pixelCorrectionWidth/2, pixelCorrectionHeight/2)
sensors[0].pixelCorrectionHeight,
sensors[0].pixelSize);
// set other/individual sensor parameters
for (int i = 1; i < numSensors; i++){
if ( (sensors[0].theta != sensors[i].theta) || // elevation
(sensors[0].heading != sensors[i].heading)){
System.out.println("initGeometryCorrection(): All sensors have to have the same elevation and heading, but channels 0 and "+i+" mismatch");
return false;
}
}
double [] forward = new double[numSensors];
double [] right = new double[numSensors];
double [] height = new double[numSensors];
double [] roll = new double[numSensors];
double [][] pXY0 = new double[numSensors][2];
for (int i = 0; i < numSensors; i++){
forward[i] = sensors[i].forward;
right[i] = sensors[i].right;
height[i] = sensors[i].height;
roll[i] = sensors[i].psi;
pXY0[i][0] = sensors[i].px0;
pXY0[i][1] = sensors[i].py0;
}
geometryCorrection.setSensors(
numSensors,
sensors[0].theta,
sensors[0].heading,
forward,
right,
height,
roll,
pXY0);
geometryCorrection.planeProjectLenses(); // project all lenses to the common plane
// calcualte reverse distortion as a table to be linear intr4epolated
geometryCorrection.calcReverseDistortionTable();
if (numSensors == 4){
geometryCorrection.adustSquare();
System.out.println("Adjusted camera to orient X Y along the sides of a square");
} else {
System.out.println("============= Cannot adustSquare() as it requires exactly 4 sensors, "+numSensors+" provided ==========");
return false;
}
// Print parameters
if (debugLevel > 0){
geometryCorrection.listGeometryCorrection(debugLevel > 1);
}
//listGeometryCorrection
return true;
}
*/
public DCTKernels calculateDCTKernel ( public DCTKernels calculateDCTKernel (
final ImageStack kernelStack, // first stack with 3 colors/slices convolution kernels final ImageStack kernelStack, // first stack with 3 colors/slices convolution kernels
final int kernelSize, // 64 final int kernelSize, // 64
......
...@@ -523,6 +523,7 @@ private Panel panel1, ...@@ -523,6 +523,7 @@ private Panel panel1,
addButton("CLT disparity scan", panelClt2, color_conf_process); addButton("CLT disparity scan", panelClt2, color_conf_process);
addButton("CLT reset fine corr", panelClt2, color_stop); addButton("CLT reset fine corr", panelClt2, color_stop);
addButton("CLT reset extrinsic corr", panelClt2, color_stop); addButton("CLT reset extrinsic corr", panelClt2, color_stop);
addButton("CLT show geometry", panelClt2, color_configure);
addButton("CLT show fine corr", panelClt2, color_configure); addButton("CLT show fine corr", panelClt2, color_configure);
addButton("CLT apply fine corr", panelClt2, color_process); addButton("CLT apply fine corr", panelClt2, color_process);
addButton("CLT test fine corr", panelClt2, color_process); addButton("CLT test fine corr", panelClt2, color_process);
...@@ -4613,6 +4614,18 @@ private Panel panel1, ...@@ -4613,6 +4614,18 @@ private Panel panel1,
} }
QUAD_CLT.resetExtrinsicCorr(CLT_PARAMETERS); QUAD_CLT.resetExtrinsicCorr(CLT_PARAMETERS);
return; return;
} else if (label.equals("CLT show geometry")) {
if (QUAD_CLT == null){
QUAD_CLT = new QuadCLT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS);
if (DEBUG_LEVEL > 0){
System.out.println("Created new QuadCLT instance, will need to read CLT kernels");
}
}
QUAD_CLT.listGeometryCorrection(true);
return;
} else if (label.equals("CLT show fine corr")) { } else if (label.equals("CLT show fine corr")) {
if (QUAD_CLT == null){ if (QUAD_CLT == null){
QUAD_CLT = new QuadCLT ( QUAD_CLT = new QuadCLT (
......
...@@ -61,20 +61,20 @@ public class GeometryCorrection { ...@@ -61,20 +61,20 @@ public class GeometryCorrection {
public int numSensors = 4; public int numSensors = 4;
public double [] forward = null; private double [] forward = null;
public double [] right = null; private double [] right = null;
public double [] height = null; private double [] height = null;
public double [] roll = null; // degrees, CW (to target) - positive private double [] roll = null; // degrees, CW (to target) - positive
public double [][] pXY0 = null; // sensor center XY in pixels public double [][] pXY0 = null; // sensor center XY in pixels
public double common_right; // mm right, camera center private double common_right; // mm right, camera center
public double common_forward; // mm forward (to target), camera center private double common_forward; // mm forward (to target), camera center
public double common_height; // mm up, camera center private double common_height; // mm up, camera center
public double common_roll; // degrees CW (to target) camera as a whole private double common_roll; // degrees CW (to target) camera as a whole
public double [][] XYZ_he; // all cameras coordinates transformed to eliminate heading and elevation (rolls preserved) private double [][] XYZ_he; // all cameras coordinates transformed to eliminate heading and elevation (rolls preserved)
public double [][] XYZ_her = null; // XYZ of the lenses in a corrected CCS (adjusted for to elevation, heading, common_roll) private double [][] XYZ_her = null; // XYZ of the lenses in a corrected CCS (adjusted for to elevation, heading, common_roll)
public double [][] rXY = null; // XY pairs of the in a normal plane, relative to disparityRadius private double [][] rXY = null; // XY pairs of the in a normal plane, relative to disparityRadius
public double [][] rXY_ideal = {{-0.5, -0.5}, {0.5,-0.5}, {-0.5, 0.5}, {0.5,0.5}}; private double [][] rXY_ideal = {{-0.5, -0.5}, {0.5,-0.5}, {-0.5, 0.5}, {0.5,0.5}};
public double cameraRadius=0; // average distance from the "mass center" of the sensors to the sensors public double cameraRadius=0; // average distance from the "mass center" of the sensors to the sensors
public double disparityRadius=0; // distance between cameras to normalize disparity units to. sqrt(2)*disparityRadius for quad camera (~=150mm)? public double disparityRadius=0; // distance between cameras to normalize disparity units to. sqrt(2)*disparityRadius for quad camera (~=150mm)?
......
...@@ -22,11 +22,17 @@ ...@@ -22,11 +22,17 @@
** **
*/ */
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import Jama.Matrix; import Jama.Matrix;
import ij.ImageStack; import ij.ImageStack;
public class ImageDtt { public class ImageDtt {
static boolean FPGA_COMPARE_DATA= false; // true; // false; //
static int FPGA_SHIFT_BITS = 7; // number of bits for fractional pixel shift
static int FPGA_PIXEL_BITS = 15; // bits to represent pixel data (positive)
static int FPGA_WND_BITS = 17; // bits to represent mclt window (positive for 18-bit signed mpy input)
static int FPGA_DTT_IN = 22; // bits to represent maximal value after folding (input to DTT)
static int FPGA_TILE_SIZE = 22; // size of square side for the composite colors tile (16..22)
static double [] kern_g={ static double [] kern_g={
0.0, 0.125, 0.0 , 0.0, 0.125, 0.0 ,
0.125, 0.5, 0.125, 0.125, 0.5, 0.125,
...@@ -44,7 +50,7 @@ public class ImageDtt { ...@@ -44,7 +50,7 @@ public class ImageDtt {
{0,1,2,3,4,5,6,7,8}, // middle {0,1,2,3,4,5,6,7,8}, // middle
{0,1,3,4,6,7}, // middle right {0,1,3,4,6,7}, // middle right
{1,2,4,5}, // bottom left {1,2,4,5}, // bottom left
{0,1,2,3,4,5}, // mottom middle {0,1,2,3,4,5}, // bottom middle
{0,1,3,4}}; // bottom right {0,1,3,4}}; // bottom right
// public static int FORCE_DISPARITY_BIT = 8; // move to parameters? // public static int FORCE_DISPARITY_BIT = 8; // move to parameters?
...@@ -188,6 +194,7 @@ public class ImageDtt { ...@@ -188,6 +194,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
DttRad2 dtt = new DttRad2(dct_size); DttRad2 dtt = new DttRad2(dct_size);
dtt.set_window(window_type); dtt.set_window(window_type);
...@@ -421,6 +428,7 @@ public class ImageDtt { ...@@ -421,6 +428,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -500,6 +508,7 @@ public class ImageDtt { ...@@ -500,6 +508,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -614,6 +623,7 @@ public class ImageDtt { ...@@ -614,6 +623,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -683,6 +693,7 @@ public class ImageDtt { ...@@ -683,6 +693,7 @@ public class ImageDtt {
ai.set(0); ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
DttRad2 dtt = new DttRad2(dct_size); DttRad2 dtt = new DttRad2(dct_size);
dtt.set_window(window_type); dtt.set_window(window_type);
...@@ -745,6 +756,7 @@ public class ImageDtt { ...@@ -745,6 +756,7 @@ public class ImageDtt {
} }
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
DttRad2 dtt = new DttRad2(transform_size); DttRad2 dtt = new DttRad2(transform_size);
dtt.set_window(window_type); dtt.set_window(window_type);
...@@ -855,6 +867,7 @@ public class ImageDtt { ...@@ -855,6 +867,7 @@ public class ImageDtt {
} }
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
DttRad2 dtt = new DttRad2(transform_size); DttRad2 dtt = new DttRad2(transform_size);
dtt.set_window(window_type); dtt.set_window(window_type);
...@@ -966,9 +979,389 @@ public class ImageDtt { ...@@ -966,9 +979,389 @@ public class ImageDtt {
return clt_data; return clt_data;
} }
/* public void printSignsFPGA (
* DttRad2 dtt
*/ ){
double [][][] fold_coeff = dtt.getFoldK();
int [][] fpga_fi = dtt.getFoldIndex();
// For R/B color channels (1 - 4 non-zero) show signs during folding of a single pixel contributor (4 Bayer variants) per each mode
String [] mode_names={"CC","SC", "CS","SS"};
int [] bayer_patterns = {0x1, 0x2, 0x4, 0x8}; // , 0x9, 0x6};
boolean [][][] signs = new boolean [bayer_patterns.length][4][64];
// for (int bp:bayer_patterns){
for (int ibp = 0; ibp < bayer_patterns.length; ibp++){
int bp = bayer_patterns[ibp];
System.out.println("\nPattern (row/col) "+bp+":");
System.out.println("| "+(((bp & 1) !=0) ? "X ":" ")+(((bp & 2) !=0) ? "X ":" ")+"|");
System.out.println("| "+(((bp & 4) !=0) ? "X ":" ")+(((bp & 8) !=0) ? "X ":" ")+"|");
for (int mode = 0; mode < 4; mode++){
if (mode == 0) System.out.println("DTT mode = "+mode+" ("+ mode_names[mode]+"): term sign");
else System.out.println("DTT mode = "+mode+" ("+ mode_names[mode]+"): term inverse relative to CC ");
for (int i = 0; i < 64; i++){
for (int k = 0; k < 4; k++){
int row = (fpga_fi[i][k] >> 4);
int col = (fpga_fi[i][k] & 0xf);
int indx = (row & 1) + 2 * (col & 1);
if (((1 << indx) & bp) != 0) { // only use non-zero pixels, for 1 in 4 - only one k would match
signs[ibp][mode][i] = fold_coeff[mode][i][k] < 0;
if (mode == 0) {
if (fold_coeff[mode][i][k] < 0) System.out.print("- ");
else System.out.print("+ ");
} else {
boolean sgn = signs[ibp][mode][i] ^ signs[ibp][0][i];
if (sgn) System.out.print("* ");
else System.out.print(". ");
}
// continue;
}
}
if ((i+1)%8 == 0) System.out.println();
}
}
}
}
public void generateFPGACompareData(
final double [][] image_data, // for selected subcamera
final double [][] colorCentersXY, // pixel centers per color (2 - green)
final int transform_size,
final int width,
DttRad2 dtt
){
printSignsFPGA(dtt);
int height = image_data[0].length/width;
double [][][] fpga_clt_data_in = new double [3][4][];
double [][][] fpga_clt_data_out = new double [3][4][];
double [][][] fpga_clt_data_rot = new double [3][4][];
// double [][] fpga_fract_shiftsXY = new double[3][];
double [][] fpga_centersXY = new double [3][2];
// int [][] color_int_shifts = new int [3][2];
double [][][][] fold_coeff = new double[3][][][];
int [] ctile_left = new int [3];
int [] ctile_top = new int [3];
double [][] residual_shift = new double[3][2];
int [] ishx = new int[3];
int [] ishy = new int[3];
double [][] fpga_full_tile = new double [3][FPGA_TILE_SIZE * FPGA_TILE_SIZE];
double [][] fpga_tile = new double [3][4*transform_size*transform_size];
for (int chn = 0; chn<3; chn++) for (int j = 0; j < 2; j++) {
fpga_centersXY[chn][j] = colorCentersXY[chn][j];
// Round to FPGA precision
fpga_centersXY[chn][j] = Math.round(128*fpga_centersXY[chn][j])/128.0;
}
for (int chn = 0; chn<3; chn++) {
double px = fpga_centersXY[chn][0] - transform_size;
double py = fpga_centersXY[chn][1] - transform_size;
// Was wrong rounding, fractional part gets to +0.5
ctile_left[chn] = (int) -Math.round(-px);
ctile_top[chn] = (int) -Math.round(-py);
residual_shift[chn][0] = -(px - ctile_left[chn]);
residual_shift[chn][1] = -(py - ctile_top[chn]);
}
int lt = (FPGA_TILE_SIZE - 2 * transform_size)/2;
for (int chn = 0; chn < 3; chn++){
for (int i = 0; i < FPGA_TILE_SIZE; i++){
System.arraycopy(
image_data[chn],
((ctile_top[GREEN_CHN] - lt) + i) * width + (ctile_left[GREEN_CHN] - lt),
fpga_full_tile[chn], FPGA_TILE_SIZE * i,
FPGA_TILE_SIZE);
}
}
for (int chn = 0; chn < 3; chn++){
if ((ctile_left[chn] >= 0) && (ctile_left[chn] < (width - transform_size * 2)) &&
(ctile_top[chn] >= 0) && (ctile_top[chn] < (height - transform_size * 2))) {
for (int i = 0; i < transform_size * 2; i++){
System.arraycopy(image_data[chn], (ctile_top[chn] + i) * width + ctile_left[chn], fpga_tile[chn], transform_size * 2 * i, transform_size* 2);
}
} else { // copy by 1
for (int i = 0; i < transform_size* 2; i++){
int pi = ctile_top[chn] + i;
if (pi < 0) pi &= 1;
else if (pi >= height) pi = height - 2 + (pi & 1);
for (int j = 0; j < transform_size* 2; j++){
int pj = ctile_left[chn] + j;
if (pj < 0) pj &= 1;
else if (pj >= width) pj = width - 2 + (pj & 1);
fpga_tile[chn][transform_size * 2 * i + j] = image_data[chn][pi * width + pj];
}
}
}
}
// Fold and transform
for (int chn = 0; chn < 3; chn++){
fold_coeff[chn] = dtt.get_shifted_fold_2d ( // get_shifted_fold_2d(
transform_size,
residual_shift[chn][0],
residual_shift[chn][1],
0); // debug level
}
for (int chn = 0; chn < 3; chn++){
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
// fpga_clt_data_in[chn][dct_mode] = dtt.fold_tile_debug (fpga_tile[chn], transform_size, dct_mode, fold_coeff[chn]); // DCCT, DSCT, DCST, DSST
fpga_clt_data_in[chn][dct_mode] = dtt.fold_tile (fpga_tile[chn], transform_size, dct_mode, fold_coeff[chn]); // DCCT, DSCT, DCST, DSST
}
}
for (int chn = 0; chn < 3; chn++) if (chn != GREEN_CHN) {
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
fpga_clt_data_in[chn][dct_mode][i] *= 2.0; //adding twice each number in FPGA for R and B
}
}
}
for (int chn = 0; chn < 3; chn++) {
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
fpga_clt_data_out[chn][dct_mode] = fpga_clt_data_in[chn][dct_mode].clone();
}
}
double scale1 = (1 << (FPGA_DTT_IN - 9)); // -1;
scale1 *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
scale1 *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
// scale1 *= 2.0;
System.out.println("scale1="+scale1);
for (int chn = 0; chn < 3; chn++) {
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
System.out.println("// Color="+chn+" fpga_clt_data_out[chn][dct_mode] = dtt.dttt_iv(..., scale1="+scale1);
fpga_clt_data_out[chn][dct_mode] = dtt.dttt_iv (fpga_clt_data_out[chn][dct_mode], dct_mode, transform_size, scale1, ((1 << 25) -1)); // debug level
// fpga_clt_data_out[chn][dct_mode] = dtt.dttt_iv (fpga_clt_data_out[chn][dct_mode], dct_mode, transform_size);
}
}
for (int chn = 0; chn < 3; chn++) {
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
fpga_clt_data_rot[chn][dct_mode] = fpga_clt_data_out[chn][dct_mode].clone();
}
}
// Rotate for fractional shift:
for (int chn = 0; chn < 3; chn++) {
fract_shift( // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations
fpga_clt_data_rot[chn], // double [][] clt_tile,
transform_size,
residual_shift[chn][0], // double shiftX,
residual_shift[chn][1], // double shiftY,
true); // debug
}
// int byr_shift = ((ctile_top[GREEN_CHN] & 1) <<1) | (ctile_left[GREEN_CHN] & 1);
//GREEN_CHN
// Printout
System.out.println("// Debugging FPGA implementation");
for (int chn = 0; chn<3; chn++) {
System.out.println("// residual_shift["+chn+"][0]="+residual_shift[chn][0]+", residual_shift["+chn+"][1]="+residual_shift[chn][1]);
ishx[chn] = (int) Math.round((1 << (FPGA_SHIFT_BITS)) * residual_shift[chn][0]);
ishy[chn] = (int) Math.round((1 << (FPGA_SHIFT_BITS)) * residual_shift[chn][1]);
if (ishx[chn] >= (1 << (FPGA_SHIFT_BITS-1))) ishx[chn] = (1 << (FPGA_SHIFT_BITS-1)) - 1;
if (ishy[chn] >= (1 << (FPGA_SHIFT_BITS-1))) ishy[chn] = (1 << (FPGA_SHIFT_BITS-1)) - 1;
if (ishx[chn] < -(1 << (FPGA_SHIFT_BITS-1))) ishx[chn] = -(1 << (FPGA_SHIFT_BITS-1));
if (ishy[chn] < -(1 << (FPGA_SHIFT_BITS-1))) ishy[chn] = -(1 << (FPGA_SHIFT_BITS-1));
residual_shift[chn][0] = ishx[chn] * (1.0/(1 << (FPGA_SHIFT_BITS)));
residual_shift[chn][1] = ishy[chn] * (1.0/(1 << (FPGA_SHIFT_BITS)));
System.out.println(String.format("%4x // color %d shift_x, %d bits", ishx[chn] & ((1 << (FPGA_SHIFT_BITS)) - 1),chn,FPGA_SHIFT_BITS));
System.out.println(String.format("%4x // color %d shift_y, %d bits", ishy[chn] & ((1 << (FPGA_SHIFT_BITS)) - 1),chn,FPGA_SHIFT_BITS));
System.out.println(String.format("%4x // color %d ctile_left", ctile_left[chn],chn));
System.out.println(String.format("%4x // color %d ctile_top", ctile_top[chn], chn));
}
System.out.println("\n// Full Bayer fpga tile data");
int id = (1 << (FPGA_PIXEL_BITS - 9)); // 8
for (int i = 0; i < FPGA_TILE_SIZE*FPGA_TILE_SIZE; i++) {
double d = 0.0;
for (int fpga_chn = 0; fpga_chn < 3; fpga_chn++){
d += fpga_full_tile[fpga_chn][i];
}
System.out.print(String.format("%4x ",(int) Math.round(id * d)));
if (((i+1) %FPGA_TILE_SIZE) == 0) {
System.out.println();
}
}
System.out.println();
for (int chn = 0; chn<3; chn++) {
double [] fpga_pix_lim = {0.0,0.0};
for (int i = 0; i < 256; i++) if (fpga_tile[chn][i] != 0){
if (fpga_tile[chn][i] > fpga_pix_lim[0]) fpga_pix_lim[0] = fpga_tile[chn][i];
if (fpga_tile[chn][i] < fpga_pix_lim[1]) fpga_pix_lim[1] = fpga_tile[chn][i];
}
System.out.println(String.format("\n// Color # %d: Pixels input range: %f ... %f", chn, fpga_pix_lim[1], fpga_pix_lim[0]));
System.out.println(String.format("//%x // shift_x, %d bits",ishx[chn] & ((1 << (FPGA_SHIFT_BITS)) - 1),FPGA_SHIFT_BITS));
System.out.println(String.format("//%x // shift_y, %d bits",ishy[chn] & ((1 << (FPGA_SHIFT_BITS)) - 1),FPGA_SHIFT_BITS));
for (int row = 0; row <16; row++){
for (int col = 0; col <16; col++){
System.out.print(String.format("%4x ",(int) Math.round(id * fpga_tile[chn][row*16 + col])));
}
System.out.println();
}
System.out.println();
}
System.out.println();
for (int chn = 0; chn<3; chn++) {
System.out.println("// Color="+chn+", signs table (per mode, per index - bitstring of variants, 0 - positive, 1 - negative)");
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
int d = 0;
for (int b = 0; b < 4; b++){
if (fold_coeff[chn][dct_mode][i][b] < 0){
d |= (1 << b);
}
}
System.out.print(String.format("%x ",d));
if ((i % 16) == 15){
System.out.println();
}
}
}
System.out.println();
}
System.out.println();
for (int chn = 0; chn<3; chn++) {
System.out.println("// Color = "+chn+", absolute values, mode0 (CC), others are the same");
// for (int dct_mode = 0; dct_mode <4; dct_mode++) {
int dct_mode = 0;
for (int i = 0; i < 64; i++){
for (int b = 0; b < 4; b++){
int d = (int) Math.round(((1 << FPGA_WND_BITS) -1)* Math.abs(fold_coeff[chn][dct_mode][i][b]));
System.out.print(String.format("%5x ",d & ((1 << (FPGA_WND_BITS)) - 1)));
}
if ((i % 4) == 3){
System.out.println();
}
}
System.out.println();
// }
}
System.out.println();
for (int chn = 0; chn<3; chn++) {
double [] fpga_dtt_lim = {0.0,0.0};
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
if (fpga_clt_data_in[chn][dct_mode][i] > fpga_dtt_lim[0]) fpga_dtt_lim[0] = fpga_clt_data_in[chn][dct_mode][i];
if (fpga_clt_data_in[chn][dct_mode][i] < fpga_dtt_lim[1]) fpga_dtt_lim[1] = fpga_clt_data_in[chn][dct_mode][i];
}
}
System.out.println(String.format("// Color= %d, DTT input range: %f ... %f", chn, fpga_dtt_lim[1], fpga_dtt_lim[0]));
double scale = (1 << (FPGA_DTT_IN - 9)); // -1;
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
scale *= 2; // Increased twice in FPGA adding twice each number in FPGA
System.out.println("// Color="+chn+" fpga_clt_data_out[chn][dct_mode] = dtt.dttt_iv(..., scale="+scale);
// if (chn != GREEN_CHN) scale *= 2; // adding twice each number in FPGA for R and B - done before
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
int idd = (int) Math.round(scale * fpga_clt_data_in[chn][dct_mode][i]);
System.out.print(String.format("%7x ", idd & ((1 << 25) -1)));
if ((i % 8) == 7) System.out.println();
}
System.out.println();
}
System.out.println();
}
System.out.println();
for (int chn = 0; chn<3; chn++) {
double [] fpga_dtt_lim = {0.0,0.0};
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
if (fpga_clt_data_out[chn][dct_mode][i] > fpga_dtt_lim[0]) fpga_dtt_lim[0] = fpga_clt_data_out[chn][dct_mode][i];
if (fpga_clt_data_out[chn][dct_mode][i] < fpga_dtt_lim[1]) fpga_dtt_lim[1] = fpga_clt_data_out[chn][dct_mode][i];
}
}
System.out.println(String.format("// Color = %d: DTT output range: %f ... %f", chn, fpga_dtt_lim[1], fpga_dtt_lim[0]));
// scale = (1 << (FPGA_DTT_IN - 9)); // -1;
// double scale = (1 << (FPGA_DTT_IN - 8)); // increased twice
double scale = (1 << (FPGA_DTT_IN - 9)); // Do not increase - lead to overflow !
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
int idd = (int) Math.round(scale * fpga_clt_data_out[chn][dct_mode][i]);
System.out.print(String.format("%7x ", idd & ((1 << 25) -1)));
if ((i % 8) == 7) System.out.println();
}
System.out.println();
}
System.out.println();
System.out.println("// Color = "+chn+" Testing symmetry of checkerboard patterns");
for (int dct_mode = 0; dct_mode < 2; dct_mode++) {
for (int i = 0; i < 64; i++){
if ((i % 8) == 0) System.out.print("// ");
int idd = (int) Math.round(scale * fpga_clt_data_out[chn][dct_mode][i]);
int idd1 = (int) Math.round(scale * fpga_clt_data_out[chn][3-dct_mode][63-i]);
System.out.print(String.format("%7x ", (idd-idd1) & ((1 << 25) -1)));
if ((i % 8) == 7) System.out.println();
}
System.out.println();
}
System.out.println();
System.out.println("// Color = "+chn+" Testing antisymmetry of checkerboard patterns");
for (int dct_mode = 0; dct_mode < 2; dct_mode++) {
for (int i = 0; i < 64; i++){
if ((i % 8) == 0) System.out.print("// ");
int idd = (int) Math.round(scale * fpga_clt_data_out[chn][dct_mode][i]);
int idd1 = (int) Math.round(scale * fpga_clt_data_out[chn][3-dct_mode][63-i]);
System.out.print(String.format("%7x ", (idd+idd1) & ((1 << 25) -1)));
if ((i % 8) == 7) System.out.println();
}
System.out.println();
}
System.out.println();
}
System.out.println();
for (int chn = 0; chn<3; chn++) {
// double scale = (1 << (FPGA_DTT_IN - 9)); // -1;
// double scale = (1 << (FPGA_DTT_IN - 8)); //
double scale = (1 << (FPGA_DTT_IN - 9)); // Do not increase - lead to overflow !
// compensate for DTT scale
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
// compensate for rotator scale:
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
double [] fpga_dtt_lim = {0.0,0.0};
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int j = 0; j < 64; j++){
if (fpga_clt_data_rot[chn][dct_mode][j] > fpga_dtt_lim[0]) fpga_dtt_lim[0] = fpga_clt_data_rot[chn][dct_mode][j];
if (fpga_clt_data_rot[chn][dct_mode][j] < fpga_dtt_lim[1]) fpga_dtt_lim[1] = fpga_clt_data_rot[chn][dct_mode][j];
}
}
System.out.println(String.format("// Color = %d: DTT rotated, shift_x=%f. shift_y = %f", chn, residual_shift[chn][0],residual_shift[chn][1]));
System.out.println(String.format("// DTT rotated range: %f ... %f", fpga_dtt_lim[1], fpga_dtt_lim[0]));
// scale = (1 << (FPGA_DTT_IN - 9)); // -1;
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int j = 0; j < 64; j++){
int idd = (int) Math.round(scale * fpga_clt_data_rot[chn][dct_mode][j]);
System.out.print(String.format("%7x ", idd & ((1 << 25) -1)));
if ((j % 8) == 7) System.out.println();
}
System.out.println();
}
}
}
public double [][][][][][] clt_aberrations_quad_corr( public double [][][][][][] clt_aberrations_quad_corr(
...@@ -1034,7 +1427,7 @@ public class ImageDtt { ...@@ -1034,7 +1427,7 @@ public class ImageDtt {
final int threadsMax, // maximal number of threads to launch final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel) final int globalDebugLevel)
{ {
final boolean debug_ports_coordinates = (debug_tileX == -1234); // final boolean debug_ports_coordinates = (debug_tileX == -1234);
final boolean macro_mode = macro_scale != 1; // correlate tile data instead of the pixel data final boolean macro_mode = macro_scale != 1; // correlate tile data instead of the pixel data
final int quad = 4; // number of subcameras final int quad = 4; // number of subcameras
final int numcol = 3; // number of colors final int numcol = 3; // number of colors
...@@ -1189,6 +1582,7 @@ public class ImageDtt { ...@@ -1189,6 +1582,7 @@ public class ImageDtt {
final Matrix [] corr_rots = geometryCorrection.getCorrVector().getRotMatrices(); // get array of per-sensor rotation matrices final Matrix [] corr_rots = geometryCorrection.getCorrVector().getRotMatrices(); // get array of per-sensor rotation matrices
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
DttRad2 dtt = new DttRad2(transform_size); DttRad2 dtt = new DttRad2(transform_size);
dtt.set_window(window_type); dtt.set_window(window_type);
...@@ -1281,20 +1675,6 @@ public class ImageDtt { ...@@ -1281,20 +1675,6 @@ public class ImageDtt {
} }
// TODO: use correction after disparity applied (to work for large disparity values) // TODO: use correction after disparity applied (to work for large disparity values)
if (fine_corr != null){ if (fine_corr != null){
// old correction
//double tX = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0
//double tY = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
//for (int ip = 0; ip < centersXY.length; ip++){
// //f(x,y)=A*x^2+B*y^2+C*x*y+D*x+E*y+F
// for (int d = 0; d <2; d++)
// centersXY[ip][d] -= (
// fine_corr[ip][d][0]*tX*tX+
// fine_corr[ip][d][1]*tY*tY+
// fine_corr[ip][d][2]*tX*tY+
// fine_corr[ip][d][3]*tX+
// fine_corr[ip][d][4]*tY+
// fine_corr[ip][d][5]);
//}
for (int ip = 0; ip < centersXY.length; ip++){ for (int ip = 0; ip < centersXY.length; ip++){
double [] tXY = geometryCorrection.getRelativeCoords(centersXY[ip]); double [] tXY = geometryCorrection.getRelativeCoords(centersXY[ip]);
...@@ -1310,94 +1690,141 @@ public class ImageDtt { ...@@ -1310,94 +1690,141 @@ public class ImageDtt {
} }
} }
} // if (macro_mode) ... else } // if (macro_mode) ... else
if (FPGA_COMPARE_DATA && (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)) {
final int fpga_cam = 0;
for (int chn = 0; chn <numcol; chn++) { double [][] manual_offsets={
// { 1.3, -2.7},
/* // {-1.3, 2.7},
centerX = tileX * transform_size + transform_size/2 - shiftX; // { 0.0, 0.0}};
centerY = tileY * transform_size + transform_size/2 - shiftY;
// TODO: move port coordinates out of color channel loop // { 2.3, -2.7},
double [][] centersXY; // {-0.3, 2.7},
if (macro_mode){ // { 0.0, 0.0}};
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) { // before correction
System.out.println("\nUsing MACRO mode, centerX="+centerX+", centerY="+centerY); { 2.3, -2.7},
} {-0.3, 2.7},
centersXY = geometryCorrection.getPortsCoordinatesIdeal( { 1.0, 0.0}};
macro_scale,
centerX, double [][] colorCentersXY = {
centerY, {centersXY[fpga_cam][0] + manual_offsets[0][0], centersXY[fpga_cam][1] + manual_offsets[0][1]}, // add manual offsets here
macro_scale* disparity_array[tileY][tileX] + disparity_corr); {centersXY[fpga_cam][0] + manual_offsets[1][0], centersXY[fpga_cam][1] + manual_offsets[1][1]},
} else { {centersXY[fpga_cam][0] + manual_offsets[2][0], centersXY[fpga_cam][1] + manual_offsets[2][1]}
centersXY = geometryCorrection.getPortsCoordinates( };
centerX, generateFPGACompareData(
centerY, image_data[fpga_cam], // final double [][] image_data, // for selected subcamera
disparity_array[tileY][tileX] + disparity_corr); colorCentersXY, // final double [][] colorCentersXY, // pixel centers per color (2 - green)
if ((globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)) { transform_size, // final int transform_size,
for (int i = 0; i < quad; i++) { width, // final int width
System.out.println("clt_aberrations_quad_corr(): color="+chn+", tileX="+tileX+", tileY="+tileY+ dtt
" centerX="+centerX+" centerY="+centerY+" disparity="+disparity_array[tileY][tileX]+ );
" centersXY["+i+"][0]="+centersXY[i][0]+" centersXY["+i+"][1]="+centersXY[i][1]);
}
} }
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) { // before correction for (int chn = 0; chn <numcol; chn++) {
System.out.print(disparity_array[tileY][tileX]+"\t"+ boolean debug_for_fpga = FPGA_COMPARE_DATA && (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2);
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.println("\nUsing "+(macro_mode?"MACRO":"PIXEL")+" mode, centerX="+centerX+", centerY="+centerY);
System.out.println(disparity_array[tileY][tileX]+"\t"+
centersXY[0][0]+"\t"+centersXY[0][1]+"\t"+ centersXY[0][0]+"\t"+centersXY[0][1]+"\t"+
centersXY[1][0]+"\t"+centersXY[1][1]+"\t"+ centersXY[1][0]+"\t"+centersXY[1][1]+"\t"+
centersXY[2][0]+"\t"+centersXY[2][1]+"\t"+ centersXY[2][0]+"\t"+centersXY[2][1]+"\t"+
centersXY[3][0]+"\t"+centersXY[3][1]+"\t"); centersXY[3][0]+"\t"+centersXY[3][1]+"\t");
} }
for (int ip = 0; ip < centersXY.length; ip++){ for (int i = 0; i < quad; i++) {
centersXY[ip][0] -= shiftXY[ip][0]; if (debug_for_fpga && (i==0)){
centersXY[ip][1] -= shiftXY[ip][1]; double [][] fpga_clt_data = new double [4][];
double [] fpga_fract_shiftsXY;
double [] fpga_centersXY = {centersXY[i][0],centersXY[i][1]};
int fpga_chn = chn; // ==2, green
// round to nearest 1/128 pix (supported by FPGA code)
System.out.println(String.format("Center X= %f, center Y = %f", fpga_centersXY[0],fpga_centersXY[1]));
for (int j=0; j<2;j++){
fpga_centersXY[j] = Math.round(128*fpga_centersXY[j])/128.0;
} }
// TODO: use correction after disparity applied (to work for large disparity values)
if (fine_corr != null){
// old correction
//double tX = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0
//double tY = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
//for (int ip = 0; ip < centersXY.length; ip++){
// //f(x,y)=A*x^2+B*y^2+C*x*y+D*x+E*y+F
// for (int d = 0; d <2; d++)
// centersXY[ip][d] -= (
// fine_corr[ip][d][0]*tX*tX+
// fine_corr[ip][d][1]*tY*tY+
// fine_corr[ip][d][2]*tX*tY+
// fine_corr[ip][d][3]*tX+
// fine_corr[ip][d][4]*tY+
// fine_corr[ip][d][5]);
//}
for (int ip = 0; ip < centersXY.length; ip++){
double [] tXY = geometryCorrection.getRelativeCoords(centersXY[ip]); for (int j=0; j<2;j++){
for (int d = 0; d <2; d++) { fpga_centersXY[j] = Math.round(fpga_centersXY[j]);
centersXY[ip][d] -= ( }
fine_corr[ip][d][0]*tXY[0]*tXY[0]+
fine_corr[ip][d][1]*tXY[1]*tXY[1]+
fine_corr[ip][d][2]*tXY[0]*tXY[1]+ // fpga_centersXY[0]+=0.5; // half pixel shift horizontal zero pixel shift vertical
fine_corr[ip][d][3]*tXY[0]+ // fpga_centersXY[1]+=0.5; // half pixel shift vertical, zero pixel shift horizontal
fine_corr[ip][d][4]*tXY[1]+
fine_corr[ip][d][5]); // fpga_centersXY[0]+=1.0; //
fpga_chn = 2;
System.out.println(String.format("Manually changing offset: center X= %f, center Y = %f", fpga_centersXY[0],fpga_centersXY[1]));
System.out.println(String.format("Manually changing color to %d (was %d)", fpga_chn, chn));
fpga_fract_shiftsXY = extract_correct_tile( // return a pair of residual offsets
image_data[i],
width, // image width
null,
fpga_clt_data, //double [][] clt_tile, // should be double [4][];
kernel_step,
transform_size,
dtt,
fpga_chn, // chn,
fpga_centersXY[0], // centersXY[i][0], // centerX, // center of aberration-corrected (common model) tile, X
fpga_centersXY[1], // centersXY[i][1], // centerY, //
-10, // globalDebugLevel,
true, // no_deconvolution,
false, // ); // transpose);
null,
null);
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"CC","SC","CS","SS"};
double [][] dbg_tile = new double [4][];
for (int im = 0; im < 4; im++) dbg_tile[im]=fpga_clt_data[im];
sdfa_instance.showArrays(dbg_tile, transform_size, transform_size, true, "fpre-shifted_x"+tileX+"_y"+tileY+"-z", titles);
fract_shift( // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations
fpga_clt_data, // double [][] clt_tile,
transform_size,
fpga_fract_shiftsXY[0], // double shiftX,
fpga_fract_shiftsXY[1], // double shiftY,
true); // debug
for (int im = 0; im < 4; im++) dbg_tile[im]=fpga_clt_data[im];
sdfa_instance.showArrays(dbg_tile, transform_size, transform_size, true, "f-shifted_x"+tileX+"_y"+tileY+"-z", titles);
System.out.println("Debugging for FPGA data, globalDebugLevel = "+globalDebugLevel+", tileX="+tileX+", tileY="+tileY+", sesnlor="+i+", color="+chn);
System.out.println("Debugging for FPGA data, fpga_fract_shiftsXY[0] = "+fpga_fract_shiftsXY[0]+", fpga_fract_shiftsXY[1]="+fpga_fract_shiftsXY[1]);
System.out.println();
double scale = (1 << (FPGA_DTT_IN - 9)); // -1;
// compensate for DTT scale
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
// compensate for rotator scale:
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
double [] fpga_dtt_lim = {0.0,0.0};
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int j = 0; j < 64; j++){
if (fpga_clt_data[dct_mode][j] > fpga_dtt_lim[0]) fpga_dtt_lim[0] = fpga_clt_data[dct_mode][j];
if (fpga_clt_data[dct_mode][j] < fpga_dtt_lim[1]) fpga_dtt_lim[1] = fpga_clt_data[dct_mode][j];
} }
} }
System.out.println(String.format("// DTT rotated, shift_x=%f. shift_y = %f", fpga_fract_shiftsXY[0],fpga_fract_shiftsXY[1]));
System.out.println(String.format("// DTT rotated range: %f ... %f", fpga_dtt_lim[1], fpga_dtt_lim[0]));
// scale = (1 << (FPGA_DTT_IN - 9)); // -1;
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int j = 0; j < 64; j++){
int id = (int) Math.round(scale * fpga_clt_data[dct_mode][j]);
System.out.print(String.format("%7x ", id & ((1 << 25) -1)));
if ((j % 8) == 7) System.out.println();
}
System.out.println();
} }
} // if (macro_mode) ... else
*/
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.println("\nUsing "+(macro_mode?"MACRO":"PIXEL")+" mode, centerX="+centerX+", centerY="+centerY);
System.out.println(disparity_array[tileY][tileX]+"\t"+
centersXY[0][0]+"\t"+centersXY[0][1]+"\t"+
centersXY[1][0]+"\t"+centersXY[1][1]+"\t"+
centersXY[2][0]+"\t"+centersXY[2][1]+"\t"+
centersXY[3][0]+"\t"+centersXY[3][1]+"\t");
} }
for (int i = 0; i < quad; i++) {
clt_data[i][chn][tileY][tileX] = new double [4][]; clt_data[i][chn][tileY][tileX] = new double [4][];
fract_shiftsXY[i] = extract_correct_tile( // return a pair of residual offsets fract_shiftsXY[i] = extract_correct_tile( // return a pair of residual offsets
image_data[i], image_data[i],
...@@ -1411,7 +1838,7 @@ public class ImageDtt { ...@@ -1411,7 +1838,7 @@ public class ImageDtt {
centersXY[i][0], // centerX, // center of aberration-corrected (common model) tile, X centersXY[i][0], // centerX, // center of aberration-corrected (common model) tile, X
centersXY[i][1], // centerY, // centersXY[i][1], // centerY, //
// ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)), // ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)),
((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) ? (globalDebugLevel + 0) : 0, // external tile compare (!FPGA_COMPARE_DATA && (globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2) && (i==0)) ? (globalDebugLevel + 0) : 0, // external tile compare
// (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2), // external tile compare // (globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2), // external tile compare
no_deconvolution, no_deconvolution,
...@@ -1419,11 +1846,12 @@ public class ImageDtt { ...@@ -1419,11 +1846,12 @@ public class ImageDtt {
((saturation_imp != null) ? saturation_imp[i] : null), //final boolean [][] saturation_imp, // (near) saturated pixels or null ((saturation_imp != null) ? saturation_imp[i] : null), //final boolean [][] saturation_imp, // (near) saturated pixels or null
((saturation_imp != null) ? overexp_all: null)); // final double [] overexposed) ((saturation_imp != null) ? overexp_all: null)); // final double [] overexposed)
} }
if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) { if ((globalDebugLevel > -1) && (tileX == debug_tileX) && (tileY == debug_tileY) && (chn == 2)) {
System.out.println(); System.out.println();
} }
if ((globalDebugLevel > 0) && (debug_tileX == tileX) && (debug_tileY == tileY) && (chn == 2)) { if ((globalDebugLevel > 0) && (debug_tileX == tileX) && (debug_tileY == tileY) && (chn == 2) && !FPGA_COMPARE_DATA) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging? showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"CC0","SC0","CS0","SS0","CC1","SC1","CS1","SS1","CC2","SC2","CS2","SS2","CC3","SC3","CS3","SS3"}; String [] titles = {"CC0","SC0","CS0","SS0","CC1","SC1","CS1","SS1","CC2","SC2","CS2","SS2","CC3","SC3","CS3","SS3"};
double [][] dbg_tile = new double [16][]; double [][] dbg_tile = new double [16][];
...@@ -1439,6 +1867,7 @@ public class ImageDtt { ...@@ -1439,6 +1867,7 @@ public class ImageDtt {
} }
} }
// if (!no_fract_shift && !FPGA_COMPARE_DATA) {
if (!no_fract_shift) { if (!no_fract_shift) {
// apply residual shift // apply residual shift
for (int i = 0; i < quad; i++) { for (int i = 0; i < quad; i++) {
...@@ -1456,10 +1885,15 @@ public class ImageDtt { ...@@ -1456,10 +1885,15 @@ public class ImageDtt {
String [] titles = {"CC0","SC0","CS0","SS0","CC1","SC1","CS1","SS1","CC2","SC2","CS2","SS2","CC3","SC3","CS3","SS3"}; String [] titles = {"CC0","SC0","CS0","SS0","CC1","SC1","CS1","SS1","CC2","SC2","CS2","SS2","CC3","SC3","CS3","SS3"};
double [][] dbg_tile = new double [16][]; double [][] dbg_tile = new double [16][];
for (int i = 0; i < 16; i++) dbg_tile[i]=clt_data[i>>2][chn][tileY][tileX][i & 3]; for (int i = 0; i < 16; i++) dbg_tile[i]=clt_data[i>>2][chn][tileY][tileX][i & 3];
sdfa_instance.showArrays(dbg_tile, transform_size, transform_size, true, "shifted_x"+tileX+"_y"+tileY, titles); sdfa_instance.showArrays(dbg_tile, transform_size, transform_size, true, "shifted_x"+tileX+"_y"+tileY+"-z", titles);
} }
} }
} }
// calculate overexposed fraction // calculate overexposed fraction
if (saturation_imp != null) { if (saturation_imp != null) {
disparity_map[OVEREXPOSED][nTile] = (1.0 * overexp_all[0]) / overexp_all[1]; disparity_map[OVEREXPOSED][nTile] = (1.0 * overexp_all[0]) / overexp_all[1];
...@@ -2569,6 +3003,7 @@ public class ImageDtt { ...@@ -2569,6 +3003,7 @@ public class ImageDtt {
} }
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
DttRad2 dtt = new DttRad2(dct_size); DttRad2 dtt = new DttRad2(dct_size);
dtt.set_window(window_type); dtt.set_window(window_type);
...@@ -2668,6 +3103,7 @@ public class ImageDtt { ...@@ -2668,6 +3103,7 @@ public class ImageDtt {
ai.set(0); ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
DttRad2 dtt = new DttRad2(dct_size); DttRad2 dtt = new DttRad2(dct_size);
dtt.set_window(window_type); dtt.set_window(window_type);
...@@ -2783,6 +3219,7 @@ public class ImageDtt { ...@@ -2783,6 +3219,7 @@ public class ImageDtt {
ai.set(0); ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
int n2 = transform_size * 2; int n2 = transform_size * 2;
...@@ -2915,6 +3352,7 @@ public class ImageDtt { ...@@ -2915,6 +3352,7 @@ public class ImageDtt {
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -2990,6 +3428,7 @@ public class ImageDtt { ...@@ -2990,6 +3428,7 @@ public class ImageDtt {
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -3109,6 +3548,7 @@ public class ImageDtt { ...@@ -3109,6 +3548,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -3143,6 +3583,7 @@ public class ImageDtt { ...@@ -3143,6 +3583,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
DttRad2 dtt = new DttRad2(dct_size); DttRad2 dtt = new DttRad2(dct_size);
int tileY,tileX; int tileY,tileX;
...@@ -3178,6 +3619,7 @@ public class ImageDtt { ...@@ -3178,6 +3619,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
double scale = 0.25; double scale = 0.25;
...@@ -3299,6 +3741,7 @@ public class ImageDtt { ...@@ -3299,6 +3741,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -3356,6 +3799,7 @@ public class ImageDtt { ...@@ -3356,6 +3799,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -3456,6 +3900,7 @@ public class ImageDtt { ...@@ -3456,6 +3900,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -3645,6 +4090,7 @@ public class ImageDtt { ...@@ -3645,6 +4090,7 @@ public class ImageDtt {
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX,chn; int tileY,tileX,chn;
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
...@@ -3716,13 +4162,15 @@ public class ImageDtt { ...@@ -3716,13 +4162,15 @@ public class ImageDtt {
double centerX, // center of aberration-corrected (common model) tile, X double centerX, // center of aberration-corrected (common model) tile, X
double centerY, // double centerY, //
int debugLevel, int debugLevel,
// boolean bdebug0, // external tile compare
boolean dbg_no_deconvolution, boolean dbg_no_deconvolution,
boolean dbg_transpose, boolean dbg_transpose,
boolean [] saturation_imp, // (near) saturated pixels or null boolean [] saturation_imp, // (near) saturated pixels or null
int [] overexp_all ) // {number of overexposed, number of all tiles} or null int [] overexp_all ) // {number of overexposed, number of all tiles} or null
{ {
boolean debug_fpga = debugLevel < -9;
if (debug_fpga) debugLevel = 1;
boolean use_kernels = (clt_kernels != null) && !dbg_no_deconvolution; boolean use_kernels = (clt_kernels != null) && !dbg_no_deconvolution;
boolean bdebug0 = debugLevel > 0; boolean bdebug0 = debugLevel > 0;
boolean bdebug = debugLevel > 1; boolean bdebug = debugLevel > 1;
...@@ -3757,9 +4205,9 @@ public class ImageDtt { ...@@ -3757,9 +4205,9 @@ public class ImageDtt {
if (bdebug0){ if (bdebug0){
System.out.print(px+"\t"+py+"\t"); System.out.print(px+"\t"+py+"\t");
} }
// Was wrong rounding, fractional part gets to +0.5
int ctile_left = (int) Math.round(px); int ctile_left = (int) -Math.round(-px);
int ctile_top = (int) Math.round(py); int ctile_top = (int) -Math.round(-py);
residual_shift[0] = -(px - ctile_left); residual_shift[0] = -(px - ctile_left);
residual_shift[1] = -(py - ctile_top); residual_shift[1] = -(py - ctile_top);
// 4. Verify the tile fits in image and use System.arraycopy(sym_conv, 0, tile_in, 0, n2*n2) to copy data to tile_in // 4. Verify the tile fits in image and use System.arraycopy(sym_conv, 0, tile_in, 0, n2*n2) to copy data to tile_in
...@@ -3782,6 +4230,30 @@ public class ImageDtt { ...@@ -3782,6 +4230,30 @@ public class ImageDtt {
} }
} }
} }
if (debug_fpga){ // show extended tile, all colors
// //FPGA_TILE_SIZE
System.out.println("\nFull Bayer fpga tile data");
int lt = (FPGA_TILE_SIZE - transform_size2)/2;
double [][] fpga_tile = new double [3][FPGA_TILE_SIZE * FPGA_TILE_SIZE];
for (int fpga_chn = 0; fpga_chn < 3; fpga_chn++){
for (int i = 0; i < FPGA_TILE_SIZE; i++){
System.arraycopy(image_data[fpga_chn], ((ctile_top - lt) + i) * width + (ctile_left - lt), fpga_tile[fpga_chn], FPGA_TILE_SIZE * i, FPGA_TILE_SIZE);
}
}
int id = (1 << (FPGA_PIXEL_BITS - 9)); // 8
for (int i = 0; i < FPGA_TILE_SIZE*FPGA_TILE_SIZE; i++) {
double d = 0.0;
for (int fpga_chn = 0; fpga_chn < 3; fpga_chn++){
d += fpga_tile[fpga_chn][i];
}
System.out.print(String.format("%4x ",(int) Math.round(id * d)));
if (((i+1) %FPGA_TILE_SIZE) == 0) {
System.out.println();
}
}
}
if ((chn == GREEN_CHN) && (saturation_imp != null)) { if ((chn == GREEN_CHN) && (saturation_imp != null)) {
// double overexp_fract = 1.0/(transform_size2 * transform_size2 * QUAD); // double overexp_fract = 1.0/(transform_size2 * transform_size2 * QUAD);
// int num_overexp = 0; // int num_overexp = 0;
...@@ -3814,16 +4286,212 @@ public class ImageDtt { ...@@ -3814,16 +4286,212 @@ public class ImageDtt {
overexp_all[1] += transform_size2 * transform_size2; overexp_all[1] += transform_size2 * transform_size2;
} }
} }
if (debug_fpga) {
System.out.println("debug_fpga: residual_shift[0]="+residual_shift[0]+", residual_shift[1]="+residual_shift[1]);
int ishx, ishy;
ishx = (int) Math.round((1 << (FPGA_SHIFT_BITS)) * residual_shift[0]);
ishy = (int) Math.round((1 << (FPGA_SHIFT_BITS)) * residual_shift[1]);
if (ishx >= (1 << (FPGA_SHIFT_BITS-1))) ishx = (1 << (FPGA_SHIFT_BITS-1)) - 1;
if (ishy >= (1 << (FPGA_SHIFT_BITS-1))) ishy = (1 << (FPGA_SHIFT_BITS-1)) - 1;
if (ishx < -(1 << (FPGA_SHIFT_BITS-1))) ishx = -(1 << (FPGA_SHIFT_BITS-1));
if (ishy < -(1 << (FPGA_SHIFT_BITS-1))) ishy = -(1 << (FPGA_SHIFT_BITS-1));
residual_shift[0] = ishx * (1.0/(1 << (FPGA_SHIFT_BITS)));
residual_shift[1] = ishy * (1.0/(1 << (FPGA_SHIFT_BITS)));
System.out.println("rounded: residual_shift[0]="+residual_shift[0]+", residual_shift[1]="+residual_shift[1]);
double [] fpga_pix_lim = {0.0,0.0};
for (int i = 0; i < 256; i++){
if (tile_in[i] > fpga_pix_lim[0]) fpga_pix_lim[0] = tile_in[i];
if (tile_in[i] < fpga_pix_lim[1]) fpga_pix_lim[1] = tile_in[i];
}
System.out.println(String.format("\n// Pixels input range: %f ... %f", fpga_pix_lim[1], fpga_pix_lim[0]));
System.out.println(String.format("%x // shift_x, %d bits",ishx & ((1 << (FPGA_SHIFT_BITS)) - 1),FPGA_SHIFT_BITS));
System.out.println(String.format("%x // shift_y, %d bits",ishy & ((1 << (FPGA_SHIFT_BITS)) - 1),FPGA_SHIFT_BITS));
System.out.println(String.format("%x // bayer",15));
int id = (1 << (FPGA_PIXEL_BITS - 9)); // 8
for (int row = 0; row <16; row++){
for (int col = 0; col <16; col++){
System.out.print(String.format("%4x ",(int) Math.round(id * tile_in[row*16 + col])));
}
System.out.println();
}
}
// Fold and transform // Fold and transform
double [][][] fold_coeff = null; double [][][] fold_coeff = null;
if (!dbg_transpose){ if (!dbg_transpose){
fold_coeff = dtt.get_shifted_fold_2d( fold_coeff = dtt.get_shifted_fold_2d ( // get_shifted_fold_2d(
transform_size, transform_size,
residual_shift[0], residual_shift[0],
residual_shift[1]); residual_shift[1],
0); // debug level
} }
if (debug_fpga) {
System.out.println("debug_fpga: residual_shift[0]="+residual_shift[0]+", residual_shift[1]="+residual_shift[1]);
System.out.println("Signs table (per mode, per index - bitstring of variants, 0 - positive, 1 - negative");
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
int d = 0;
for (int b = 0; b < 4; b++){
if (fold_coeff[dct_mode][i][b] < 0){
d |= (1 << b);
}
}
System.out.print(String.format("%x ",d));
if ((i % 16) == 15){
System.out.println();
}
}
}
System.out.println("Absolute values, shoud be the same for each of 4 modes");
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
for (int b = 0; b < 4; b++){
int d = (int) Math.round(((1 << FPGA_WND_BITS) -1)* Math.abs(fold_coeff[dct_mode][i][b]));
System.out.print(String.format("%5x ",d & ((1 << (FPGA_WND_BITS)) - 1)));
}
if ((i % 4) == 3){
System.out.println();
}
}
System.out.println();
}
double [][][] fold_coeff_direct = dtt.get_shifted_fold_2d_direct ( // get_shifted_fold_2d(
transform_size,
residual_shift[0],
residual_shift[1],
(1 << FPGA_WND_BITS) -1); // debug level - use as scale
System.out.println("Direct sin table");
for (int i = 0; i < 64; i++){
for (int b = 0; b < 4; b++){
int d = (int) Math.round(((1 << FPGA_WND_BITS) -1)* Math.abs(fold_coeff_direct[0][i][b])); // dct_mode=0
System.out.print(String.format("%5x ",d & ((1 << (FPGA_WND_BITS)) - 1)));
}
if ((i % 4) == 3){
System.out.println();
}
}
System.out.println();
double [][][] fold_coeff_old = dtt.get_shifted_fold_2d ( // get_shifted_fold_2d(
transform_size,
residual_shift[0],
residual_shift[1],
(1 << FPGA_WND_BITS) -1); // debug level - use as scale
System.out.println("Direct sin table");
for (int i = 0; i < 64; i++){
for (int b = 0; b < 4; b++){
int d = (int) Math.round(((1 << FPGA_WND_BITS) -1)* Math.abs(fold_coeff_old[0][i][b])); // dct_mode=0
System.out.print(String.format("%5x ",d & ((1 << (FPGA_WND_BITS)) - 1)));
}
if ((i % 4) == 3){
System.out.println();
}
}
System.out.println();
System.out.println("Diff: new - old");
for (int i = 0; i < 64; i++){
for (int b = 0; b < 4; b++){
int d0 = (int) Math.round(((1 << FPGA_WND_BITS) -1)* Math.abs(fold_coeff[0][i][b])); // dct_mode=0
int d = (int) Math.round(((1 << FPGA_WND_BITS) -1)* Math.abs(fold_coeff_direct[0][i][b])); // dct_mode=0
System.out.print(String.format("%5d ",d - d0));
}
if ((i % 4) == 3){
System.out.println();
}
}
System.out.println();
System.out.println("\nFold index");
int [][] fpga_fi = dtt.getFoldIndex();
for (int i = 0; i < 64; i++){
for (int k = 0; k <4; k++) {
System.out.print(String.format("%02x ", fpga_fi[i][k]));
}
System.out.print(" ");
if (i%8 == 7) System.out.println();
}
System.out.println();
// Show for different Bayer patterns
int [] bayer_patterns = {0x1, 0x2, 0x4, 0x8, 0x9, 0x6};
for (int bp:bayer_patterns){
System.out.println("Pattern (row/col) "+bp+":");
System.out.println("| "+(((bp & 1) !=0) ? "X ":" ")+(((bp & 2) !=0) ? "X ":" ")+"|");
System.out.println("| "+(((bp & 4) !=0) ? "X ":" ")+(((bp & 8) !=0) ? "X ":" ")+"|");
for (int i = 0; i < 64; i++){
for (int k = 0; k <4; k++) {
int row = (fpga_fi[i][k] >> 4);
int col = (fpga_fi[i][k] & 0xf);
int indx = (row & 1) + 2 * (col & 1);
if (((1 << indx) & bp) != 0) {
System.out.print(String.format("%2x ", fpga_fi[i][k]));
} else {
System.out.print(" . ");
}
}
System.out.print(" ");
if (i%8 == 7) System.out.println();
}
System.out.println();
}
for (int bp:bayer_patterns){
System.out.println("Pattern (mode bits) "+bp+":");
System.out.println("| "+(((bp & 1) !=0) ? "X ":" ")+(((bp & 2) !=0) ? "X ":" ")+"|");
System.out.println("| "+(((bp & 4) !=0) ? "X ":" ")+(((bp & 8) !=0) ? "X ":" ")+"|");
for (int i = 0; i < 64; i++){
for (int k = 0; k < 4; k++) {
int row = (fpga_fi[i][k] >> 4);
int col = (fpga_fi[i][k] & 0xf);
int indx = (row & 1) + 2 * (col & 1);
int d = 0;
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
if (fold_coeff[dct_mode][i][k] < 0){
d |= (1 << dct_mode);
}
}
if (((1 << indx) & bp) != 0) {
System.out.print(String.format("%02x ", d));
} else {
System.out.print(" . ");
}
}
System.out.print(" ");
if (i%8 == 7) System.out.println();
}
System.out.println();
}
double [][] fpga_w_u = new double [4][256];
double [][] fpga_w_s = new double [4][256];
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
for (int b=0; b < 4; b++){
fpga_w_u [dct_mode][fpga_fi[i][b]] = Math.abs(fold_coeff[dct_mode][i][b]);
fpga_w_s [dct_mode][fpga_fi[i][b]] = fold_coeff[dct_mode][i][b];
}
}
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
String [] titles = {"CC","SC","CS","SS"};
sdfa_instance.showArrays(fpga_w_s, 2 * transform_size, 2 * transform_size, true, "fpga_w_s_x"+ctile_left+"_y"+ctile_top, titles);
sdfa_instance.showArrays(fpga_w_u, 2 * transform_size, 2 * transform_size, true, "fpga_w_u_x"+ctile_left+"_y"+ctile_top, titles);
} //if (debug_fpga)
if (!debug_fpga) {
for (int dct_mode = 0; dct_mode <4; dct_mode++) { for (int dct_mode = 0; dct_mode <4; dct_mode++) {
if (fold_coeff != null){ if (fold_coeff != null){
clt_tile[dct_mode] = dtt.fold_tile (tile_in, transform_size, dct_mode, fold_coeff); // DCCT, DSCT, DCST, DSST clt_tile[dct_mode] = dtt.fold_tile (tile_in, transform_size, dct_mode, fold_coeff); // DCCT, DSCT, DCST, DSST
...@@ -3832,6 +4500,94 @@ public class ImageDtt { ...@@ -3832,6 +4500,94 @@ public class ImageDtt {
} }
clt_tile[dct_mode] = dtt.dttt_iv (clt_tile[dct_mode], dct_mode, transform_size); clt_tile[dct_mode] = dtt.dttt_iv (clt_tile[dct_mode], dct_mode, transform_size);
} }
}
if (debug_fpga){
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
if (fold_coeff != null){
clt_tile[dct_mode] = dtt.fold_tile_debug (tile_in, transform_size, dct_mode, fold_coeff); // DCCT, DSCT, DCST, DSST
} else {
clt_tile[dct_mode] = dtt.fold_tile (tile_in, transform_size, dct_mode); // DCCT, DSCT, DCST, DSST
}
}
double [] fpga_dtt_lim = {0.0,0.0};
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
if (clt_tile[dct_mode][i] > fpga_dtt_lim[0]) fpga_dtt_lim[0] = clt_tile[dct_mode][i];
if (clt_tile[dct_mode][i] < fpga_dtt_lim[1]) fpga_dtt_lim[1] = clt_tile[dct_mode][i];
}
}
System.out.println(String.format("// DTT input range: %f ... %f", fpga_dtt_lim[1], fpga_dtt_lim[0]));
double scale = (1 << (FPGA_DTT_IN - 9)); // -1;
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
scale *= 1.0 *((1 << FPGA_WND_BITS) -1) / (1 << FPGA_WND_BITS);
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
int id = (int) Math.round(scale * clt_tile[dct_mode][i]);
System.out.print(String.format("%7x ", id & ((1 << 25) -1)));
if ((i % 8) == 7) System.out.println();
}
System.out.println();
}
System.out.println();
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
System.out.println("Color= 2? clt_tile[dct_mode] = dtt.dttt_iv(..., scale=" +scale);
clt_tile[dct_mode] = dtt.dttt_iv (clt_tile[dct_mode], dct_mode, transform_size, scale, ((1 << 25) -1)); // debug level
}
fpga_dtt_lim[0] = 0.0;
fpga_dtt_lim[1] = 0.0;
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
if (clt_tile[dct_mode][i] > fpga_dtt_lim[0]) fpga_dtt_lim[0] = clt_tile[dct_mode][i];
if (clt_tile[dct_mode][i] < fpga_dtt_lim[1]) fpga_dtt_lim[1] = clt_tile[dct_mode][i];
}
}
System.out.println(String.format("// DTT output range: %f ... %f", fpga_dtt_lim[1], fpga_dtt_lim[0]));
// scale = (1 << (FPGA_DTT_IN - 9)); // -1;
for (int dct_mode = 0; dct_mode <4; dct_mode++) {
for (int i = 0; i < 64; i++){
int id = (int) Math.round(scale * clt_tile[dct_mode][i]);
System.out.print(String.format("%7x ", id & ((1 << 25) -1)));
if ((i % 8) == 7) System.out.println();
}
System.out.println();
}
System.out.println();
System.out.println("Testing symmetry of checkerboard patterns");
for (int dct_mode = 0; dct_mode < 2; dct_mode++) {
for (int i = 0; i < 64; i++){
int id = (int) Math.round(scale * clt_tile[dct_mode][i]);
int id1 = (int) Math.round(scale * clt_tile[3-dct_mode][63-i]);
System.out.print(String.format("%7x ", (id-id1) & ((1 << 25) -1)));
if ((i % 8) == 7) System.out.println();
}
System.out.println();
}
System.out.println();
System.out.println("Testing antisymmetry of checkerboard patterns");
for (int dct_mode = 0; dct_mode < 2; dct_mode++) {
for (int i = 0; i < 64; i++){
int id = (int) Math.round(scale * clt_tile[dct_mode][i]);
int id1 = (int) Math.round(scale * clt_tile[3-dct_mode][63-i]);
System.out.print(String.format("%7x ", (id+id1) & ((1 << 25) -1)));
if ((i % 8) == 7) System.out.println();
}
System.out.println();
}
System.out.println();
//apply rotation
}
if (bdebug0) { if (bdebug0) {
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging? showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
sdfa_instance.showArrays(tile_in, transform_size2, transform_size2, "tile_in_x"+ctile_left+"_y"+ctile_top); sdfa_instance.showArrays(tile_in, transform_size2, transform_size2, "tile_in_x"+ctile_left+"_y"+ctile_top);
...@@ -4061,6 +4817,7 @@ public class ImageDtt { ...@@ -4061,6 +4817,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
DttRad2 dtt = new DttRad2(dct_size); DttRad2 dtt = new DttRad2(dct_size);
dtt.set_window(window_type); dtt.set_window(window_type);
...@@ -4128,6 +4885,7 @@ public class ImageDtt { ...@@ -4128,6 +4885,7 @@ public class ImageDtt {
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
int tileY,tileX; int tileY,tileX;
double [] dct1 = new double [dct_size*dct_size]; double [] dct1 = new double [dct_size*dct_size];
......
...@@ -116,6 +116,14 @@ public class QuadCLT { ...@@ -116,6 +116,14 @@ public class QuadCLT {
} }
} }
public void listGeometryCorrection(boolean full){
GeometryCorrection gc = geometryCorrection;
if (gc == null) { // if it was not yet created
gc = new GeometryCorrection(this.extrinsic_corr);
}
gc.listGeometryCorrection(full);
}
public void getProperties(){ // restore public void getProperties(){ // restore
for (int n = 0; n < fine_corr.length; n++){ for (int n = 0; n < fine_corr.length; n++){
for (int d = 0; d < fine_corr[n].length; d++){ for (int d = 0; d < fine_corr[n].length; d++){
...@@ -3661,7 +3669,7 @@ public class QuadCLT { ...@@ -3661,7 +3669,7 @@ public class QuadCLT {
clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing
clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down) clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down)
-1234, // clt_parameters.tileX, // final int debug_tileX, clt_parameters.tileX, // -1234, // clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY, -1234 will cause port coordinates debug images clt_parameters.tileY, // final int debug_tileY, -1234 will cause port coordinates debug images
(clt_parameters.dbg_mode & 64) != 0, // no fract shift (clt_parameters.dbg_mode & 64) != 0, // no fract shift
(clt_parameters.dbg_mode & 128) != 0, // no convolve (clt_parameters.dbg_mode & 128) != 0, // no convolve
......
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