Commit 08bccd0d authored by Andrey Filippov's avatar Andrey Filippov

implementing moving objects masking for ERS fitting, this is debug

version for GPU geometry correction
parent fabadb74
......@@ -29,23 +29,70 @@ package com.elphel.imagej.common;
public class DoubleGaussianBlur {
/* the standard deviation of the Gaussian*/
// private static double sigma = 2.0;
// private static double sigma = 2.0;
/* whether sigma is given in units corresponding to the pixel scale (not pixels)*/
// private static boolean sigmaScaled = false;
// private static boolean sigmaScaled = false;
/* The flags specifying the capabilities and needs */
// private int flags = DOES_ALL|SUPPORTS_MASKING|PARALLELIZE_STACKS|KEEP_PREVIEW;
// private ImagePlus imp; // The ImagePlus of the setup call, needed to get the spatial calibration
// private boolean hasScale = false; // whether the image has an x&y scale
// private int flags = DOES_ALL|SUPPORTS_MASKING|PARALLELIZE_STACKS|KEEP_PREVIEW;
// private ImagePlus imp; // The ImagePlus of the setup call, needed to get the spatial calibration
// private boolean hasScale = false; // whether the image has an x&y scale
private int nPasses = 1; // The number of passes (filter directions * color channels * stack slices)
// private int nChannels = 1; // The number of color channels
// private int nChannels = 1; // The number of color channels
private int pass; // Current pass
/* Default constructor */
public DoubleGaussianBlur() {
}
public double [] blurWithNaN(
double[] pixels,
double [] in_weight, // or null
int width,
int height,
double sigmaX,
double sigmaY,
double accuracy
) {
double [] weight;
double [] blured = new double[pixels.length];
if (in_weight == null) {
weight = new double [pixels.length];
for (int i = 0; i < weight.length; i++) {
weight[i] = 1.0;
}
} else {
weight = in_weight.clone();
}
for (int i = 0; i < pixels.length; i++) {
if (Double.isNaN(pixels[i])) {
weight[i] = 0.0;
} else {
blured[i] = pixels[i] * weight[i];
}
}
blurDouble(
blured,
width,
height,
sigmaX,
sigmaY,
accuracy);
blurDouble(
weight,
width,
height,
sigmaX,
sigmaY,
accuracy);
for (int i = 0; i < pixels.length; i++) {
blured[i] /= weight[i];
}
return blured;
}
public void blurDouble(double[] pixels,
public void blurDouble(
double[] pixels,
int width,
int height,
double sigmaX,
......@@ -73,31 +120,31 @@ public class DoubleGaussianBlur {
double sigma,
double accuracy,
boolean xDirection
// int extraLines
// int extraLines
) {
final int UPSCALE_K_RADIUS = 2; //number of pixels to add for upscaling
final double MIN_DOWNSCALED_SIGMA = 4.; //minimum standard deviation in the downscaled image
// float[] pixels = (float[])ip.getPixels();
// int width = ip.getWidth();
// int height = ip.getHeight();
// Rectangle roi = ip.getRoi();
// float[] pixels = (float[])ip.getPixels();
// int width = ip.getWidth();
// int height = ip.getHeight();
// Rectangle roi = ip.getRoi();
int length = xDirection ? width : height; //number of points per line (line can be a row or column)
int pointInc = xDirection ? 1 : width; //increment of the pixels array index to the next point in a line
int lineInc = xDirection ? width : 1; //increment of the pixels array index to the next line
// int lineFrom = (xDirection ? roi.y : roi.x) - extraLines; //the first line to process
// if (lineFrom < 0) lineFrom = 0;
// int lineFrom = (xDirection ? roi.y : roi.x) - extraLines; //the first line to process
// if (lineFrom < 0) lineFrom = 0;
int lineFrom = 0; //the first line to process
// int lineTo = (xDirection ? roi.y+roi.height : roi.x+roi.width) + extraLines; //the last line+1 to process
// if (lineTo > (xDirection ? height:width)) lineTo = (xDirection ? height:width);
// int lineTo = (xDirection ? roi.y+roi.height : roi.x+roi.width) + extraLines; //the last line+1 to process
// if (lineTo > (xDirection ? height:width)) lineTo = (xDirection ? height:width);
int lineTo = (xDirection ? height:width);
// int writeFrom = xDirection? roi.x : roi.y; //first point of a line that needs to be written
// int writeTo = xDirection ? roi.x+roi.width : roi.y+roi.height;
// int writeFrom = xDirection? roi.x : roi.y; //first point of a line that needs to be written
// int writeTo = xDirection ? roi.x+roi.width : roi.y+roi.height;
int writeFrom = 0; //first point of a line that needs to be written
int writeTo = xDirection ? width : height;
// int inc = Math.max((lineTo-lineFrom)/(100/(nPasses>0?nPasses:1)+1),20);
// int inc = Math.max((lineTo-lineFrom)/(100/(nPasses>0?nPasses:1)+1),20);
pass++;
if (pass>nPasses) pass =1;
// Thread thread = Thread.currentThread(); // needed to check for interrupted state
// Thread thread = Thread.currentThread(); // needed to check for interrupted state
if (sigma > 2*MIN_DOWNSCALED_SIGMA + 0.5) {
/* large radius (sigma): scale down, then convolve, then scale up */
int reduceBy = (int)Math.floor(sigma/MIN_DOWNSCALED_SIGMA); //downscale by this factor
......
......@@ -106,6 +106,7 @@ public class GPUTileProcessor {
static String GPU_RBGA_NAME = "generate_RBGA"; // name in C code
static String GPU_ROT_DERIV = "calc_rot_deriv"; // calculate rotation matrices and derivatives
static String GPU_SET_TILES_OFFSETS = "get_tiles_offsets"; // calculate pixel offsets and disparity distortions
static String GPU_CALCULATE_TILES_OFFSETS = "calculate_tiles_offsets"; // calculate pixel offsets and disparity distortions
static String GPU_CALC_REVERSE_DISTORTION = "calcReverseDistortionTable"; // calculate reverse radial distortion table from gpu_geometry_correction
// pass some defines to gpu source code with #ifdef JCUDA
......@@ -168,7 +169,8 @@ public class GPUTileProcessor {
private CUfunction GPU_TEXTURES_kernel = null;
private CUfunction GPU_RBGA_kernel = null;
private CUfunction GPU_ROT_DERIV_kernel = null;
private CUfunction GPU_SET_TILES_OFFSETS_kernel = null;
// private CUfunction GPU_SET_TILES_OFFSETS_kernel = null;
private CUfunction GPU_CALCULATE_TILES_OFFSETS_kernel = null;
private CUfunction GPU_CALC_REVERSE_DISTORTION_kernel = null;
CUmodule module; // to access constants memory
......@@ -393,7 +395,8 @@ public class GPUTileProcessor {
GPU_TEXTURES_NAME,
GPU_RBGA_NAME,
GPU_ROT_DERIV,
GPU_SET_TILES_OFFSETS,
// GPU_SET_TILES_OFFSETS,
GPU_CALCULATE_TILES_OFFSETS,
GPU_CALC_REVERSE_DISTORTION
};
CUfunction[] functions = createFunctions(kernelSources,
......@@ -408,7 +411,8 @@ public class GPUTileProcessor {
GPU_TEXTURES_kernel= functions[5];
GPU_RBGA_kernel= functions[6];
GPU_ROT_DERIV_kernel = functions[7];
GPU_SET_TILES_OFFSETS_kernel = functions[8];
// GPU_SET_TILES_OFFSETS_kernel = functions[8];
GPU_CALCULATE_TILES_OFFSETS_kernel = functions[8];
GPU_CALC_REVERSE_DISTORTION_kernel = functions[9];
System.out.println("GPU kernel functions initialized");
......@@ -420,7 +424,8 @@ public class GPUTileProcessor {
System.out.println(GPU_TEXTURES_kernel.toString());
System.out.println(GPU_RBGA_kernel.toString());
System.out.println(GPU_ROT_DERIV_kernel.toString());
System.out.println(GPU_SET_TILES_OFFSETS_kernel.toString());
// System.out.println(GPU_SET_TILES_OFFSETS_kernel.toString());
System.out.println(GPU_CALCULATE_TILES_OFFSETS_kernel.toString());
System.out.println(GPU_CALC_REVERSE_DISTORTION_kernel.toString());
// GPU data structures are now initialized through GpuQuad instances
......@@ -1603,7 +1608,8 @@ public class GPUTileProcessor {
/**
* Calculate tiles offsets (before each direct conversion run)
*/
public void execSetTilesOffsets() {
/*
public void execSetTilesOffsetsOld() {
execCalcReverseDistortions(); // will check if it is needed first
execRotDerivs(); // will check if it is needed first
if (GPU_SET_TILES_OFFSETS_kernel == null)
......@@ -1612,7 +1618,7 @@ public class GPUTileProcessor {
return;
}
// kernel parameters: pointer to pointers
int [] GridFullWarps = {(num_task_tiles + TILES_PER_BLOCK_GEOM - 1)/TILES_PER_BLOCK_GEOM, 1, 1}; // round up
int [] GridFullWarps = {(num_task_tiles + 2 * TILES_PER_BLOCK_GEOM - 1)/TILES_PER_BLOCK_GEOM, 1, 1}; // round up
int [] ThreadsFullWarps = {num_cams, TILES_PER_BLOCK_GEOM, 1}; // 4,8,1
Pointer kernelParameters = Pointer.to(
Pointer.to(gpu_tasks), // struct tp_task * gpu_tasks,
......@@ -1632,6 +1638,42 @@ public class GPUTileProcessor {
System.out.println("======execSetTilesOffsets()");
}
}
*/
public void execSetTilesOffsets() {
execCalcReverseDistortions(); // will check if it is needed first
execRotDerivs(); // will check if it is needed first
if (GPU_CALCULATE_TILES_OFFSETS_kernel == null)
{
IJ.showMessage("Error", "No GPU kernel: GPU_CALCULATE_TILES_OFFSETS_kernel");
return;
}
if (gpu_debug_level > -1) {
System.out.println("num_task_tiles="+num_task_tiles);
}
// kernel parameters: pointer to pointers
// int [] GridFullWarps = {(num_task_tiles + 2 * TILES_PER_BLOCK_GEOM - 1)/TILES_PER_BLOCK_GEOM, 1, 1}; // round up
// int [] ThreadsFullWarps = {num_cams, TILES_PER_BLOCK_GEOM, 1}; // 4,8,1
int [] GridFullWarps = {1, 1, 1}; // round up
int [] ThreadsFullWarps = {1, 1, 1}; // 4,8,1
Pointer kernelParameters = Pointer.to(
Pointer.to(gpu_tasks), // struct tp_task * gpu_tasks,
Pointer.to(new int[] { num_task_tiles }),// int num_tiles, // number of tiles in task list
Pointer.to(gpu_geometry_correction), // struct gc * gpu_geometry_correction,
Pointer.to(gpu_correction_vector), // struct corr_vector * gpu_correction_vector,
Pointer.to(gpu_rByRDist), // float * gpu_rByRDist) // length should match RBYRDIST_LEN
Pointer.to(gpu_rot_deriv)); // trot_deriv * gpu_rot_deriv);
cuCtxSynchronize();
cuLaunchKernel(GPU_CALCULATE_TILES_OFFSETS_kernel,
GridFullWarps[0], GridFullWarps[1], GridFullWarps[2], // Grid dimension
ThreadsFullWarps[0], ThreadsFullWarps[1],ThreadsFullWarps[2],// Block dimension
0, null, // Shared memory size and stream (shared - only dynamic, static is in code)
kernelParameters, null); // Kernel- and extra parameters
cuCtxSynchronize(); // remove later
if (gpu_debug_level > -1) {
System.out.println("======execSetTilesOffsets()");
}
}
/**
* Direct CLT conversion and aberration correction
......
......@@ -7904,7 +7904,7 @@ public class QuadCLTCPU {
CLTPass3d scan = tp.clt_3d_passes.get(combo_scan);
// for the second half of runs (always for single run) - limit infinity min/max
boolean debug_actual_LY_derivs = true; // debugLevel > 9;
boolean debug_actual_LY_derivs = debugLevel > 9; // true
if (debug_actual_LY_derivs) {
debugLYDerivatives(
......
......@@ -513,4 +513,41 @@ public class TileNeibs{
return num_total_removed;
}
public boolean [] fillConcave(
boolean [] tiles // should be the same size
) {
boolean [] filled = tiles.clone();
int min_neibs = 4;
ArrayList<Integer> front = new ArrayList<Integer>();
for (int start_indx = 0; start_indx < tiles.length; start_indx++) if (!filled[start_indx]) {
int nneib = 0;
for (int dir = 0; dir < dirs; dir++) {
int id = getNeibIndex(start_indx, dir);
if ((id >= 0) && filled[id]) nneib++;
}
if (nneib >= min_neibs) {
front.add(start_indx); // do not mark yet
filled[start_indx] = true;
while (!front.isEmpty()) {
int seed = front.remove(0);// get oldest element
for (int d = 0; d < dirs; d++){
int indx = getNeibIndex(seed, d);
if ((indx >=0) && !filled[indx]) {
nneib = 0;
for (int dir = 0; dir < dirs; dir++) {
int id = getNeibIndex(indx, dir);
if ((id >= 0) && filled[id]) nneib++;
}
if (nneib >= min_neibs) {
front.add(indx); // do not mark yet
filled[indx] = true;
}
}
}
}
}
}
return filled;
}
}
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