Warning: session_start(): open(/var/lib/php/sessions/sess_q6nu1vlmo0gdh1mhk7i5nss1me, 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
srecord noeq MinimalRecognizer(BufferedImage inputImage) {
replace Channel with int.
IIntegralImage mainImage;
static final int grayscale = 3; // channel number for grayscale
abstract class IIntegralImage {
// width and height of image
int w, h;
abstract double integralValue(int x, int y, Channel channel);
BufferedImage render() {
ret imageFromFunction(w, h, (x, x) -> rgbPixel(x, y, x+1, y+1) | fullAlphaMask());
}
double getPixel(Rect r, int channel) {
ret getPixel(r.x, r.y, r.x2(), r.y2(), channel);
}
double getPixel(int channel) { ret getPixel(0, 0, w, h, channel); }
// return value ranges from 0 to 1 (usually)
double getPixel(int x1, int y1, int x2, int y2, int channel) {
ret doubleRatio(rectSum(x1, y1, x2, y2, channel), (x2-x1)*(y2-y1)*255.0);
}
double rectSum(Rect r, int channel) {
ret rectSum(r.x, r.y, r.x2(), r.y2(), channel);
}
double rectSum(int x1, int y1, int x2, int y2, int channel) {
double bottomLeft = integralValue(x1-1, y2-1, channel);
double bottomRight = integralValue(x2-1, y2-1, channel);
double topLeft = integralValue(x1-1, y1-1, channel);
double topRight = integralValue(x2-1, y1-1, channel);
ret bottomRight-topRight-bottomLeft+topLeft;
}
int rgbPixel(int x1, int y1, int x2, int y2) {
int r = iround(clampZeroToOne(getPixel(x1, y1, x2, y2, 0))*255);
int g = iround(clampZeroToOne(getPixel(x1, y1, x2, y2, 1))*255);
int b = iround(clampZeroToOne(getPixel(x1, y1, x2, y2, 2))*255);
ret rgbInt(r, g, b);
}
double liveliness(int channel) {
// optimization (but no change in semantics):
// if (w <= 1 && h <= 1) ret 0; // liveliness of single pixel is 0
ret standardDeviation(map(q -> q.getPixel(channel), quadrants()));
}
L quadrants() {
if (w <= 1 && h <= 1) null; // let's really not have quadrants of a single pixel
int midX = w/2, midY = h/2;
ret mapLL clip(
rect(0, 0, max(midX, 1), max(midY, 1)),
rect(midX, 0, w-midX, max(midY, 1)),
rect(0, midY, max(midX, 1), h-midY),
rect(midX, midY, w-midX, h-midY)
);
}
IIntegralImage liveliestQuadrant(int channel) {
ret highestBy(q -> q.liveliness(channel), quadrants());
}
Clip clip(Rect r) { ret new Clip(this, r); }
Rect positionInImage(IIntegralImage mainImage) {
if (this == mainImage) ret rect(0, 0, w, h);
null;
}
}
// virtual clip of an integral image
class Clip extends IIntegralImage {
IIntegralImage fullImage;
int x1, y1;
*(IIntegralImage *fullImage, Rect r) {
x1 = r.x; y1 = r.y; w = r.w; h = r.h;
}
*(IIntegralImage *fullImage, int *x1, int *y1, int *w, int *h) {}
public double integralValue(int x, int y, int channel) {
ret fullImage.integralValue(x+x1, y+y1, channel);
}
// don't clip a clip - be smarter than that!
Clip clip(Rect r) {
ret new Clip(fullImage, translateRect(r, x1, y1));
}
Rect rectInImage() {
ret rect(x1, y1, w, h);
}
Rect positionInImage(IIntegralImage mainImage) {
try object Rect r = super.positionInImage(mainImage);
if (fullImage == mainImage) ret rect(x1, y1, w, h);
null;
}
toString { ret rectInImage() + " in " + fullImage; }
}
class IntegralImage extends IIntegralImage {
int[] data;
*(BufferedImage img) {
w = img.getWidth();
h = img.getHeight();
if (longMul(w, h) > 8000000) fail("Image too big: " + w + "*" + h);
int[] pixels = pixelsOfBufferedImage(img);
data = new int[w*h*3];
int i = 0, j = 0, sumR = 0, sumG = 0, sumB = 0;
for x to w: {
int rgb = pixels[j++];
data[i++] = (sumR += (rgb >> 16) & 0xFF);
data[i++] = (sumG += (rgb >> 8) & 0xFF);
data[i++] = (sumB += rgb & 0xFF);
}
for (int y = 1; y < h; y++) {
sumR = sumG = sumB = 0;
for x to w: {
int rgb = pixels[j++];
sumR += (rgb >> 16) & 0xFF;
sumG += (rgb >> 8) & 0xFF;
sumB += rgb & 0xFF;
data[i] = sumR + data[i-w*3];
data[i+1] = sumG + data[i-w*3+1];
data[i+2] = sumB + data[i-w*3+2];
i += 3;
}
}
}
public double integralValue(int x, int y, Channel channel) {
if (channel == grayscale)
ret doubleAvg(countIterator(3, c -> integralValue(x, y, c)));
ret x < 0 || y < 0 ? 0
: data[(min(y, h-1)*w+min(x, w-1))*3+channel];
}
}
run {
mainImage = new IntegralImage(inputImage);
inputImage = null; // save space
print(liveliness := mainImage.liveliness(grayscale));
IIntegralImage clip = mainImage;
clip = applyUntilEqual_goOneBackOnNull(c -> c.liveliestQuadrant(grayscale), clip);
print(liveliestPoint := clip);
showImageWithSelection(mainImage.render(), growRect(10, clip.positionInImage(mainImage)));
}
}