mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
add ndimage package and several filters
This commit is contained in:
parent
a67293bf8e
commit
de84e40e48
@ -515,7 +515,7 @@ public class ImageUtil {
|
||||
return r;
|
||||
}
|
||||
|
||||
private static Array corrlated1D(Array a, double[] weights) {
|
||||
private static Array correlate1D(Array a, double[] weights) {
|
||||
int size = weights.length;
|
||||
int origin = size / 2;
|
||||
int n = (int)a.getSize();
|
||||
@ -597,7 +597,7 @@ public class ImageUtil {
|
||||
}
|
||||
}
|
||||
Array temp = data.section(ranges);
|
||||
temp = corrlated1D(temp, weights);
|
||||
temp = correlate1D(temp, weights);
|
||||
for (int j = 0; j < shape[axis]; j++) {
|
||||
rcurrent[axis] = j;
|
||||
rindex.set(rcurrent);
|
||||
|
||||
@ -0,0 +1,239 @@
|
||||
package org.meteoinfo.image.ndimage;
|
||||
|
||||
import org.meteoinfo.ndarray.*;
|
||||
import org.meteoinfo.ndarray.math.ListIndexComparator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Correlate1D {
|
||||
Array weights;
|
||||
ExtendMode mode;
|
||||
int axis = -1;
|
||||
double cValue = 0.0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param weights Weights
|
||||
* @param mode Extend mode
|
||||
*/
|
||||
public Correlate1D(Array weights, ExtendMode mode) {
|
||||
this.weights = weights.copyIfView();
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param weights Weights
|
||||
*/
|
||||
public Correlate1D(Array weights) {
|
||||
this(weights, ExtendMode.REFLECT);
|
||||
}
|
||||
|
||||
/***
|
||||
* Constructor
|
||||
*/
|
||||
public Correlate1D() {
|
||||
this(Array.factory(DataType.INT, new int[]{1,1,1}), ExtendMode.REFLECT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get weights
|
||||
* @return Weights
|
||||
*/
|
||||
public Array getWeights() {
|
||||
return this.weights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set weights
|
||||
* @param value Weights
|
||||
*/
|
||||
public void setWeights(Array value) {
|
||||
this.weights = value.copyIfView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extend mode
|
||||
* @return Extend mode
|
||||
*/
|
||||
public ExtendMode getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extend mode
|
||||
* @param value Extend mode
|
||||
*/
|
||||
public void setMode(ExtendMode value) {
|
||||
this.mode = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get axis
|
||||
* @return Axis
|
||||
*/
|
||||
public int getAxis() {
|
||||
return this.axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set axis
|
||||
* @param value Axis
|
||||
*/
|
||||
public void setAxis(int value) {
|
||||
this.axis = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constant value
|
||||
* @return Constant value
|
||||
*/
|
||||
public double getCValue() {
|
||||
return this.cValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set constant value
|
||||
* @param value Constant value
|
||||
*/
|
||||
public void setCValue(double value) {
|
||||
this.cValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate a 1-D correlation along the given axis.
|
||||
* The lines of the array along the given axis are correlated with the given weights.
|
||||
*
|
||||
* @param a The input array
|
||||
* @return Correlation result
|
||||
*/
|
||||
public Array correlate(Array a) throws InvalidRangeException {
|
||||
int size = (int) weights.getSize();
|
||||
int origin = size / 2;
|
||||
int n = (int) a.getSize();
|
||||
Array r = Array.factory(a.getDataType(), a.getShape());
|
||||
double v;
|
||||
int idx;
|
||||
if (a.getRank() == 1) {
|
||||
ArrayList<Double> dList = new ArrayList<>();
|
||||
IndexIterator iter = a.getIndexIterator();
|
||||
while (iter.hasNext()) {
|
||||
dList.add(iter.getDoubleNext());
|
||||
}
|
||||
ArrayList<Double> rList = correlate(dList);
|
||||
for (int i = 0; i < r.getSize(); i++) {
|
||||
r.setDouble(i, rList.get(i));
|
||||
}
|
||||
} else {
|
||||
Index index = a.getIndex();
|
||||
int[] shape = a.getShape();
|
||||
if (axis == -1) {
|
||||
axis = n - 1;
|
||||
}
|
||||
int nn = shape[axis];
|
||||
Index indexr = r.getIndex();
|
||||
int[] current;
|
||||
List<Range> ranges = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i == axis) {
|
||||
ranges.add(new Range(0, 0, 1));
|
||||
} else {
|
||||
ranges.add(new Range(0, shape[i] - 1, 1));
|
||||
}
|
||||
}
|
||||
IndexIterator rii = r.sectionNoReduce(ranges).getIndexIterator();
|
||||
while (rii.hasNext()) {
|
||||
rii.next();
|
||||
current = rii.getCurrentCounter();
|
||||
ranges = new ArrayList<>();
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (j == axis) {
|
||||
ranges.add(new Range(0, shape[j] - 1, 1));
|
||||
} else {
|
||||
ranges.add(new Range(current[j], current[j], 1));
|
||||
}
|
||||
}
|
||||
ArrayList<Double> stlist = new ArrayList();
|
||||
IndexIterator ii = a.getRangeIterator(ranges);
|
||||
while (ii.hasNext()) {
|
||||
v = ii.getDoubleNext();
|
||||
stlist.add(v);
|
||||
}
|
||||
ArrayList<Double> rList = correlate(stlist);
|
||||
for (int j = 0; j < nn; j++) {
|
||||
indexr.set(current);
|
||||
r.setObject(indexr, rList.get(j));
|
||||
current[axis] = current[axis] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private ArrayList<Double> correlate(ArrayList<Double> a) {
|
||||
int size = (int) weights.getSize();
|
||||
int origin = size / 2;
|
||||
int n = a.size();
|
||||
ArrayList<Double> r = new ArrayList<>();
|
||||
double v;
|
||||
int idx;
|
||||
for (int i = 0; i < n; i++) {
|
||||
v = 0;
|
||||
for (int j = 0; j < size; j++) {
|
||||
idx = i - origin + j;
|
||||
v += getValue(a, idx, origin) * weights.getDouble(j);
|
||||
}
|
||||
r.add(v);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private double getValue(List<Double> dList, int idx, int origin) {
|
||||
int n = dList.size();
|
||||
switch (this.mode) {
|
||||
case REFLECT:
|
||||
if (idx < 0) {
|
||||
idx = -idx - 1;
|
||||
} else if (idx > n - 1) {
|
||||
idx = n - (idx - (n - 1));
|
||||
}
|
||||
return dList.get(idx);
|
||||
case CONSTANT:
|
||||
if (idx < 0 || idx > n - 1) {
|
||||
return this.cValue;
|
||||
} else {
|
||||
return dList.get(idx);
|
||||
}
|
||||
case NEAREST:
|
||||
if (idx < 0) {
|
||||
idx = 0;
|
||||
} else if (idx > n - 1) {
|
||||
idx = n - 1;
|
||||
}
|
||||
return dList.get(idx);
|
||||
case MIRROR:
|
||||
if (idx < 0) {
|
||||
idx = -idx;
|
||||
} else if (idx > n - 1) {
|
||||
idx = n - 1 - (idx - (n - 1));
|
||||
}
|
||||
return dList.get(idx);
|
||||
case WRAP:
|
||||
if (idx < 0) {
|
||||
idx = idx + origin;
|
||||
} else if (idx > n - 1) {
|
||||
idx = idx - origin;
|
||||
}
|
||||
return dList.get(idx);
|
||||
}
|
||||
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package org.meteoinfo.image.ndimage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public enum ExtendMode {
|
||||
REFLECT,
|
||||
CONSTANT,
|
||||
NEAREST,
|
||||
MIRROR,
|
||||
WRAP;
|
||||
|
||||
/**
|
||||
* Get value
|
||||
* @param dList The data list
|
||||
* @param idx The index
|
||||
* @param origin Origin
|
||||
* @param mode Extend mode
|
||||
* @return The value
|
||||
*/
|
||||
public double getValue(List<Double> dList, int idx, int origin, double cValue) {
|
||||
int n = dList.size();
|
||||
switch (this) {
|
||||
case REFLECT:
|
||||
if (idx < 0) {
|
||||
idx = -idx - 1;
|
||||
} else if (idx > n - 1) {
|
||||
idx = n - (idx - (n - 1));
|
||||
}
|
||||
return dList.get(idx);
|
||||
case CONSTANT:
|
||||
if (idx < 0 || idx > n - 1) {
|
||||
return cValue;
|
||||
} else {
|
||||
return dList.get(idx);
|
||||
}
|
||||
case NEAREST:
|
||||
if (idx < 0) {
|
||||
idx = 0;
|
||||
} else if (idx > n - 1) {
|
||||
idx = n - 1;
|
||||
}
|
||||
return dList.get(idx);
|
||||
case MIRROR:
|
||||
if (idx < 0) {
|
||||
idx = -idx;
|
||||
} else if (idx > n - 1) {
|
||||
idx = n - 1 - (idx - (n - 1));
|
||||
}
|
||||
return dList.get(idx);
|
||||
case WRAP:
|
||||
if (idx < 0) {
|
||||
idx = idx + origin;
|
||||
} else if (idx > n - 1) {
|
||||
idx = idx - origin;
|
||||
}
|
||||
return dList.get(idx);
|
||||
}
|
||||
|
||||
return Double.NaN;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,142 @@
|
||||
package org.meteoinfo.image.ndimage;
|
||||
|
||||
import org.meteoinfo.ndarray.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GaussianFilter {
|
||||
int size = 3;
|
||||
double sigma;
|
||||
ExtendMode mode;
|
||||
double cValue = 0.0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param sigma Sigma
|
||||
* @param size Window size
|
||||
* @param mode Extend mode
|
||||
*/
|
||||
public GaussianFilter(double sigma, int size, ExtendMode mode) {
|
||||
this.sigma = sigma;
|
||||
this.size = size;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param sigma Sigma
|
||||
* @param size Window size
|
||||
*/
|
||||
public GaussianFilter(double sigma, int size) {
|
||||
this(sigma, size, ExtendMode.REFLECT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extend mode
|
||||
* @return Extend mode
|
||||
*/
|
||||
public ExtendMode getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extend mode
|
||||
* @param value Extend mode
|
||||
*/
|
||||
public void setMode(ExtendMode value) {
|
||||
this.mode = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constant value
|
||||
* @return Constant value
|
||||
*/
|
||||
public double getCValue() {
|
||||
return this.cValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set constant value
|
||||
* @param value Constant value
|
||||
*/
|
||||
public void setCValue(double value) {
|
||||
this.cValue = value;
|
||||
}
|
||||
|
||||
private double[] getWeights() {
|
||||
double[] weights = new double[size];
|
||||
double sum = 0;
|
||||
int origin = size / 2;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
//The first constant does not need to be calculated, which will be eliminated finally
|
||||
double g = Math.exp(-(i - origin) * (i - origin) / (2 * sigma * sigma));
|
||||
sum += g;
|
||||
weights[i] = g;
|
||||
}
|
||||
//Normalized
|
||||
for (int i = 0; i < size; i++) {
|
||||
weights[i] /= sum;
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter with Gaussian kernel
|
||||
* @param data Input data
|
||||
* @return Filtered data
|
||||
* @throws InvalidRangeException
|
||||
*/
|
||||
public Array filter(Array data) throws InvalidRangeException {
|
||||
double[] weights = getWeights();
|
||||
Array aWeights = Array.factory(DataType.DOUBLE, new int[]{weights.length}, weights);
|
||||
Correlate1D correlate1D = new Correlate1D(aWeights, mode);
|
||||
|
||||
int ndim = data.getRank();
|
||||
int[] shape = data.getShape();
|
||||
Array r = Array.factory(data.getDataType(), shape);
|
||||
Index rindex = r.getIndex();
|
||||
int[] rcurrent = new int[ndim];
|
||||
int idx;
|
||||
for (int axis = 0; axis < ndim; axis++) {
|
||||
int[] nshape = new int[ndim - 1];
|
||||
for (int i = 0; i < ndim; i++) {
|
||||
if (i < axis)
|
||||
nshape[i] = shape[i];
|
||||
else if (i > axis)
|
||||
nshape[i - 1] = shape[i];
|
||||
}
|
||||
Index index = Index.factory(nshape);
|
||||
int[] current;
|
||||
for (int i = 0; i < index.getSize(); i++) {
|
||||
current = index.getCurrentCounter();
|
||||
List<Range> ranges = new ArrayList<>();
|
||||
for (int j = 0; j < ndim; j++) {
|
||||
if (j == axis) {
|
||||
ranges.add(new Range(0, shape[j] - 1, 1));
|
||||
rcurrent[j] = 0;
|
||||
} else {
|
||||
idx = j;
|
||||
if (idx > axis) {
|
||||
idx -= 1;
|
||||
}
|
||||
ranges.add(new Range(current[idx], current[idx], 1));
|
||||
rcurrent[j] = current[idx];
|
||||
}
|
||||
}
|
||||
Array temp = data.section(ranges);
|
||||
temp = correlate1D.correlate(temp);
|
||||
for (int j = 0; j < shape[axis]; j++) {
|
||||
rcurrent[axis] = j;
|
||||
rindex.set(rcurrent);
|
||||
r.setDouble(rindex, temp.getDouble(j));
|
||||
}
|
||||
index.incr();
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,189 @@
|
||||
package org.meteoinfo.image.ndimage;
|
||||
|
||||
import org.meteoinfo.ndarray.*;
|
||||
import org.meteoinfo.ndarray.math.ArrayMath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MaximumFilter {
|
||||
int size = 3;
|
||||
ExtendMode mode;
|
||||
double cValue = 0.0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param size Window size
|
||||
* @param mode Extend model
|
||||
*/
|
||||
public MaximumFilter(int size, ExtendMode mode) {
|
||||
this.size = size;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extend mode
|
||||
* @return Extend mode
|
||||
*/
|
||||
public ExtendMode getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extend mode
|
||||
* @param value Extend mode
|
||||
*/
|
||||
public void setMode(ExtendMode value) {
|
||||
this.mode = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constant value
|
||||
* @return Constant value
|
||||
*/
|
||||
public double getCValue() {
|
||||
return this.cValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set constant value
|
||||
* @param value Constant value
|
||||
*/
|
||||
public void setCValue(double value) {
|
||||
this.cValue = value;
|
||||
}
|
||||
|
||||
private ArrayList<Double> maximum(ArrayList<Double> a) {
|
||||
int origin = size / 2;
|
||||
int n = a.size();
|
||||
ArrayList<Double> r = new ArrayList<>();
|
||||
double v;
|
||||
int idx;
|
||||
for (int i = 0; i < n; i++) {
|
||||
v = -Double.MAX_VALUE;
|
||||
for (int j = 0; j < size; j++) {
|
||||
idx = i - origin + j;
|
||||
v = Math.max(mode.getValue(a, idx, origin, cValue), v);
|
||||
}
|
||||
r.add(v);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private Array maximum(Array a, int axis) throws InvalidRangeException {
|
||||
int origin = size / 2;
|
||||
int n = (int) a.getSize();
|
||||
Array r = Array.factory(a.getDataType(), a.getShape());
|
||||
double v;
|
||||
int idx;
|
||||
if (a.getRank() == 1) {
|
||||
ArrayList<Double> dList = new ArrayList<>();
|
||||
IndexIterator iter = a.getIndexIterator();
|
||||
while (iter.hasNext()) {
|
||||
dList.add(iter.getDoubleNext());
|
||||
}
|
||||
ArrayList<Double> rList = maximum(dList);
|
||||
for (int i = 0; i < r.getSize(); i++) {
|
||||
r.setDouble(i, rList.get(i));
|
||||
}
|
||||
} else {
|
||||
Index index = a.getIndex();
|
||||
int[] shape = a.getShape();
|
||||
if (axis == -1) {
|
||||
axis = n - 1;
|
||||
}
|
||||
int nn = shape[axis];
|
||||
Index indexr = r.getIndex();
|
||||
int[] current;
|
||||
List<Range> ranges = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i == axis) {
|
||||
ranges.add(new Range(0, 0, 1));
|
||||
} else {
|
||||
ranges.add(new Range(0, shape[i] - 1, 1));
|
||||
}
|
||||
}
|
||||
IndexIterator rii = r.sectionNoReduce(ranges).getIndexIterator();
|
||||
while (rii.hasNext()) {
|
||||
rii.next();
|
||||
current = rii.getCurrentCounter();
|
||||
ranges = new ArrayList<>();
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (j == axis) {
|
||||
ranges.add(new Range(0, shape[j] - 1, 1));
|
||||
} else {
|
||||
ranges.add(new Range(current[j], current[j], 1));
|
||||
}
|
||||
}
|
||||
ArrayList<Double> stlist = new ArrayList();
|
||||
IndexIterator ii = a.getRangeIterator(ranges);
|
||||
while (ii.hasNext()) {
|
||||
v = ii.getDoubleNext();
|
||||
stlist.add(v);
|
||||
}
|
||||
ArrayList<Double> rList = maximum(stlist);
|
||||
for (int j = 0; j < nn; j++) {
|
||||
indexr.set(current);
|
||||
r.setObject(indexr, rList.get(j));
|
||||
current[axis] = current[axis] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum filter
|
||||
* @param data Input data
|
||||
* @return Filtered data
|
||||
* @throws InvalidRangeException
|
||||
*/
|
||||
public Array filter(Array data) throws InvalidRangeException {
|
||||
int ndim = data.getRank();
|
||||
int[] shape = data.getShape();
|
||||
Array r = Array.factory(data.getDataType(), shape);
|
||||
Index rindex = r.getIndex();
|
||||
int[] rcurrent = new int[ndim];
|
||||
int idx;
|
||||
for (int axis = 0; axis < ndim; axis++) {
|
||||
int[] nshape = new int[ndim - 1];
|
||||
for (int i = 0; i < ndim; i++) {
|
||||
if (i < axis)
|
||||
nshape[i] = shape[i];
|
||||
else if (i > axis)
|
||||
nshape[i - 1] = shape[i];
|
||||
}
|
||||
Index index = Index.factory(nshape);
|
||||
int[] current;
|
||||
for (int i = 0; i < index.getSize(); i++) {
|
||||
current = index.getCurrentCounter();
|
||||
List<Range> ranges = new ArrayList<>();
|
||||
for (int j = 0; j < ndim; j++) {
|
||||
if (j == axis) {
|
||||
ranges.add(new Range(0, shape[j] - 1, 1));
|
||||
rcurrent[j] = 0;
|
||||
} else {
|
||||
idx = j;
|
||||
if (idx > axis) {
|
||||
idx -= 1;
|
||||
}
|
||||
ranges.add(new Range(current[idx], current[idx], 1));
|
||||
rcurrent[j] = current[idx];
|
||||
}
|
||||
}
|
||||
Array temp = data.section(ranges);
|
||||
temp = maximum(temp, axis);
|
||||
for (int j = 0; j < shape[axis]; j++) {
|
||||
rcurrent[axis] = j;
|
||||
rindex.set(rcurrent);
|
||||
r.setDouble(rindex, temp.getDouble(j));
|
||||
}
|
||||
index.incr();
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,189 @@
|
||||
package org.meteoinfo.image.ndimage;
|
||||
|
||||
import org.meteoinfo.ndarray.*;
|
||||
import org.meteoinfo.ndarray.math.ArrayMath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MinimumFilter {
|
||||
int size = 3;
|
||||
ExtendMode mode;
|
||||
double cValue = 0.0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param size Window size
|
||||
* @param mode Extend mode
|
||||
*/
|
||||
public MinimumFilter(int size, ExtendMode mode) {
|
||||
this.size = size;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extend mode
|
||||
* @return Extend mode
|
||||
*/
|
||||
public ExtendMode getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extend mode
|
||||
* @param value Extend mode
|
||||
*/
|
||||
public void setMode(ExtendMode value) {
|
||||
this.mode = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constant value
|
||||
* @return Constant value
|
||||
*/
|
||||
public double getCValue() {
|
||||
return this.cValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set constant value
|
||||
* @param value Constant value
|
||||
*/
|
||||
public void setCValue(double value) {
|
||||
this.cValue = value;
|
||||
}
|
||||
|
||||
private ArrayList<Double> minimum(ArrayList<Double> a) {
|
||||
int origin = size / 2;
|
||||
int n = a.size();
|
||||
ArrayList<Double> r = new ArrayList<>();
|
||||
double v;
|
||||
int idx;
|
||||
for (int i = 0; i < n; i++) {
|
||||
v = Double.MAX_VALUE;
|
||||
for (int j = 0; j < size; j++) {
|
||||
idx = i - origin + j;
|
||||
v = Math.min(mode.getValue(a, idx, origin, cValue), v);
|
||||
}
|
||||
r.add(v);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private Array minimum(Array a, int axis) throws InvalidRangeException {
|
||||
int origin = size / 2;
|
||||
int n = (int) a.getSize();
|
||||
Array r = Array.factory(a.getDataType(), a.getShape());
|
||||
double v;
|
||||
int idx;
|
||||
if (a.getRank() == 1) {
|
||||
ArrayList<Double> dList = new ArrayList<>();
|
||||
IndexIterator iter = a.getIndexIterator();
|
||||
while (iter.hasNext()) {
|
||||
dList.add(iter.getDoubleNext());
|
||||
}
|
||||
ArrayList<Double> rList = minimum(dList);
|
||||
for (int i = 0; i < r.getSize(); i++) {
|
||||
r.setDouble(i, rList.get(i));
|
||||
}
|
||||
} else {
|
||||
Index index = a.getIndex();
|
||||
int[] shape = a.getShape();
|
||||
if (axis == -1) {
|
||||
axis = n - 1;
|
||||
}
|
||||
int nn = shape[axis];
|
||||
Index indexr = r.getIndex();
|
||||
int[] current;
|
||||
List<Range> ranges = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i == axis) {
|
||||
ranges.add(new Range(0, 0, 1));
|
||||
} else {
|
||||
ranges.add(new Range(0, shape[i] - 1, 1));
|
||||
}
|
||||
}
|
||||
IndexIterator rii = r.sectionNoReduce(ranges).getIndexIterator();
|
||||
while (rii.hasNext()) {
|
||||
rii.next();
|
||||
current = rii.getCurrentCounter();
|
||||
ranges = new ArrayList<>();
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (j == axis) {
|
||||
ranges.add(new Range(0, shape[j] - 1, 1));
|
||||
} else {
|
||||
ranges.add(new Range(current[j], current[j], 1));
|
||||
}
|
||||
}
|
||||
ArrayList<Double> stlist = new ArrayList();
|
||||
IndexIterator ii = a.getRangeIterator(ranges);
|
||||
while (ii.hasNext()) {
|
||||
v = ii.getDoubleNext();
|
||||
stlist.add(v);
|
||||
}
|
||||
ArrayList<Double> rList = minimum(stlist);
|
||||
for (int j = 0; j < nn; j++) {
|
||||
indexr.set(current);
|
||||
r.setObject(indexr, rList.get(j));
|
||||
current[axis] = current[axis] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum filter
|
||||
* @param data Input data
|
||||
* @return Filtered data
|
||||
* @throws InvalidRangeException
|
||||
*/
|
||||
public Array filter(Array data) throws InvalidRangeException {
|
||||
int ndim = data.getRank();
|
||||
int[] shape = data.getShape();
|
||||
Array r = Array.factory(data.getDataType(), shape);
|
||||
Index rindex = r.getIndex();
|
||||
int[] rcurrent = new int[ndim];
|
||||
int idx;
|
||||
for (int axis = 0; axis < ndim; axis++) {
|
||||
int[] nshape = new int[ndim - 1];
|
||||
for (int i = 0; i < ndim; i++) {
|
||||
if (i < axis)
|
||||
nshape[i] = shape[i];
|
||||
else if (i > axis)
|
||||
nshape[i - 1] = shape[i];
|
||||
}
|
||||
Index index = Index.factory(nshape);
|
||||
int[] current;
|
||||
for (int i = 0; i < index.getSize(); i++) {
|
||||
current = index.getCurrentCounter();
|
||||
List<Range> ranges = new ArrayList<>();
|
||||
for (int j = 0; j < ndim; j++) {
|
||||
if (j == axis) {
|
||||
ranges.add(new Range(0, shape[j] - 1, 1));
|
||||
rcurrent[j] = 0;
|
||||
} else {
|
||||
idx = j;
|
||||
if (idx > axis) {
|
||||
idx -= 1;
|
||||
}
|
||||
ranges.add(new Range(current[idx], current[idx], 1));
|
||||
rcurrent[j] = current[idx];
|
||||
}
|
||||
}
|
||||
Array temp = data.section(ranges);
|
||||
temp = minimum(temp, axis);
|
||||
for (int j = 0; j < shape[axis]; j++) {
|
||||
rcurrent[axis] = j;
|
||||
rindex.set(rcurrent);
|
||||
r.setDouble(rindex, temp.getDouble(j));
|
||||
}
|
||||
index.incr();
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
package org.meteoinfo.image.ndimage;
|
||||
|
||||
import org.meteoinfo.ndarray.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class UniformFilter {
|
||||
int size = 3;
|
||||
ExtendMode mode;
|
||||
double cValue = 0.0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param size Window size
|
||||
* @param mode Extend mode
|
||||
*/
|
||||
public UniformFilter(int size, ExtendMode mode) {
|
||||
this.size = size;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param size Window size
|
||||
*/
|
||||
public UniformFilter(int size) {
|
||||
this(size, ExtendMode.REFLECT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extend mode
|
||||
* @return Extend mode
|
||||
*/
|
||||
public ExtendMode getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extend mode
|
||||
* @param value Extend mode
|
||||
*/
|
||||
public void setMode(ExtendMode value) {
|
||||
this.mode = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constant value
|
||||
* @return Constant value
|
||||
*/
|
||||
public double getCValue() {
|
||||
return this.cValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set constant value
|
||||
* @param value Constant value
|
||||
*/
|
||||
public void setCValue(double value) {
|
||||
this.cValue = value;
|
||||
}
|
||||
|
||||
private double[] getWeights() {
|
||||
double[] weights = new double[size];
|
||||
double sum = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
double g = 1.0;
|
||||
sum += g;
|
||||
weights[i] = g;
|
||||
}
|
||||
//Normalized
|
||||
for (int i = 0; i < size; i++) {
|
||||
weights[i] /= sum;
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter with Gaussian kernel
|
||||
* @param data Input data
|
||||
* @return Filtered data
|
||||
* @throws InvalidRangeException
|
||||
*/
|
||||
public Array filter(Array data) throws InvalidRangeException {
|
||||
double[] weights = getWeights();
|
||||
Array aWeights = Array.factory(DataType.DOUBLE, new int[]{weights.length}, weights);
|
||||
Correlate1D correlate1D = new Correlate1D(aWeights, mode);
|
||||
|
||||
int ndim = data.getRank();
|
||||
int[] shape = data.getShape();
|
||||
Array r = Array.factory(data.getDataType(), shape);
|
||||
Index rindex = r.getIndex();
|
||||
int[] rcurrent = new int[ndim];
|
||||
int idx;
|
||||
for (int axis = 0; axis < ndim; axis++) {
|
||||
int[] nshape = new int[ndim - 1];
|
||||
for (int i = 0; i < ndim; i++) {
|
||||
if (i < axis)
|
||||
nshape[i] = shape[i];
|
||||
else if (i > axis)
|
||||
nshape[i - 1] = shape[i];
|
||||
}
|
||||
Index index = Index.factory(nshape);
|
||||
int[] current;
|
||||
for (int i = 0; i < index.getSize(); i++) {
|
||||
current = index.getCurrentCounter();
|
||||
List<Range> ranges = new ArrayList<>();
|
||||
for (int j = 0; j < ndim; j++) {
|
||||
if (j == axis) {
|
||||
ranges.add(new Range(0, shape[j] - 1, 1));
|
||||
rcurrent[j] = 0;
|
||||
} else {
|
||||
idx = j;
|
||||
if (idx > axis) {
|
||||
idx -= 1;
|
||||
}
|
||||
ranges.add(new Range(current[idx], current[idx], 1));
|
||||
rcurrent[j] = current[idx];
|
||||
}
|
||||
}
|
||||
Array temp = data.section(ranges);
|
||||
temp = correlate1D.correlate(temp);
|
||||
for (int j = 0; j < shape[axis]; j++) {
|
||||
rcurrent[axis] = j;
|
||||
rindex.set(rcurrent);
|
||||
r.setDouble(rindex, temp.getDouble(j));
|
||||
}
|
||||
index.incr();
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\micaps">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\json"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\webmap"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\common_math\ndimage">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\wind"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\grib"/>
|
||||
@ -13,20 +10,25 @@
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\burf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\ascat"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\micaps"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\image"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\ndimage"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\zarr\icon_2.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\satellite\ascat\ascat_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\micaps\micaps_4_11.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\ndimage\minimum_filter_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\ndimage\uniform_filter_1.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\zarr\icon_2.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\satellite\ascat\ascat_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\micaps\micaps_4_11.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\ndimage\minimum_filter_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\ndimage\uniform_filter_1.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
|
||||
Binary file not shown.
@ -15,9 +15,10 @@ from . import spatial
|
||||
from . import special
|
||||
from . import integrate
|
||||
from . import fft
|
||||
from . import ndimage
|
||||
|
||||
__all__ = ['linalg', 'fitting', 'random', 'ma', 'stats', 'interpolate', 'optimize', 'signal', 'spatial',
|
||||
'special', 'integrate', 'fft']
|
||||
'special', 'integrate', 'fft', 'ndimage']
|
||||
__all__.extend(['__version__'])
|
||||
__all__.extend(core.__all__)
|
||||
__all__.extend(lib.__all__)
|
||||
|
||||
4
meteoinfo-lab/pylib/mipylib/numeric/ndimage/__init__.py
Normal file
4
meteoinfo-lab/pylib/mipylib/numeric/ndimage/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
from ._filters import *
|
||||
|
||||
__all__ = []
|
||||
__all__ += _filters.__all__
|
||||
277
meteoinfo-lab/pylib/mipylib/numeric/ndimage/_filters.py
Normal file
277
meteoinfo-lab/pylib/mipylib/numeric/ndimage/_filters.py
Normal file
@ -0,0 +1,277 @@
|
||||
# coding=utf-8
|
||||
|
||||
from org.meteoinfo.image.ndimage import Correlate1D, ExtendMode, GaussianFilter, \
|
||||
UniformFilter, MaximumFilter, MinimumFilter
|
||||
|
||||
from ..core import numeric as np
|
||||
|
||||
|
||||
__all__ = ['correlate1d', 'gaussian_filter', 'uniform_filter', 'maximum_filter',
|
||||
'minimum_filter']
|
||||
|
||||
|
||||
def correlate1d(input, weights, axis=-1, mode='reflect', cval=0.0):
|
||||
"""
|
||||
Calculate a 1-D correlation along the given axis.
|
||||
|
||||
The lines of the array along the given axis are correlated with the
|
||||
given weights.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
input : array
|
||||
The input array.
|
||||
weights : array
|
||||
1-D sequence of numbers.
|
||||
axis : int
|
||||
The axis of input along which to calculate. Default is -1.
|
||||
mode : {‘reflect’, ‘constant’, ‘nearest’, ‘mirror’, ‘wrap’}, optional
|
||||
The mode parameter determines how the input array is extended beyond its boundaries.
|
||||
Default is ‘reflect’. Behavior for each valid value is as follows:
|
||||
‘reflect’ (d c b a | a b c d | d c b a)
|
||||
The input is extended by reflecting about the edge of the last pixel. This mode is
|
||||
also sometimes referred to as half-sample symmetric.
|
||||
‘constant’ (k k k k | a b c d | k k k k)
|
||||
The input is extended by filling all values beyond the edge with the same constant
|
||||
value, defined by the cval parameter.
|
||||
‘nearest’ (a a a a | a b c d | d d d d)
|
||||
The input is extended by replicating the last pixel.
|
||||
‘mirror’ (d c b | a b c d | c b a)
|
||||
The input is extended by reflecting about the center of the last pixel. This mode
|
||||
is also sometimes referred to as whole-sample symmetric.
|
||||
‘wrap’ (a b c d | a b c d | a b c d)
|
||||
The input is extended by wrapping around to the opposite edge.
|
||||
cval : scalar, optional
|
||||
Value to fill past edges of input if mode is ‘constant’. Default is 0.0.
|
||||
|
||||
Returns
|
||||
-------
|
||||
result : array
|
||||
Correlation result. Has the same shape as `input`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from np.ndimage import correlate1d
|
||||
>>> correlate1d([2, 8, 0, 4, 1, 9, 9, 0], weights=[1, 3])
|
||||
array([ 8, 26, 8, 12, 7, 28, 36, 9])
|
||||
"""
|
||||
input = np.asarray(input)
|
||||
weights = np.asarray(weights)
|
||||
mode = ExtendMode.valueOf(mode.upper())
|
||||
jc1d = Correlate1D(weights._array, mode)
|
||||
jc1d.setAxis(axis)
|
||||
jc1d.setCValue(cval)
|
||||
r = jc1d.correlate(input._array)
|
||||
|
||||
return np.array(r)
|
||||
|
||||
|
||||
def gaussian_filter(input, sigma, order=0, mode='reflect', cval=0.0, radius=1):
|
||||
"""
|
||||
Multidimensional Gaussian filter.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
input : array
|
||||
The input array
|
||||
sigma : scalar or sequence of scalars
|
||||
Standard deviation for Gaussian kernel. The standard
|
||||
deviations of the Gaussian filter are given for each axis as a
|
||||
sequence, or as a single number, in which case it is equal for
|
||||
all axes.
|
||||
order : int or sequence of ints, optional
|
||||
The order of the filter along each axis is given as a sequence
|
||||
of integers, or as a single number. An order of 0 corresponds
|
||||
to convolution with a Gaussian kernel. A positive order
|
||||
corresponds to convolution with that derivative of a Gaussian.
|
||||
mode : {‘reflect’, ‘constant’, ‘nearest’, ‘mirror’, ‘wrap’}, optional
|
||||
The mode parameter determines how the input array is extended beyond its boundaries.
|
||||
Default is ‘reflect’. Behavior for each valid value is as follows:
|
||||
‘reflect’ (d c b a | a b c d | d c b a)
|
||||
The input is extended by reflecting about the edge of the last pixel. This mode is
|
||||
also sometimes referred to as half-sample symmetric.
|
||||
‘constant’ (k k k k | a b c d | k k k k)
|
||||
The input is extended by filling all values beyond the edge with the same constant
|
||||
value, defined by the cval parameter.
|
||||
‘nearest’ (a a a a | a b c d | d d d d)
|
||||
The input is extended by replicating the last pixel.
|
||||
‘mirror’ (d c b | a b c d | c b a)
|
||||
The input is extended by reflecting about the center of the last pixel. This mode
|
||||
is also sometimes referred to as whole-sample symmetric.
|
||||
‘wrap’ (a b c d | a b c d | a b c d)
|
||||
The input is extended by wrapping around to the opposite edge.
|
||||
cval : scalar, optional
|
||||
Value to fill past edges of input if mode is ‘constant’. Default is 0.0.
|
||||
radius : None or int or sequence of ints, optional
|
||||
Radius of the Gaussian kernel. The radius is given for each axis
|
||||
as a sequence, or as a single number, in which case it is equal
|
||||
for all axes. If specified, the size of the kernel along each axis
|
||||
will be ``2*radius + 1``, and `truncate` is ignored.
|
||||
Default is 1.
|
||||
|
||||
Returns
|
||||
-------
|
||||
gaussian_filter : array
|
||||
Returned array of same shape as `input`.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The multidimensional filter is implemented as a sequence of
|
||||
1-D convolution filters. The intermediate arrays are
|
||||
stored in the same data type as the output. Therefore, for output
|
||||
types with a limited precision, the results may be imprecise
|
||||
because intermediate results may be stored with insufficient
|
||||
precision.
|
||||
|
||||
The Gaussian kernel will have size ``2*radius + 1`` along each axis. If
|
||||
`radius` is None, the default ``radius = round(truncate * sigma)`` will be
|
||||
used.
|
||||
"""
|
||||
input = np.asarray(input)
|
||||
mode = ExtendMode.valueOf(mode.upper())
|
||||
size = 2 * radius + 1
|
||||
g_filter = GaussianFilter(sigma, size, mode)
|
||||
g_filter.setCValue(cval)
|
||||
r = g_filter.filter(input._array)
|
||||
|
||||
return np.array(r)
|
||||
|
||||
|
||||
def uniform_filter(input, size=3, mode='reflect', cval=0.0):
|
||||
"""
|
||||
Multidimensional uniform filter.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
input : array
|
||||
The input array
|
||||
size : int or sequence of ints, optional
|
||||
The sizes of the uniform filter are given for each axis as a sequence, or as a single
|
||||
number, in which case the size is equal for all axes.
|
||||
mode : {‘reflect’, ‘constant’, ‘nearest’, ‘mirror’, ‘wrap’}, optional
|
||||
The mode parameter determines how the input array is extended beyond its boundaries.
|
||||
Default is ‘reflect’. Behavior for each valid value is as follows:
|
||||
‘reflect’ (d c b a | a b c d | d c b a)
|
||||
The input is extended by reflecting about the edge of the last pixel. This mode is
|
||||
also sometimes referred to as half-sample symmetric.
|
||||
‘constant’ (k k k k | a b c d | k k k k)
|
||||
The input is extended by filling all values beyond the edge with the same constant
|
||||
value, defined by the cval parameter.
|
||||
‘nearest’ (a a a a | a b c d | d d d d)
|
||||
The input is extended by replicating the last pixel.
|
||||
‘mirror’ (d c b | a b c d | c b a)
|
||||
The input is extended by reflecting about the center of the last pixel. This mode
|
||||
is also sometimes referred to as whole-sample symmetric.
|
||||
‘wrap’ (a b c d | a b c d | a b c d)
|
||||
The input is extended by wrapping around to the opposite edge.
|
||||
cval : scalar, optional
|
||||
Value to fill past edges of input if mode is ‘constant’. Default is 0.0.
|
||||
|
||||
Returns
|
||||
-------
|
||||
uniform_filter : array
|
||||
Returned array of same shape as `input`.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The multidimensional filter is implemented as a sequence of
|
||||
1-D uniform filters. The intermediate arrays are stored
|
||||
in the same data type as the output. Therefore, for output types
|
||||
with a limited precision, the results may be imprecise because
|
||||
intermediate results may be stored with insufficient precision.
|
||||
"""
|
||||
input = np.asarray(input)
|
||||
mode = ExtendMode.valueOf(mode.upper())
|
||||
u_filter = UniformFilter(size, mode)
|
||||
u_filter.setCValue(cval)
|
||||
r = u_filter.filter(input._array)
|
||||
|
||||
return np.array(r)
|
||||
|
||||
|
||||
def minimum_filter(input, size=3, mode='reflect', cval=0.0):
|
||||
"""
|
||||
Multidimensional minimum filter.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
input : array
|
||||
The input array
|
||||
size : int or sequence of ints, optional
|
||||
The sizes of the uniform filter are given for each axis as a sequence, or as a single
|
||||
number, in which case the size is equal for all axes.
|
||||
mode : {‘reflect’, ‘constant’, ‘nearest’, ‘mirror’, ‘wrap’}, optional
|
||||
The mode parameter determines how the input array is extended beyond its boundaries.
|
||||
Default is ‘reflect’. Behavior for each valid value is as follows:
|
||||
‘reflect’ (d c b a | a b c d | d c b a)
|
||||
The input is extended by reflecting about the edge of the last pixel. This mode is
|
||||
also sometimes referred to as half-sample symmetric.
|
||||
‘constant’ (k k k k | a b c d | k k k k)
|
||||
The input is extended by filling all values beyond the edge with the same constant
|
||||
value, defined by the cval parameter.
|
||||
‘nearest’ (a a a a | a b c d | d d d d)
|
||||
The input is extended by replicating the last pixel.
|
||||
‘mirror’ (d c b | a b c d | c b a)
|
||||
The input is extended by reflecting about the center of the last pixel. This mode
|
||||
is also sometimes referred to as whole-sample symmetric.
|
||||
‘wrap’ (a b c d | a b c d | a b c d)
|
||||
The input is extended by wrapping around to the opposite edge.
|
||||
cval : scalar, optional
|
||||
Value to fill past edges of input if mode is ‘constant’. Default is 0.0.
|
||||
|
||||
Returns
|
||||
-------
|
||||
minimum_filter : array
|
||||
Returned array of same shape as `input`.
|
||||
"""
|
||||
input = np.asarray(input)
|
||||
mode = ExtendMode.valueOf(mode.upper())
|
||||
u_filter = MinimumFilter(size, mode)
|
||||
u_filter.setCValue(cval)
|
||||
r = u_filter.filter(input._array)
|
||||
|
||||
return np.array(r)
|
||||
|
||||
|
||||
def maximum_filter(input, size=3, mode='reflect', cval=0.0):
|
||||
"""
|
||||
Multidimensional maximum filter.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
input : array
|
||||
The input array
|
||||
size : int or sequence of ints, optional
|
||||
The sizes of the uniform filter are given for each axis as a sequence, or as a single
|
||||
number, in which case the size is equal for all axes.
|
||||
mode : {‘reflect’, ‘constant’, ‘nearest’, ‘mirror’, ‘wrap’}, optional
|
||||
The mode parameter determines how the input array is extended beyond its boundaries.
|
||||
Default is ‘reflect’. Behavior for each valid value is as follows:
|
||||
‘reflect’ (d c b a | a b c d | d c b a)
|
||||
The input is extended by reflecting about the edge of the last pixel. This mode is
|
||||
also sometimes referred to as half-sample symmetric.
|
||||
‘constant’ (k k k k | a b c d | k k k k)
|
||||
The input is extended by filling all values beyond the edge with the same constant
|
||||
value, defined by the cval parameter.
|
||||
‘nearest’ (a a a a | a b c d | d d d d)
|
||||
The input is extended by replicating the last pixel.
|
||||
‘mirror’ (d c b | a b c d | c b a)
|
||||
The input is extended by reflecting about the center of the last pixel. This mode
|
||||
is also sometimes referred to as whole-sample symmetric.
|
||||
‘wrap’ (a b c d | a b c d | a b c d)
|
||||
The input is extended by wrapping around to the opposite edge.
|
||||
cval : scalar, optional
|
||||
Value to fill past edges of input if mode is ‘constant’. Default is 0.0.
|
||||
|
||||
Returns
|
||||
-------
|
||||
maximum_filter : array
|
||||
Returned array of same shape as `input`.
|
||||
"""
|
||||
input = np.asarray(input)
|
||||
mode = ExtendMode.valueOf(mode.upper())
|
||||
u_filter = MaximumFilter(size, mode)
|
||||
u_filter.setCValue(cval)
|
||||
r = u_filter.filter(input._array)
|
||||
|
||||
return np.array(r)
|
||||
Loading…
x
Reference in New Issue
Block a user