Warning: session_start(): open(/var/lib/php/sessions/sess_6dmivstpt6f7ua4f7vrd4hbd5k, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
!include once #1010056 // OpenIMAJ
import org.openimaj.image.Image;
import org.openimaj.image.processor.*;
import static org.openimaj.image.processor.SinglebandImageProcessor.Processable;
replace Rectangle with RectangleO.
abstract sclass SingleBandImage, I extends SingleBandImage> extends Image implements Processable, org.openimaj.image.processor.SinglebandKernelProcessor.Processable {
private static final long serialVersionUID = 1L;
public int height;
public int width;
public SingleBandImage() {
}
public int getHeight() {
return this.height;
}
public int getWidth() {
return this.width;
}
public I process(KernelProcessor p) {
return this.process(p, false);
}
public I process(KernelProcessor p, boolean pad) {
I newImage = (I) this.newInstance(this.width, this.height);
I tmp = (I) this.newInstance(p.getKernelWidth(), p.getKernelHeight());
int hh = p.getKernelHeight() / 2;
int hw = p.getKernelWidth() / 2;
int y;
int x;
if (!pad) {
for(y = hh; y < this.getHeight() - (p.getKernelHeight() - hh); ++y) {
for(x = hw; x < this.getWidth() - (p.getKernelWidth() - hw); ++x) {
newImage.setPixel(x, y, p.processKernel(this.extractROI(x, y, tmp)));
}
}
} else {
for(y = 0; y < this.getHeight(); ++y) {
for(x = 0; x < this.getWidth(); ++x) {
newImage.setPixel(x, y, p.processKernel(this.extractROI(x, y, tmp)));
}
}
}
return newImage;
}
public I process(SinglebandKernelProcessor p) {
return this.process(p, false);
}
public I process(SinglebandKernelProcessor p, boolean pad) {
I newImage = (SingleBandImage)this.newInstance(this.width, this.height);
I tmp = (SingleBandImage)this.newInstance(p.getKernelWidth(), p.getKernelHeight());
int hh = p.getKernelHeight() / 2;
int hw = p.getKernelWidth() / 2;
int y;
int x;
if (!pad) {
for(y = hh; y < this.getHeight() - (p.getKernelHeight() - hh); ++y) {
for(x = hw; x < this.getWidth() - (p.getKernelWidth() - hw); ++x) {
newImage.setPixel(x, y, p.processKernel(this.extractROI(x, y, tmp)));
}
}
} else {
for(y = 0; y < this.getHeight(); ++y) {
for(x = 0; x < this.getWidth(); ++x) {
newImage.setPixel(x, y, p.processKernel(this.extractROI(x, y, tmp)));
}
}
}
return newImage;
}
public I processInplace(SinglebandKernelProcessor p) {
return this.processInplace(p, false);
}
public I processInplace(SinglebandKernelProcessor p, boolean pad) {
I newImage = this.process(p, pad);
this.internalAssign(newImage);
return this;
}
public I process(SinglebandImageProcessor p) {
I newImage = this.clone();
newImage.processInplace(p);
return newImage;
}
public I processInplace(SinglebandImageProcessor p) {
p.processImage(this);
return this;
}
public I fill(Q colour) {
for(int y = 0; y < this.getHeight(); ++y) {
for(int x = 0; x < this.getWidth(); ++x) {
this.setPixel(x, y, colour);
}
}
return this;
}
public abstract I clone();
public boolean equals(Object obj) {
I that = (SingleBandImage)obj;
for(int y = 0; y < this.getHeight(); ++y) {
for(int x = 0; x < this.getWidth(); ++x) {
boolean fail = !((Comparable)this.getPixel(x, y)).equals(that.getPixel(x, y));
if (fail) {
return false;
}
}
}
return true;
}
}
sclass FImage extends SingleBandImage {
private static final long serialVersionUID = 1L;
protected static Logger logger = Logger.getLogger(FImage.class);
protected static final float DEFAULT_GAUSS_TRUNCATE = 4.0F;
public float[][] pixels;
public FImage(float[] array, int width, int height) {
assert array.length == width * height;
this.pixels = new float[height][width];
this.height = height;
this.width = width;
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
this.pixels[y][x] = array[y * width + x];
}
}
}
public FImage(double[] array, int width, int height) {
assert array.length == width * height;
this.pixels = new float[height][width];
this.height = height;
this.width = width;
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
this.pixels[y][x] = (float)array[y * width + x];
}
}
}
public FImage(double[] array, int width, int height, int offset) {
assert array.length == width * height;
this.pixels = new float[height][width];
this.height = height;
this.width = width;
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
this.pixels[y][x] = (float)array[offset + y * width + x];
}
}
}
public FImage(float[][] array) {
this.pixels = array;
this.height = array.length;
this.width = array[0].length;
}
public FImage(int width, int height) {
this.pixels = new float[height][width];
this.height = height;
this.width = width;
}
public FImage(int[] data, int width, int height) {
this.internalAssign(data, width, height);
}
public FImage(int[] data, int width, int height, ARGBPlane plane) {
this.width = width;
this.height = height;
this.pixels = new float[height][width];
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
int rgb = data[x + y * width];
int colour = 0;
switch(plane) {
case RED:
colour = rgb >> 16 & 255;
break;
case GREEN:
colour = rgb >> 8 & 255;
break;
case BLUE:
colour = rgb & 255;
}
this.pixels[y][x] = (float)colour;
}
}
}
public FImage abs() {
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] = Math.abs(this.pixels[r][c]);
}
}
return this;
}
public FImage add(FImage im) {
if (!ImageUtilities.checkSameSize(new Image[]{this, im})) {
throw new AssertionError("images must be the same size");
} else {
FImage newImage = new FImage(im.width, im.height);
for(int r = 0; r < im.height; ++r) {
for(int c = 0; c < im.width; ++c) {
newImage.pixels[r][c] = this.pixels[r][c] + im.pixels[r][c];
}
}
return newImage;
}
}
public FImage add(Float num) {
FImage newImage = new FImage(this.width, this.height);
float fnum = num;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
newImage.pixels[r][c] = this.pixels[r][c] + fnum;
}
}
return newImage;
}
public FImage add(Image, ?> im) {
if (im instanceof FImage) {
return this.add((FImage)im);
} else {
throw new UnsupportedOperationException("Unsupported Type");
}
}
public FImage addInplace(FImage im) {
if (!ImageUtilities.checkSameSize(new Image[]{this, im})) {
throw new AssertionError("images must be the same size");
} else {
for(int r = 0; r < im.height; ++r) {
for(int c = 0; c < im.width; ++c) {
this.pixels[r][c] += im.pixels[r][c];
}
}
return this;
}
}
public FImage addInplace(Float num) {
float fnum = num;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] += fnum;
}
}
return this;
}
public FImage addInplace(Image, ?> im) {
if (im instanceof FImage) {
return this.addInplace((FImage)im);
} else {
throw new UnsupportedOperationException("Unsupported Type");
}
}
public FImage clip(Float min, Float max) {
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
if (this.pixels[r][c] < min) {
this.pixels[r][c] = 0.0F;
}
if (this.pixels[r][c] > max) {
this.pixels[r][c] = 1.0F;
}
}
}
return this;
}
public FImage clipMax(Float thresh) {
float fthresh = thresh;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
if (this.pixels[r][c] > fthresh) {
this.pixels[r][c] = 1.0F;
}
}
}
return this;
}
public FImage clipMin(Float thresh) {
float fthresh = thresh;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
if (this.pixels[r][c] < fthresh) {
this.pixels[r][c] = 0.0F;
}
}
}
return this;
}
public FImage clone() {
FImage cpy = new FImage(this.width, this.height);
for(int r = 0; r < this.height; ++r) {
System.arraycopy(this.pixels[r], 0, cpy.pixels[r], 0, this.width);
}
return cpy;
}
public FImageRenderer createRenderer() {
return new FImageRenderer(this);
}
public FImageRenderer createRenderer(RenderHints options) {
return new FImageRenderer(this, options);
}
public FImage divide(FImage im) {
if (!ImageUtilities.checkSameSize(new Image[]{this, im})) {
throw new AssertionError("images must be the same size");
} else {
FImage newImage = new FImage(im.width, im.height);
for(int r = 0; r < im.height; ++r) {
for(int c = 0; c < im.width; ++c) {
newImage.pixels[r][c] = this.pixels[r][c] / im.pixels[r][c];
}
}
return newImage;
}
}
public FImage divideInplace(FImage im) {
if (!ImageUtilities.checkSameSize(new Image[]{this, im})) {
throw new AssertionError("images must be the same size");
} else {
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
this.pixels[y][x] /= im.pixels[y][x];
}
}
return this;
}
}
public FImage divideInplace(Float val) {
float fval = val;
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
this.pixels[y][x] /= fval;
}
}
return this;
}
public FImage divideInplace(float fval) {
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
this.pixels[y][x] /= fval;
}
}
return this;
}
public FImage divideInplace(Image, ?> im) {
if (im instanceof FImage) {
return this.divideInplace((FImage)im);
} else {
throw new UnsupportedOperationException("Unsupported Type");
}
}
public FImage extractROI(int x, int y, FImage out) {
int r = y;
for(int rr = 0; rr < out.height; ++rr) {
int c = x;
for(int cc = 0; cc < out.width; ++cc) {
if (r >= 0 && r < this.height && c >= 0 && c < this.width) {
out.pixels[rr][cc] = this.pixels[r][c];
} else {
out.pixels[rr][cc] = 0.0F;
}
++c;
}
++r;
}
return out;
}
public FImage extractROI(int x, int y, int w, int h) {
FImage out = new FImage(w, h);
int r = y;
for(int rr = 0; rr < h; ++rr) {
int c = x;
for(int cc = 0; cc < w; ++cc) {
if (r >= 0 && r < this.height && c >= 0 && c < this.width) {
out.pixels[rr][cc] = this.pixels[r][c];
} else {
out.pixels[rr][cc] = 0.0F;
}
++c;
}
++r;
}
return out;
}
public FImage fill(Float colour) {
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] = colour;
}
}
return this;
}
public FImage fill(float colour) {
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] = colour;
}
}
return this;
}
public Rectangle getContentArea() {
int minc = this.width;
int maxc = 0;
int minr = this.height;
int maxr = 0;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
if (this.pixels[r][c] > 0.0F) {
if (c < minc) {
minc = c;
}
if (c > maxc) {
maxc = c;
}
if (r < minr) {
minr = r;
}
if (r > maxr) {
maxr = r;
}
}
}
}
return new Rectangle((float)minc, (float)minr, (float)(maxc - minc + 1), (float)(maxr - minr + 1));
}
public double[] getDoublePixelVector() {
double[] f = new double[this.height * this.width];
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
f[x + y * this.width] = (double)this.pixels[y][x];
}
}
return f;
}
public FImage getField(Field f) {
FImage img = new FImage(this.width, this.height / 2);
int init = f.equals(Field.ODD) ? 1 : 0;
int r = init;
for(int r2 = 0; r < this.height && r2 < this.height / 2; ++r2) {
for(int c = 0; c < this.width; ++c) {
img.pixels[r2][c] = this.pixels[r][c];
}
r += 2;
}
return img;
}
public FImage getFieldCopy(Field f) {
FImage img = new FImage(this.width, this.height);
for(int r = 0; r < this.height; r += 2) {
for(int c = 0; c < this.width; ++c) {
if (f.equals(Field.EVEN)) {
img.pixels[r][c] = this.pixels[r][c];
img.pixels[r + 1][c] = this.pixels[r][c];
} else {
img.pixels[r][c] = this.pixels[r + 1][c];
img.pixels[r + 1][c] = this.pixels[r + 1][c];
}
}
}
return img;
}
public FImage getFieldInterpolate(Field f) {
FImage img = new FImage(this.width, this.height);
for(int r = 0; r < this.height; r += 2) {
for(int c = 0; c < this.width; ++c) {
if (f.equals(Field.EVEN)) {
img.pixels[r][c] = this.pixels[r][c];
if (r + 2 == this.height) {
img.pixels[r + 1][c] = this.pixels[r][c];
} else {
img.pixels[r + 1][c] = 0.5F * (this.pixels[r][c] + this.pixels[r + 2][c]);
}
} else {
img.pixels[r + 1][c] = this.pixels[r + 1][c];
if (r == 0) {
img.pixels[r][c] = this.pixels[r + 1][c];
} else {
img.pixels[r][c] = 0.5F * (this.pixels[r - 1][c] + this.pixels[r + 1][c]);
}
}
}
}
return img;
}
public float[] getFloatPixelVector() {
float[] f = new float[this.height * this.width];
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
f[x + y * this.width] = this.pixels[y][x];
}
}
return f;
}
public Float getPixel(int x, int y) {
return this.pixels[y][x];
}
public Comparator super Float> getPixelComparator() {
return new Comparator() {
public int compare(Float o1, Float o2) {
return o1.compareTo(o2);
}
};
}
public Float getPixelInterp(double x, double y) {
int x0 = (int)Math.floor(x);
int x1 = x0 + 1;
int y0 = (int)Math.floor(y);
int y1 = y0 + 1;
if (x0 < 0) {
x0 = 0;
}
if (x0 >= this.width) {
x0 = this.width - 1;
}
if (y0 < 0) {
y0 = 0;
}
if (y0 >= this.height) {
y0 = this.height - 1;
}
if (x1 < 0) {
x1 = 0;
}
if (x1 >= this.width) {
x1 = this.width - 1;
}
if (y1 < 0) {
y1 = 0;
}
if (y1 >= this.height) {
y1 = this.height - 1;
}
float f00 = this.pixels[y0][x0];
float f01 = this.pixels[y1][x0];
float f10 = this.pixels[y0][x1];
float f11 = this.pixels[y1][x1];
float dx = (float)(x - (double)x0);
float dy = (float)(y - (double)y0);
if (dx < 0.0F) {
++dx;
}
if (dy < 0.0F) {
++dy;
}
return Interpolation.bilerp(dx, dy, f00, f01, f10, f11);
}
public Float getPixelInterp(double x, double y, Float background) {
int x0 = (int)Math.floor(x);
int x1 = x0 + 1;
int y0 = (int)Math.floor(y);
int y1 = y0 + 1;
boolean ty1 = true;
boolean tx1 = true;
boolean ty0 = true;
boolean tx0 = true;
if (x0 < 0) {
tx0 = false;
}
if (x0 >= this.width) {
tx0 = false;
}
if (y0 < 0) {
ty0 = false;
}
if (y0 >= this.height) {
ty0 = false;
}
if (x1 < 0) {
tx1 = false;
}
if (x1 >= this.width) {
tx1 = false;
}
if (y1 < 0) {
ty1 = false;
}
if (y1 >= this.height) {
ty1 = false;
}
double f00 = (double)(ty0 && tx0 ? this.pixels[y0][x0] : background);
double f01 = (double)(ty1 && tx0 ? this.pixels[y1][x0] : background);
double f10 = (double)(ty0 && tx1 ? this.pixels[y0][x1] : background);
double f11 = (double)(ty1 && tx1 ? this.pixels[y1][x1] : background);
double dx = x - (double)x0;
double dy = y - (double)y0;
if (dx < 0.0D) {
++dx;
}
if (dy < 0.0D) {
++dy;
}
double interpVal = Interpolation.bilerp(dx, dy, f00, f01, f10, f11);
return (float)interpVal;
}
public float getPixelInterpNative(float x, float y, float background) {
int x0 = (int)Math.floor((double)x);
int x1 = x0 + 1;
int y0 = (int)Math.floor((double)y);
int y1 = y0 + 1;
boolean ty1 = true;
boolean tx1 = true;
boolean ty0 = true;
boolean tx0 = true;
if (x0 < 0) {
tx0 = false;
}
if (x0 >= this.width) {
tx0 = false;
}
if (y0 < 0) {
ty0 = false;
}
if (y0 >= this.height) {
ty0 = false;
}
if (x1 < 0) {
tx1 = false;
}
if (x1 >= this.width) {
tx1 = false;
}
if (y1 < 0) {
ty1 = false;
}
if (y1 >= this.height) {
ty1 = false;
}
float f00 = ty0 && tx0 ? this.pixels[y0][x0] : background;
float f01 = ty1 && tx0 ? this.pixels[y1][x0] : background;
float f10 = ty0 && tx1 ? this.pixels[y0][x1] : background;
float f11 = ty1 && tx1 ? this.pixels[y1][x1] : background;
float dx = x - (float)x0;
float dy = y - (float)y0;
if (dx < 0.0F) {
++dx;
}
if (dy < 0.0F) {
++dy;
}
float interpVal = Interpolation.bilerpf(dx, dy, f00, f01, f10, f11);
return interpVal;
}
public FImage internalCopy(FImage im) {
int h = im.height;
int w = im.width;
float[][] impixels = im.pixels;
for(int r = 0; r < h; ++r) {
System.arraycopy(impixels[r], 0, this.pixels[r], 0, w);
}
return this;
}
public FImage internalAssign(FImage im) {
this.pixels = im.pixels;
this.height = im.height;
this.width = im.width;
return this;
}
public FImage internalAssign(int[] data, int width, int height) {
if (this.height != height || this.width != width) {
this.height = height;
this.width = width;
this.pixels = new float[height][width];
}
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
int rgb = data[x + width * y];
int red = rgb >> 16 & 255;
int green = rgb >> 8 & 255;
int blue = rgb & 255;
float fpix = 0.299F * (float)red + 0.587F * (float)green + 0.114F * (float)blue;
this.pixels[y][x] = ImageUtilities.BYTE_TO_FLOAT_LUT[(int)fpix];
}
}
return this;
}
public FImage inverse() {
float max = this.max();
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] = max - this.pixels[r][c];
}
}
return this;
}
public Float max() {
float max = 1.4E-45F;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
if (max < this.pixels[r][c]) {
max = this.pixels[r][c];
}
}
}
return max;
}
public FValuePixel maxPixel() {
FValuePixel max = new FValuePixel(-1, -1);
max.value = -3.4028235E38F;
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
if (max.value < this.pixels[y][x]) {
max.value = this.pixels[y][x];
max.x = x;
max.y = y;
}
}
}
return max;
}
public Float min() {
float min = 3.4028235E38F;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
if (min > this.pixels[r][c]) {
min = this.pixels[r][c];
}
}
}
return min;
}
public FValuePixel minPixel() {
FValuePixel min = new FValuePixel(-1, -1);
min.value = 3.4028235E38F;
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
if (min.value > this.pixels[y][x]) {
min.value = this.pixels[y][x];
min.x = x;
min.y = y;
}
}
}
return min;
}
public FImage multiply(Float num) {
return (FImage)super.multiply(num);
}
public FImage multiplyInplace(FImage im) {
if (!ImageUtilities.checkSameSize(new Image[]{this, im})) {
throw new AssertionError("images must be the same size");
} else {
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] *= im.pixels[r][c];
}
}
return this;
}
}
public FImage multiplyInplace(Float num) {
float fnum = num;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] *= fnum;
}
}
return this;
}
public FImage multiplyInplace(float fnum) {
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] *= fnum;
}
}
return this;
}
public FImage multiplyInplace(Image, ?> im) {
if (im instanceof FImage) {
return this.multiplyInplace((FImage)im);
} else {
throw new UnsupportedOperationException("Unsupported Type");
}
}
public FImage newInstance(int width, int height) {
return new FImage(width, height);
}
public FImage normalise() {
float min = this.min();
float max = this.max();
if (max == min) {
return this;
} else {
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] = (this.pixels[r][c] - min) / (max - min);
}
}
return this;
}
}
public FImage process(KernelProcessor p) {
return this.process(p, false);
}
public FImage process(KernelProcessor p, boolean pad) {
FImage newImage = new FImage(this.width, this.height);
int kh = p.getKernelHeight();
int kw = p.getKernelWidth();
FImage tmp = new FImage(kw, kh);
int hh = kh / 2;
int hw = kw / 2;
int y;
int x;
if (!pad) {
for(y = hh; y < this.height - (kh - hh); ++y) {
for(x = hw; x < this.width - (kw - hw); ++x) {
newImage.pixels[y][x] = (Float)p.processKernel(this.extractROI(x - hw, y - hh, tmp));
}
}
} else {
for(y = 0; y < this.height; ++y) {
for(x = 0; x < this.width; ++x) {
newImage.pixels[y][x] = (Float)p.processKernel(this.extractROI(x - hw, y - hh, tmp));
}
}
}
return newImage;
}
public FImage processInplace(PixelProcessor p) {
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
this.pixels[y][x] = (Float)p.processPixel(this.pixels[y][x]);
}
}
return this;
}
public void analyseWith(PixelAnalyser p) {
p.reset();
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
p.analysePixel(this.pixels[y][x]);
}
}
}
public void setPixel(int x, int y, Float val) {
if (x >= 0 && x < this.width && y >= 0 && y < this.height) {
this.pixels[y][x] = val;
}
}
public FImage subtract(FImage im) {
if (!ImageUtilities.checkSameSize(new Image[]{this, im})) {
throw new AssertionError("images must be the same size");
} else {
FImage newImage = new FImage(im.width, im.height);
for(int r = 0; r < im.height; ++r) {
for(int c = 0; c < im.width; ++c) {
newImage.pixels[r][c] = this.pixels[r][c] - im.pixels[r][c];
}
}
return newImage;
}
}
public FImage subtract(Float num) {
FImage newImage = new FImage(this.width, this.height);
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
newImage.pixels[r][c] = this.pixels[r][c] - num;
}
}
return newImage;
}
public FImage subtract(Image, ?> input) {
if (input instanceof FImage) {
return this.subtract((FImage)input);
} else {
throw new UnsupportedOperationException("Unsupported Type");
}
}
public FImage subtractInplace(FImage im) {
if (!ImageUtilities.checkSameSize(new Image[]{this, im})) {
throw new AssertionError("images must be the same size");
} else {
float[][] pix1 = this.pixels;
float[][] pix2 = im.pixels;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
pix1[r][c] -= pix2[r][c];
}
}
return this;
}
}
public FImage subtractInplace(Float num) {
float fnum = num;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] -= fnum;
}
}
return this;
}
public FImage subtractInplace(Image, ?> im) {
if (im instanceof FImage) {
return this.subtractInplace((FImage)im);
} else {
throw new UnsupportedOperationException("Unsupported Type");
}
}
public FImage threshold(Float thresh) {
float fthresh = thresh;
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
if (this.pixels[r][c] <= fthresh) {
this.pixels[r][c] = 0.0F;
} else {
this.pixels[r][c] = 1.0F;
}
}
}
return this;
}
public byte[] toByteImage() {
byte[] pgmData = new byte[this.height * this.width];
for(int j = 0; j < this.height; ++j) {
for(int i = 0; i < this.width; ++i) {
int v = (int)(255.0F * this.pixels[j][i]);
v = Math.max(0, Math.min(255, v));
pgmData[i + j * this.width] = (byte)(v & 255);
}
}
return pgmData;
}
public int[] toPackedARGBPixels() {
int[] bimg = new int[this.width * this.height];
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
int v = Math.max(0, Math.min(255, (int)(this.pixels[r][c] * 255.0F)));
int rgb = -16777216 | v << 16 | v << 8 | v;
bimg[c + this.width * r] = rgb;
}
}
return bimg;
}
public String toString() {
String imageString = "";
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
imageString = imageString + String.format("%+.3f ", this.pixels[y][x]);
if (x == 16 && this.width - 16 > x) {
imageString = imageString + "... ";
x = this.width - 16;
}
}
imageString = imageString + "\n";
if (y == 16 && this.height - 16 > y) {
y = this.height - 16;
imageString = imageString + "... \n";
}
}
return imageString;
}
public String toString(String format) {
String imageString = "";
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < this.width; ++x) {
imageString = imageString + String.format(format, this.pixels[y][x]);
}
imageString = imageString + "\n";
}
return imageString;
}
public FImage transform(Matrix transform) {
return (FImage)super.transform(transform);
}
public FImage zero() {
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
this.pixels[r][c] = 0.0F;
}
}
return this;
}
public boolean equals(Object o) {
return !(o instanceof FImage) ? false : this.equalsThresh((FImage)o, 0.0F);
}
public boolean equalsThresh(FImage o, float thresh) {
FImage that = o;
if (o.height == this.height && o.width == this.width) {
for(int i = 0; i < this.height; ++i) {
for(int j = 0; j < this.width; ++j) {
if (Math.abs(that.pixels[i][j] - this.pixels[i][j]) > thresh) {
return false;
}
}
}
return true;
} else {
return false;
}
}
public float getPixelNative(Pixel p) {
return this.getPixelNative(p.x, p.y);
}
public float getPixelNative(int x, int y) {
return this.pixels[y][x];
}
public float[] getPixelVectorNative(float[] f) {
for(int y = 0; y < this.getHeight(); ++y) {
for(int x = 0; x < this.getWidth(); ++x) {
f[x + y * this.getWidth()] = this.pixels[y][x];
}
}
return f;
}
public void setPixelNative(int x, int y, float val) {
this.pixels[y][x] = val;
}
public static FImage[] createArray(int num, int width, int height) {
FImage[] array = new FImage[num];
for(int i = 0; i < num; ++i) {
array[i] = new FImage(width, height);
}
return array;
}
public float sum() {
float sum = 0.0F;
float[][] var2 = this.pixels;
int var3 = var2.length;
for(int var4 = 0; var4 < var3; ++var4) {
float[] row = var2[var4];
for(int i = 0; i < row.length; ++i) {
sum += row[i];
}
}
return sum;
}
public MBFImage toRGB() {
return new MBFImage(ColourSpace.RGB, new FImage[]{this.clone(), this.clone(), this.clone()});
}
public FImage flipX() {
int hwidth = this.width / 2;
for(int y = 0; y < this.height; ++y) {
for(int x = 0; x < hwidth; ++x) {
int xx = this.width - x - 1;
float tmp = this.pixels[y][x];
this.pixels[y][x] = this.pixels[y][xx];
this.pixels[y][xx] = tmp;
}
}
return this;
}
public FImage flipY() {
int hheight = this.height / 2;
for(int y = 0; y < hheight; ++y) {
int yy = this.height - y - 1;
for(int x = 0; x < this.width; ++x) {
float tmp = this.pixels[y][x];
this.pixels[y][x] = this.pixels[yy][x];
this.pixels[yy][x] = tmp;
}
}
return this;
}
public FImage overlayInplace(FImage img, FImage alpha, int x, int y) {
int sx = Math.max(x, 0);
int sy = Math.max(y, 0);
int ex = Math.min(this.width, x + img.getWidth());
int ey = Math.min(this.height, y + img.getHeight());
for(int yc = sy; yc < ey; ++yc) {
for(int xc = sx; xc < ex; ++xc) {
float a = alpha.pixels[yc - sy][xc - sx];
this.pixels[yc][xc] = a * img.pixels[yc - sy][xc - sx] + (1.0F - a) * this.pixels[yc][xc];
}
}
return this;
}
public FImage overlayInplace(FImage image, int x, int y) {
return this.overlayInplace(image, this.clone().fill(1.0F), x, y);
}
public static FImage randomImage(int width, int height) {
FImage img = new FImage(width, height);
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
img.pixels[y][x] = (float)Math.random();
}
}
return img;
}
public FImage replace(Float target, Float replacement) {
return this.replace(target, replacement);
}
public FImage replace(float target, float replacement) {
for(int r = 0; r < this.height; ++r) {
for(int c = 0; c < this.width; ++c) {
if (this.pixels[r][c] == target) {
this.pixels[r][c] = replacement;
}
}
}
return this;
}
public FImage extractCentreSubPix(float cx, float cy, FImage out) {
int width = out.width;
int height = out.height;
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
float ix = (float)((double)((float)x + cx) - (double)(width - 1) * 0.5D);
float iy = (float)((double)((float)y + cy) - (double)(height - 1) * 0.5D);
out.pixels[y][x] = this.getPixelInterpNative(ix, iy, 0.0F);
}
}
return out;
}
}
static abstract class AbstractMultiScaleObjectDetector, DETECTED_OBJECT> implements MultiScaleObjectDetector {
protected Rectangle roi;
protected int minSize = 0;
protected int maxSize = 0;
protected AbstractMultiScaleObjectDetector() {
}
protected AbstractMultiScaleObjectDetector(int minSize, int maxSize) {
this.minSize = minSize;
this.maxSize = maxSize;
}
public void setROI(Rectangle roi) {
this.roi = roi;
}
public void setMinimumDetectionSize(int size) {
this.minSize = size;
}
public void setMaximumDetectionSize(int size) {
this.maxSize = size;
}
public int getMinimumDetectionSize() {
return this.minSize;
}
public int getMaximumDetectionSize() {
return this.maxSize;
}
}
sclass Detector extends AbstractMultiScaleObjectDetector {
/**
* Default step size to make when there is a hint of detection.
*/
public static final int DEFAULT_SMALL_STEP = 1;
/**
* Default step size to make when there is definitely no detection.
*/
public static final int DEFAULT_BIG_STEP = 2;
/**
* Default scale factor multiplier.
*/
public static final float DEFAULT_SCALE_FACTOR = 1.1f;
protected StageTreeClassifier cascade;
protected float scaleFactor = 1.1f;
protected int smallStep = 1;
protected int bigStep = 2;
/**
* Construct the {@link Detector} with the given parameters.
*
* @param cascade
* the cascade or tree of stages.
* @param scaleFactor
* the amount to change between scales (multiplicative)
* @param smallStep
* the amount to step when there is a hint of detection
* @param bigStep
* the amount to step when there is definitely no detection
*/
public Detector(StageTreeClassifier cascade, float scaleFactor, int smallStep, int bigStep) {
super(Math.max(cascade.width, cascade.height), 0);
this.cascade = cascade;
this.scaleFactor = scaleFactor;
this.smallStep = smallStep;
this.bigStep = bigStep;
}
/**
* Construct the {@link Detector} with the given tree of stages and scale
* factor. The default step sizes are used.
*
* @param cascade
* the cascade or tree of stages.
* @param scaleFactor
* the amount to change between scales
*/
public Detector(StageTreeClassifier cascade, float scaleFactor) {
this(cascade, scaleFactor, DEFAULT_SMALL_STEP, DEFAULT_BIG_STEP);
}
/**
* Construct the {@link Detector} with the given tree of stages, and the
* default parameters for step sizes and scale factor.
*
* @param cascade
* the cascade or tree of stages.
*/
public Detector(StageTreeClassifier cascade) {
this(cascade, DEFAULT_SCALE_FACTOR, DEFAULT_SMALL_STEP, DEFAULT_BIG_STEP);
}
/**
* Perform detection at a single scale. Subclasses may override this to
* customise the spatial search. The given starting and stopping coordinates
* take into account any region of interest set on this detector.
*
* @param sat
* the summed area table(s)
* @param startX
* the starting x-ordinate
* @param stopX
* the stopping x-ordinate
* @param startY
* the starting y-ordinate
* @param stopY
* the stopping y-ordinate
* @param ystep
* the amount to step
* @param windowWidth
* the window width at the current scale
* @param windowHeight
* the window height at the current scale
* @param results
* the list to store detection results in
*/
protected void detectAtScale(final SummedSqTiltAreaTable sat, final int startX, final int stopX, final int startY,
final int stopY, final float ystep, final int windowWidth, final int windowHeight,
final List results)
{
for (int iy = startY; iy < stopY; iy++) {
final int y = Math.round(iy * ystep);
for (int ix = startX, xstep = 0; ix < stopX; ix += xstep) {
final int x = Math.round(ix * ystep);
final int result = cascade.classify(sat, x, y);
if (result > 0) {
results.add(new Rectangle(x, y, windowWidth, windowHeight));
}
// if there is no detection, then increase the step size
xstep = (result > 0 ? smallStep : bigStep);
// TODO: think about what to do if there isn't a detection, but
// we're very close to having one based on the ratio of stages
// passes to total stages.
}
}
}
@Override
public List detect(FImage image) {
final List results = new ArrayList();
final int imageWidth = image.getWidth();
final int imageHeight = image.getHeight();
final SummedSqTiltAreaTable sat = new SummedSqTiltAreaTable(image, cascade.hasTiltedFeatures);
// compute the number of scales to test and the starting factor
int nFactors = 0;
int startFactor = 0;
for (float factor = 1; factor * cascade.width < imageWidth - 10 &&
factor * cascade.height < imageHeight - 10; factor *= scaleFactor)
{
final float width = factor * cascade.width;
final float height = factor * cascade.height;
if (width < minSize || height < minSize) {
startFactor++;
}
if (maxSize > 0 && (width > maxSize || height > maxSize)) {
break;
}
nFactors++;
}
// run the detection at each scale
float factor = (float) Math.pow(scaleFactor, startFactor);
for (int scaleStep = startFactor; scaleStep < nFactors; factor *= scaleFactor, scaleStep++) {
final float ystep = Math.max(2, factor);
final int windowWidth = (int) (factor * cascade.width);
final int windowHeight = (int) (factor * cascade.height);
// determine the spatial range, taking into account any ROI.
final int startX = (int) (roi == null ? 0 : Math.max(0, roi.x));
final int startY = (int) (roi == null ? 0 : Math.max(0, roi.y));
final int stopX = Math.round(
(((roi == null ? imageWidth : Math.min(imageWidth, roi.x + roi.width)) - windowWidth)) / ystep);
final int stopY = Math.round(
(((roi == null ? imageHeight : Math.min(imageHeight, roi.y + roi.height)) - windowHeight)) / ystep);
// prepare the cascade for this scale
cascade.setScale(factor);
detectAtScale(sat, startX, stopX, startY, stopY, ystep, windowWidth, windowHeight, results);
}
return results;
}
/**
* Get the step size the detector will make if there is any hint of a
* detection. This should be smaller than {@link #bigStep()}.
*
* @return the amount to step on any hint of detection.
*/
public int smallStep() {
return smallStep;
}
/**
* Get the step size the detector will make if there is definitely no
* detection. This should be bigger than {@link #smallStep()}.
*
* @return the amount to step when there is definitely no detection.
*/
public int bigStep() {
return bigStep;
}
/**
* Set the step size the detector will make if there is any hint of a
* detection. This should be smaller than {@link #bigStep()}.
*
* @param smallStep
* The amount to step on any hint of detection.
*/
public void setSmallStep(int smallStep) {
this.smallStep = smallStep;
}
/**
* Set the step size the detector will make if there is definitely no
* detection. This should be bigger than {@link #smallStep()}.
*
* @param bigStep
* The amount to step when there is definitely no detection.
*/
public void bigStep(int bigStep) {
this.bigStep = bigStep;
}
/**
* Get the scale factor (the amount to change between scales
* (multiplicative)).
*
* @return the scaleFactor
*/
public float getScaleFactor() {
return scaleFactor;
}
/**
* Set the scale factor (the amount to change between scales
* (multiplicative)).
*
* @param scaleFactor
* the scale factor to set
*/
public void setScaleFactor(float scaleFactor) {
this.scaleFactor = scaleFactor;
}
/**
* Get the classifier tree or cascade used by this detector.
*
* @return the classifier tree or cascade.
*/
public StageTreeClassifier getClassifier() {
return cascade;
}
}
sclass HaarCascadeDetector {
public enum BuiltInCascade {
/**
* A eye detector
*/
eye("haarcascade_eye.xml"),
/**
* A eye with glasses detector
*/
eye_tree_eyeglasses("haarcascade_eye_tree_eyeglasses.xml"),
/**
* A frontal face detector
*/
frontalface_alt("haarcascade_frontalface_alt.xml"),
/**
* A frontal face detector
*/
frontalface_alt2("haarcascade_frontalface_alt2.xml"),
/**
* A frontal face detector
*/
frontalface_alt_tree("haarcascade_frontalface_alt_tree.xml"),
/**
* A frontal face detector
*/
frontalface_default("haarcascade_frontalface_default.xml"),
/**
* A fullbody detector
*/
fullbody("haarcascade_fullbody.xml"),
/**
* A left eye detector
*/
lefteye_2splits("haarcascade_lefteye_2splits.xml"),
/**
* A lower body detector
*/
lowerbody("haarcascade_lowerbody.xml"),
/**
* A detector for a pair of eyes
*/
mcs_eyepair_big("haarcascade_mcs_eyepair_big.xml"),
/**
* A detector for a pair of eyes
*/
mcs_eyepair_small("haarcascade_mcs_eyepair_small.xml"),
/**
* A left eye detector
*/
mcs_lefteye("haarcascade_mcs_lefteye.xml"),
/**
* A mouth detector
*/
mcs_mouth("haarcascade_mcs_mouth.xml"),
/**
* A nose detector
*/
mcs_nose("haarcascade_mcs_nose.xml"),
/**
* A right eye detector
*/
mcs_righteye("haarcascade_mcs_righteye.xml"),
/**
* An upper body detector
*/
mcs_upperbody("haarcascade_mcs_upperbody.xml"),
/**
* A profile face detector
*/
profileface("haarcascade_profileface.xml"),
/**
* A right eye detector
*/
righteye_2splits("haarcascade_righteye_2splits.xml"),
/**
* An upper body detector
*/
upperbody("haarcascade_upperbody.xml");
private String classFile;
private BuiltInCascade(String classFile) {
this.classFile = classFile;
}
/**
* @return The name of the cascade resource
*/
public String classFile() {
return classFile;
}
/**
* Create a new detector with the this cascade.
*
* @return A new {@link HaarCascadeDetector}
*/
public HaarCascadeDetector load() {
try {
return new HaarCascadeDetector(classFile);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}
protected Detector detector;
protected DetectionFilter> groupingFilter;
protected boolean histogramEqualize = false;
/**
* Construct with the given cascade resource. See
* {@link #setCascade(String)} to understand how the cascade is loaded.
*
* @param cas
* The cascade resource.
* @see #setCascade(String)
*/
public HaarCascadeDetector(String cas) {
try {
setCascade(cas);
} catch (final Exception e) {
throw new RuntimeException(e);
}
groupingFilter = new OpenCVGrouping();
}
/**
* Construct with the {@link BuiltInCascade#frontalface_default} cascade.
*/
public HaarCascadeDetector() {
this(BuiltInCascade.frontalface_default.classFile());
}
/**
* Construct with the {@link BuiltInCascade#frontalface_default} cascade and
* the given minimum search window size.
*
* @param minSize
* minimum search window size
*/
public HaarCascadeDetector(int minSize) {
this();
this.detector.setMinimumDetectionSize(minSize);
}
/**
* Construct with the given cascade resource and the given minimum search
* window size. See {@link #setCascade(String)} to understand how the
* cascade is loaded.
*
* @param cas
* The cascade resource.
* @param minSize
* minimum search window size.
*
* @see #setCascade(String)
*/
public HaarCascadeDetector(String cas, int minSize) {
this(cas);
this.detector.setMinimumDetectionSize(minSize);
}
/**
* @return The minimum detection window size
*/
public int getMinSize() {
return this.detector.getMinimumDetectionSize();
}
/**
* Set the minimum detection window size
*
* @param size
* the window size
*/
public void setMinSize(int size) {
this.detector.setMinimumDetectionSize(size);
}
/**
* @return The maximum detection window size
*/
public int getMaxSize() {
return this.detector.getMaximumDetectionSize();
}
/**
* Set the maximum detection window size
*
* @param size
* the window size
*/
public void setMaxSize(int size) {
this.detector.setMaximumDetectionSize(size);
}
/**
* @return The grouping filter
*/
public DetectionFilter> getGroupingFilter() {
return groupingFilter;
}
/**
* Set the filter for merging detections
*
* @param grouping
*/
public void setGroupingFilter(DetectionFilter> grouping) {
this.groupingFilter = grouping;
}
@Override
public List detectFaces(FImage image) {
if (histogramEqualize)
image.processInplace(new EqualisationProcessor());
final List rects = detector.detect(image);
final List> filteredRects = groupingFilter.apply(rects);
final List results = new ArrayList();
for (final ObjectIntPair r : filteredRects) {
results.add(new DetectedFace(r.first, image.extractROI(r.first), r.second));
}
return results;
}
/**
* @see Detector#getScaleFactor()
* @return The detector scale factor
*/
public double getScaleFactor() {
return detector.getScaleFactor();
}
/**
* Set the cascade classifier for this detector. The cascade file is first
* searched for as a java resource, and if it is not found then a it is
* assumed to be a file on the filesystem.
*
* @param cascadeResource
* The cascade to load.
* @throws Exception
* if there is a problem loading the cascade.
*/
public void setCascade(String cascadeResource) throws Exception {
// try to load serialized cascade from external XML file
InputStream in = null;
try {
in = OCVHaarLoader.class.getResourceAsStream(cascadeResource);
if (in == null) {
in = new FileInputStream(new File(cascadeResource));
}
final StageTreeClassifier cascade = OCVHaarLoader.read(in);
if (this.detector == null)
this.detector = new Detector(cascade);
else
this.detector = new Detector(cascade, this.detector.getScaleFactor());
} catch (final Exception e) {
throw e;
} finally {
if (in != null) {
try {
in.close();
} catch (final IOException e) {
}
}
}
}
/**
* Set the detector scale factor
*
* @see Detector#setScaleFactor(float)
*
* @param scaleFactor
* the scale factor
*/
public void setScale(float scaleFactor) {
this.detector.setScaleFactor(scaleFactor);
}
/**
* Serialize the detector using java serialization to the given stream
*
* @param os
* the stream
* @throws IOException
*/
public void save(OutputStream os) throws IOException {
final ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(this);
}
/**
* Deserialize the detector from a stream. The detector must have been
* written with a previous invokation of {@link #save(OutputStream)}.
*
* @param is
* @return {@link HaarCascadeDetector} read from stream.
* @throws IOException
* @throws ClassNotFoundException
*/
public static HaarCascadeDetector read(InputStream is) throws IOException, ClassNotFoundException {
final ObjectInputStream ois = new ObjectInputStream(is);
return (HaarCascadeDetector) ois.readObject();
}
@Override
public int hashCode() {
int hashCode = HashCodeUtil.SEED;
hashCode = HashCodeUtil.hash(hashCode, this.detector.getMinimumDetectionSize());
hashCode = HashCodeUtil.hash(hashCode, this.detector.getScaleFactor());
hashCode = HashCodeUtil.hash(hashCode, this.detector.getClassifier().getName());
hashCode = HashCodeUtil.hash(hashCode, this.groupingFilter);
hashCode = HashCodeUtil.hash(hashCode, this.histogramEqualize);
return hashCode;
}
@Override
public void readBinary(DataInput in) throws IOException {
this.detector = IOUtils.read(in);
this.groupingFilter = IOUtils.read(in);
histogramEqualize = in.readBoolean();
}
@Override
public byte[] binaryHeader() {
return "HAAR".getBytes();
}
@Override
public void writeBinary(DataOutput out) throws IOException {
IOUtils.write(detector, out);
IOUtils.write(groupingFilter, out);
out.writeBoolean(histogramEqualize);
}
@Override
public String toString() {
return "HaarCascadeDetector[cascade=" + detector.getClassifier().getName() + "]";
}
/**
* @return the underlying Haar cascade.
*/
public StageTreeClassifier getCascade() {
return detector.getClassifier();
}
/**
* @return the underlying {@link Detector}.
*/
public Detector getDetector() {
return detector;
}
}
sclass HaarCascade_FaceDetector extends F1> {
new HaarCascadeDetector detector;
public L get(BufferedImage img) {
if (img == null) null;
ret map(detector.detectFaces(ImageUtilities.createFImage(img)),
func(DetectedFace f) -> RectAndConfidence {
RectAndConfidence(openImajRectangleToRect(f.getBounds()), f.getConfidence())
});
}
}
module HCFD > DynSingleFunctionWithPrintLog {
void doIt {
pnl(new HaarCascade_FaceDetector().get(loadImage2(#1101409)));
}
}