Commit a602300e authored by Andrey Filippov's avatar Andrey Filippov

for functions to Differentials_, added multithreaded version

parent 151ea276
...@@ -3,6 +3,8 @@ package epfl; ...@@ -3,6 +3,8 @@ package epfl;
| Version: April 6, 2014 | Version: April 6, 2014
\=====================================================================*/ \=====================================================================*/
import java.util.concurrent.atomic.AtomicInteger;
/*===================================================================== /*=====================================================================
| Philippe Thevenaz | Philippe Thevenaz
| EPFL/STI/IMT-LS/LIB/BM.4.137 | EPFL/STI/IMT-LS/LIB/BM.4.137
...@@ -77,6 +79,12 @@ public final static int GRADIENT_X = 6; ...@@ -77,6 +79,12 @@ public final static int GRADIENT_X = 6;
public final static int GRADIENT_Y = 7; public final static int GRADIENT_Y = 7;
public final static int GRADIENT_XY = 8; public final static int GRADIENT_XY = 8;
public final static int NORMALIZE_LMAX = 9; public final static int NORMALIZE_LMAX = 9;
public final static int LOCAL_MIN = 10; // local minimum within radius
public final static int LOCAL_MAX = 11; // local maximum within radius
public final static int LOCAL_DIFF = 12; // local maximum - local minimum within radius
private final static int THREADS_MAX = 100;
/*.................................................................... /*....................................................................
private variables private variables
...@@ -103,7 +111,10 @@ private static String[] operations = { ...@@ -103,7 +111,10 @@ private static String[] operations = {
"Gradient X", "Gradient X",
"Gradient Y", "Gradient Y",
"Directional derivative", "Directional derivative",
"Normalize by local maximum" "Normalize by local maximum",
"Local min",
"Local max",
"Local diff"
}; };
/*.................................................................... /*....................................................................
...@@ -147,17 +158,19 @@ public void run ( ...@@ -147,17 +158,19 @@ public void run (
GenericDialog dialog = new GenericDialog("Differentials"); GenericDialog dialog = new GenericDialog("Differentials");
dialog.addChoice("Operation:", operations, operations[operation]); dialog.addChoice("Operation:", operations, operations[operation]);
dialog.addMessage("--- optional parameters ---"); dialog.addMessage("--- optional parameters ---");
dialog.addNumericField("Multiply d/dx by", dir_x, 3,5,""); dialog.addNumericField("Multiply_d/dx_by", dir_x, 3,5,"");
dialog.addNumericField("Multiply d/dy by", dir_y, 3,5,""); dialog.addNumericField("Multiply_d/dy_by", dir_y, 3,5,"");
dialog.addNumericField("Normalization radius", max_norm_rad, 3,5,""); dialog.addNumericField("Normalization_radius", max_norm_rad, 3,5,"");
dialog.showDialog(); dialog.showDialog();
if (dialog.wasCanceled()) { if (dialog.wasCanceled()) {
return; return;
} }
final String operationString = dialog.getNextChoice(); final String operationString = dialog.getNextChoice();
System.out.println("operationString='"+operationString+"'");
for (int choice = 0; (choice < operations.length); choice++) { for (int choice = 0; (choice < operations.length); choice++) {
if (operationString == operations[choice]) { if (operationString.equals(operations[choice])) {
operation = choice; operation = choice;
break; break;
} }
...@@ -165,7 +178,7 @@ public void run ( ...@@ -165,7 +178,7 @@ public void run (
dir_x = (float) dialog.getNextNumber(); dir_x = (float) dialog.getNextNumber();
dir_y = (float) dialog.getNextNumber(); dir_y = (float) dialog.getNextNumber();
max_norm_rad = dialog.getNextNumber(); max_norm_rad = dialog.getNextNumber();
System.out.println("operation="+operation+", dir_x="+dir_x+", dir_y="+dir_y+", max_norm_rad="+max_norm_rad);
imp.startTiming(); imp.startTiming();
if (1 < imp.getStackSize()) { if (1 < imp.getStackSize()) {
if (!(imp.getProcessor().getPixels() instanceof float[])) { if (!(imp.getProcessor().getPixels() instanceof float[])) {
...@@ -357,6 +370,156 @@ private void doIt ( ...@@ -357,6 +370,156 @@ private void doIt (
throw new IllegalArgumentException("Float image required"); throw new IllegalArgumentException("Float image required");
} }
switch (operation) { switch (operation) {
case LOCAL_DIFF:
{
final int ir = (int) Math.ceil(max_norm_rad);
final double r2 = max_norm_rad * max_norm_rad;
final float[] floatPixels = (float[])ip.getPixels();
final double [] pixels = new double[floatPixels.length];
for (int i = 0; i < pixels.length; i++) {
pixels[i] = floatPixels[i];
}
final Thread[] threads = newThreadArray(THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int y00 = 0; (y00 < height); y00++) {
final int y0 = y00;
int ymin = Math.max(y0-ir, 0);
int ymax = Math.min(y0+ir, height-1);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int x0 = ai.getAndIncrement(); x0 < width; x0 = ai.getAndIncrement()) {
int k = y0*width + x0;
int xmin = Math.max(x0-ir, 0);
int xmax = Math.min(x0+ir, width-1);
double d = pixels[k];
double dmax = d;
double dmin = d;
for (int y = ymin; y <= ymax; y++) {
for (int x = xmin; x <= xmax; x++) {
int dx = x-x0;
int dy = y-y0;
if ((dx*dx+dy*dy) > r2) {
continue;
}
if (pixels[y*width+x] > dmax) {
dmax=pixels[y*width+x];
} else if (pixels[y*width+x] < dmin) {
dmin=pixels[y*width+x];
}
}
}
floatPixels[k] = (float) (dmax - dmin);
}
}
};
}
startAndJoin(threads);
stepProgressBar();
}
}
break;
case LOCAL_MIN:
{
final int ir = (int) Math.ceil(max_norm_rad);
final double r2 = max_norm_rad * max_norm_rad;
final float[] floatPixels = (float[])ip.getPixels();
final double [] pixels = new double[floatPixels.length];
for (int i = 0; i < pixels.length; i++) {
pixels[i] = floatPixels[i];
}
final Thread[] threads = newThreadArray(THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int y00 = 0; (y00 < height); y00++) {
final int y0 = y00;
int ymin = Math.max(y0-ir, 0);
int ymax = Math.min(y0+ir, height-1);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int x0 = ai.getAndIncrement(); x0 < width; x0 = ai.getAndIncrement()) {
int k = y0*width + x0;
int xmin = Math.max(x0-ir, 0);
int xmax = Math.min(x0+ir, width-1);
double d = pixels[k];
double dmin = d;
for (int y = ymin; y <= ymax; y++) {
for (int x = xmin; x <= xmax; x++) {
int dx = x-x0;
int dy = y-y0;
if ((dx*dx+dy*dy) > r2) {
continue;
}
if (pixels[y*width+x] < dmin) {
dmin=pixels[y*width+x];
}
}
}
floatPixels[k] = (float) dmin;
}
}
};
}
startAndJoin(threads);
stepProgressBar();
}
}
break;
case LOCAL_MAX:
{
final int ir = (int) Math.ceil(max_norm_rad);
final double r2 = max_norm_rad * max_norm_rad;
final float[] floatPixels = (float[])ip.getPixels();
final double [] pixels = new double[floatPixels.length];
for (int i = 0; i < pixels.length; i++) {
pixels[i] = floatPixels[i];
}
final Thread[] threads = newThreadArray(THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int y00 = 0; (y00 < height); y00++) {
final int y0 = y00;
int ymin = Math.max(y0-ir, 0);
int ymax = Math.min(y0+ir, height-1);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int x0 = ai.getAndIncrement(); x0 < width; x0 = ai.getAndIncrement()) {
int k = y0*width + x0;
int xmin = Math.max(x0-ir, 0);
int xmax = Math.min(x0+ir, width-1);
double d = pixels[k];
double dmax = d;
for (int y = ymin; y <= ymax; y++) {
for (int x = xmin; x <= xmax; x++) {
int dx = x-x0;
int dy = y-y0;
if ((dx*dx+dy*dy) > r2) {
continue;
}
if (pixels[y*width+x] > dmax) {
dmax=pixels[y*width+x];
}
}
}
floatPixels[k] = (float) dmax;
}
}
};
}
startAndJoin(threads);
stepProgressBar();
}
}
break;
case NORMALIZE_LMAX: case NORMALIZE_LMAX:
{ {
int ir = (int) Math.ceil(max_norm_rad); int ir = (int) Math.ceil(max_norm_rad);
...@@ -771,6 +934,9 @@ private void setupProgressBar ( ...@@ -771,6 +934,9 @@ private void setupProgressBar (
completed = 0; completed = 0;
lastTime = System.currentTimeMillis(); lastTime = System.currentTimeMillis();
switch (operation) { switch (operation) {
case LOCAL_MIN:
case LOCAL_MAX:
case LOCAL_DIFF:
case NORMALIZE_LMAX: case NORMALIZE_LMAX:
processDuration = stackSize * (width + 1 * height); processDuration = stackSize * (width + 1 * height);
break; break;
...@@ -849,4 +1015,36 @@ private void symmetricFirMirrorOnBounds ( ...@@ -849,4 +1015,36 @@ private void symmetricFirMirrorOnBounds (
} }
} /* end symmetricFirMirrorOnBounds */ } /* end symmetricFirMirrorOnBounds */
/* Create a Thread[] array as large as the number of processors available.
* From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
public static Thread[] newThreadArray(int maxCPUs) { // USED in lwir
int n_cpus = Runtime.getRuntime().availableProcessors();
if (n_cpus>maxCPUs)n_cpus=maxCPUs;
return new Thread[n_cpus];
}
/* Start all given threads and wait on each of them until all are done.
* From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
public static void startAndJoin(Thread[] threads) // USED in lwir
{
for (int ithread = 0; ithread < threads.length; ++ithread)
{
threads[ithread].setPriority(Thread.NORM_PRIORITY);
threads[ithread].start();
}
try
{
for (int ithread = 0; ithread < threads.length; ++ithread)
threads[ithread].join();
} catch (InterruptedException ie)
{
throw new RuntimeException(ie);
}
}
} /* end class Differentials_ */ } /* end class Differentials_ */
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