package com.github.axet.lookup.common;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import com.github.axet.lookup.Capture;
public class FeatureK {
public Feature f;
public List<RectK> list;
public double k;
IntegralImage template;
public FeatureK(RectK k) {
list.add(k);
}
public FeatureK(Feature f, IntegralImage template) {
this.template = template;
this.f = f;
Set<RectK> list = new TreeSet<RectK>();
for (int x = 0; x < f.cx; x++) {
for (int y = 0; y < f.cy; y++) {
RectK k = rectNearFill(x, y);
list.add(k);
}
}
this.list = Arrays.asList(list.toArray(new RectK[] {}));
double dx = template.cx / (double) f.cx;
double dy = template.cy / (double) f.cy;
for (RectK k : this.list) {
int w = k.x2 - k.x1 + 1;
int h = k.y2 - k.y1 + 1;
k.x1 *= dx;
k.y1 *= dy;
k.x2 = (int) (k.x1 + w * dx - 1);
k.y2 = (int) (k.y1 + h * dy - 1);
k.cxBase = template.cx;
k.cyBase = template.cy;
k.k = template.mean(k.x1, k.y1, k.x2, k.y2);
this.k += k.k;
}
// this.list = fillFeature(3);
}
/**
* debug. make feature exact as template image
*
* @param step
* @return
*/
List<RectK> fillFeature(int step) {
List<RectK> list = new ArrayList<RectK>();
int cx = template.cx;
int cy = template.cy;
for (int x = 0; x < cx; x += step) {
for (int y = 0; y < cy; y += step) {
RectK k = new RectK(x, y);
k.x2 += step - 1;
k.y2 += step - 1;
if (k.x2 >= cx)
k.x2 = cx - 1;
if (k.y2 >= cy)
k.y2 = cy - 1;
if (k.getWidth() == 0)
continue;
if (k.getHeight() == 0)
continue;
k.cxBase = template.cx;
k.cyBase = template.cy;
k.k = template.mean(k.x1, k.y1, k.x2, k.y2);
list.add(k);
}
}
return list;
}
RectK rectNearFill(int x, int y) {
RectK k = near(x, y);
k = fill(k);
return k;
}
int limX(int i) {
if (i < 0)
return 0;
if (i >= f.cx)
return f.cx - 1;
return i;
}
int limY(int i) {
if (i < 0)
return 0;
if (i >= f.cy)
return f.cy - 1;
return i;
}
RectK near(int x, int y) {
if (test(x, y))
return new RectK(x, y);
int m = Math.max(f.cx, f.cy);
for (int r = 1; r < m; r++) {
int xx;
int xxm;
int yy;
int yym;
// top - bottom
xx = limX(x - r);
yym = limY(y + r);
for (yy = limY(y - r); yy <= yym; yy++) {
if (test(xx, yy))
return new RectK(xx, yy);
}
// left - right
yy = limY(y + r);
xxm = limX(x + r);
for (xx = limX(x - r); xx <= xxm; xx++) {
if (test(xx, yy))
return new RectK(xx, yy);
}
// down - top
xx = limX(x + r);
yym = limY(y - r);
for (yy = limY(y + r); yy >= yym; yy--) {
if (test(xx, yy))
return new RectK(xx, yy);
}
// right - left
yy = limY(y - r);
xxm = limX(x - r);
for (xx = limX(x + r); xx >= xxm; xx--) {
if (test(xx, yy))
return new RectK(xx, yy);
}
}
throw new RuntimeException("no 1 found");
}
boolean test(int x, int y) {
if (x >= f.cx)
return false;
if (y >= f.cy)
return false;
if (f.s(x, y) == 1)
return true;
return false;
}
RectK fill(RectK k) {
while (test(k.x1 - 1, k.y1)) {
k.x1--;
}
while (test(k.x1, k.y1 - 1)) {
k.y1--;
}
while (test(k.x2 + 1, k.y1)) {
k.x2++;
}
while (test(k.x2, k.y2 + 1)) {
k.y2++;
}
k.cxBase = f.cx;
k.cyBase = f.cy;
return k;
}
public void devide(RectK k) {
;
}
public BufferedImage getImage() {
BufferedImage image = new BufferedImage(template.cx, template.cy, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
g.setColor(Color.MAGENTA);
g.fillRect(0, 0, template.cx, template.cy);
g.setColor(new Color(0, 0, 0));
for (RectK k : list) {
g.fillRect(k.x1, k.y1, k.getWidth(), k.getHeight());
}
return image;
}
public void writeDesktop() {
Capture.writeDesktop(getImage());
}
}