Skip to content

Commit

Permalink
Merge pull request #189 from saalfeldlab/feature/exponential-fit
Browse files Browse the repository at this point in the history
Exponential fit
  • Loading branch information
minnerbe authored May 2, 2024
2 parents be048a7 + 1002f08 commit 7976e1b
Show file tree
Hide file tree
Showing 9 changed files with 461 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.janelia.alignment.filter;

import ij.process.ImageProcessor;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* Holds a list of {@link Filter}s to be applied in sequence (first to last).
*
* @author Michael Innerberger
*/
public class CompositeFilter implements Filter {

private List<Filter> filters;

// empty constructor required to create instances from specifications
@SuppressWarnings("unused")
public CompositeFilter() {
this((List<Filter>) null);
}

public CompositeFilter(final Filter... filters) {
this(List.of(filters));
}

public CompositeFilter(final List<Filter> filters) {
this.filters = filters;
}

@Override
public void init(final Map<String, String> params) {
filters = new ArrayList<>(params.size());
for (int i = 0; i < params.size(); i++) {
final String serializedFilter = params.get(filterKey(i));
final FilterSpec filterSpec = FilterSpec.fromJson(serializedFilter);
filters.add(filterSpec.buildInstance());
}
}

@Override
public Map<String, String> toParametersMap() {
final Map<String, String> map = new LinkedHashMap<>();
for (int i = 0; i < filters.size(); i++) {
final FilterSpec filterSpec = FilterSpec.forFilter(filters.get(i));
map.put(filterKey(i), filterSpec.toJson());
}
return map;
}

private static String filterKey(final int i) {
return "filter" + i;
}

@Override
public void process(final ImageProcessor ip, final double scale) {
for (final Filter filter : filters) {
filter.process(ip, scale);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.janelia.alignment.filter;

import ij.process.ImageProcessor;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* Applies a multiplicative correction (1 + exp(-a * (y - b))) to the y-direction of the given image data.
* <p>
* This filter is used to correct an exponential intensity drop towards the upper edge of the images in
* MultiSEM stacks.
*
* @author Michael Innerberger
*/
public class ExponentialIntensityFilter implements Filter {

private double a;
private double b;

// empty constructor required to create instances from specifications
@SuppressWarnings("unused")
public ExponentialIntensityFilter() {
this(0.0, 0.0);
}

public ExponentialIntensityFilter(final double a, final double b) {
this.a = a;
this.b = b;
}

@Override
public void init(final Map<String, String> params) {
this.a = Filter.getDoubleParameter("a", params);
this.b = Filter.getDoubleParameter("b", params);
}

@Override
public Map<String, String> toParametersMap() {
final Map<String, String> map = new LinkedHashMap<>();
map.put("a", String.valueOf(a));
map.put("b", String.valueOf(b));
return map;
}

@Override
public void process(final ImageProcessor ip, final double scale) {
// find midpoints of pixels in highest-resolution coordinate system
final int height = ip.getHeight();
final double[] y = new double[height];
for (int i = 0; i < height; i++) {
y[i] = (i + 0.5) / scale;
}

// apply correction
for (int j = 0; j < height; j++) {
final float correction = (float) (1.0 + Math.exp(-a * (y[j] - b)));
for (int i = 0; i < ip.getWidth(); i++) {
ip.setf(i, j, ip.getf(i, j) * correction);
}
}
}

}
Loading

0 comments on commit 7976e1b

Please sign in to comment.