use of org.twak.viewTrace.facades.MiniFacade.Feature in project chordatlas by twak.
the class Regularizer method goDebug.
public List<MiniFacade> goDebug(List<MiniFacade> in, double debugFrac, MegaFeatures megaFeatures) {
miniFacadesUsed += in.size();
regularised++;
for (MiniFacade mf : in) if (mf.imageFeatures != null)
seenImages.add(mf.imageFeatures.ortho);
if (in.isEmpty())
return Collections.singletonList(gridMini());
System.out.println("starting to regularize " + in.size() + " facades...");
in = augmentWithTween(in, megaFeatures);
System.out.println(" adding tween for " + in.size() + " facades");
double alpha = 0.2;
List<MiniFacade> out;
if (true)
out = newFromWindows(in);
else
out = in.stream().map(mf -> new MiniFacade(mf)).collect(Collectors.toList());
System.out.println(" included grids for " + out.size() + " facades...");
if (debugFrac < 0) {
out.add(0, new MiniFacade());
return out;
}
alignMFs(out);
if (debugFrac == 0) {
out.add(0, new MiniFacade());
return out;
}
for (MiniFacade mf : out) {
assignFeaturesToWindows(mf.getRects(Feature.WINDOW, Feature.SHOP).stream().collect(Collectors.toList()), mf.rects);
mf.rects.get(Feature.CORNICE).clear();
mf.rects.get(Feature.BALCONY).clear();
mf.rects.get(Feature.SILL).clear();
mf.rects.get(Feature.GRID).clear();
}
for (MiniFacade mf : out) {
mergeRemoveSmall(mf);
mergeRemoveSimilar(mf);
}
for (Feature f : Feature.values()) for (MiniFacade mf : out) mf.rects.get(f).stream().forEach(r -> r.f = f);
for (int i = 0; i < 50 * debugFrac; i++) {
for (MiniFacade mf : out) for (Feature f : toReg) cluster1(mf.getRects(f), 1, alpha, Bounds.XMIN, Bounds.XMAX, Bounds.YMIN, Bounds.YMAX);
// for (MiniFacade mf : out)
// cluster1 ( mf.getRects(toReg), 1, alpha, Bounds.XMIN, Bounds.XMAX, Bounds.YMIN, Bounds.YMAX);
List<FRect> allRects = new ArrayList<>();
for (MiniFacade mf : out) for (Feature f : toReg) allRects.addAll(mf.rects.get(f));
for (Feature f : toReg) {
List<FRect> allF = out.stream().flatMap(mf -> mf.rects.get(f).stream()).collect(Collectors.toList());
cluster1(allF, 0.5, alpha, Bounds.WIDTH, Bounds.HEIGHT);
}
cluster1(allRects, 0.3, alpha, Bounds.XMIN, Bounds.XMAX, Bounds.YMIN, Bounds.YMAX);
if (i % 5 == 0)
for (MiniFacade mf : out) findNeighbours(mf.getRects(Feature.WINDOW));
for (Dir dir : Dir.values()) clusterDeltas(allRects, 0.2, alpha, dir);
for (MiniFacade mf : out) {
for (FRect d : mf.rects.get(Feature.DOOR)) constrainDoor(mf, d, alpha);
for (FRect m : mf.rects.get(Feature.MOULDING)) constrainMoulding(mf, m, alpha);
}
for (MiniFacade mf : out) {
for (Feature f : toReg) {
Iterator<FRect> rit = mf.rects.get(f).iterator();
while (rit.hasNext()) {
FRect r = rit.next();
if (r.width <= 0.4 || r.height <= 0.4)
rit.remove();
else
for (FRect n : r.adjacent) if (n != null && similar(n, r)) {
n.attached.putAll(r.attached);
rit.remove();
break;
}
}
}
}
}
if (debugFrac < 1) {
out.add(0, new MiniFacade());
return out;
}
for (MiniFacade mf : out) {
findOuters(mf);
mergeRemoveSmall(mf);
}
ids = 0;
for (// find ids...starting with the biggest
Feature f : // find ids...starting with the biggest
toReg) {
List<Pair<MiniFacade, FRect>> allRects = new ArrayList<>();
for (MiniFacade mf : out) for (FRect r : mf.rects.get(f)) allRects.add(new Pair<>(mf, r));
Collections.sort(allRects, new Comparator<Pair<MiniFacade, FRect>>() {
@Override
public int compare(Pair<MiniFacade, FRect> a_, Pair<MiniFacade, FRect> b_) {
FRect a = a_.second(), b = b_.second();
if (a.gridCoords != null && b.gridCoords == null)
return -1;
if (b.gridCoords != null && a.gridCoords == null)
return 1;
if (a.gridCoords != null && b.gridCoords != null) {
int out = -Integer.compare(countCoords(a.gridCoords), countCoords(b.gridCoords));
if (out != 0)
return out;
}
return Double.compare(a.area(), b.area());
}
private int countCoords(int[] gridCoords) {
int out = 0;
for (int i : gridCoords) if (i != -Integer.MAX_VALUE)
out++;
return out;
}
});
for (Pair<MiniFacade, FRect> pair : allRects) {
FRect w = pair.second();
if (w.id == -1)
findId(w, f, out, pair.first(), ids++);
}
}
out.add(0, combine(out));
totalFeature += out.get(0).getRects(Feature.values()).size();
System.out.println("done");
return out;
}
use of org.twak.viewTrace.facades.MiniFacade.Feature in project chordatlas by twak.
the class Regularizer method findOuters.
private void findOuters(MiniFacade mf) {
mf.outers.clear();
for (Feature f : Feature.values()) {
if (f != Feature.WINDOW)
continue;
Set<FRect> togo = new LinkedHashSet(mf.rects.get(f));
while (!togo.isEmpty()) {
AOuter outer = new AOuter(f);
FRect first = findBest(togo);
Set<FRect> neighbours = new TreeSet<>(FRect.comparatorArea(false));
neighbours.add(first);
while (!neighbours.isEmpty()) {
FRect n = neighbours.iterator().next();
if (!togo.contains(n)) {
neighbours.remove(n);
continue;
}
if (outer.easyAdd(n)) {
neighbours.remove(n);
add(togo, neighbours, n);
} else {
n = findBest(neighbours);
neighbours.remove(n);
if (outer.extend(n))
add(togo, neighbours, n);
}
}
if (outer.building.findPositions().values().size() >= 2) {
outer.done();
mf.outers.add(outer);
// re-ground the grid coordinate system
CountThings<Integer> xes = new CountThings<>(), yes = new CountThings<>();
for (int x = 0; x < outer.elements.length; x++) for (int y = 0; y < outer.elements[0].length; y++) if (outer.elements[x][y] != null) {
xes.count(x);
yes.count(y);
}
double halfAvgX = 0.5 * xes.getSize() / xes.counts.cache.keySet().size(), halfAvgY = 0.5 * yes.getSize() / yes.counts.cache.keySet().size();
List<Integer> rows = new ArrayList(xes.counts.cache.keySet());
Collections.sort(rows);
int xMin = rows.stream().filter(row -> xes.total(row) > halfAvgX).findFirst().get();
Collections.reverse(rows);
int xMax = rows.stream().filter(row -> xes.total(row) > halfAvgX).findFirst().get();
List<Integer> cols = new ArrayList(yes.counts.cache.keySet());
int yMin = cols.stream().filter(col -> yes.total(col) > halfAvgY).findFirst().get();
Collections.reverse(cols);
int yMax = cols.stream().filter(col -> yes.total(col) > halfAvgY).findFirst().get();
for (int x = 0; x < outer.elements.length; x++) for (int y = 0; y < outer.elements[0].length; y++) {
FRect w = outer.elements[x][y];
if (w == null)
continue;
w.gridCoords = new int[] { w.xi - xMin, xMax - w.xi, w.yi - yMin, yMax - w.yi };
if (mf.softLeft)
w.gridCoords[0] = -Integer.MAX_VALUE;
if (mf.softRight)
w.gridCoords[1] = -Integer.MAX_VALUE;
}
}
}
}
}
use of org.twak.viewTrace.facades.MiniFacade.Feature in project chordatlas by twak.
the class Regularizer method assignFeaturesToWindows.
private void assignFeaturesToWindows(List<FRect> windows, MultiMap<Feature, FRect> rects) {
int count = 0;
for (Feature f : new Feature[] { Feature.CORNICE, Feature.SILL, Feature.BALCONY }) {
for (FRect r : rects.get(f)) {
for (FRect w : windows) {
DRectangle bounds = new DRectangle(w);
bounds.height = bounds.height * 0.5;
switch(f) {
case SILL:
bounds.y = bounds.x - bounds.height;
break;
case BALCONY:
bounds.y = bounds.x;
break;
case CORNICE:
bounds.y = bounds.getMaxY();
break;
default:
break;
}
if (r.intersects(w)) {
w.attached.put(f, r);
count++;
}
}
FRect win = nearest(windows, r, 2);
if (win != null)
win.attached.put(f, r);
}
}
// System.out.println("atatched " + count +" cornicesesese");
}
use of org.twak.viewTrace.facades.MiniFacade.Feature in project chordatlas by twak.
the class Regularizer method combine.
private MiniFacade combine(List<MiniFacade> in) {
MiniFacade out = new MiniFacade();
out.left = lp;
out.width = rp - lp;
out.imageFeatures = in.get(0).imageFeatures;
out.color = new double[] { 0, 0, 0, 1 };
out.groundColor = new double[] { 0, 0, 0, 1 };
int gcc = 0;
for (MiniFacade mf : in) for (int i = 0; i < 3; i++) {
out.color[i] += mf.color[i];
if (mf.groundColor != null) {
out.groundColor[i] += mf.groundColor[i];
gcc++;
}
}
for (int i = 0; i < 3; i++) {
out.color[i] /= in.size();
if (gcc > 0)
out.groundColor[i] /= gcc;
}
Cache2<Outer, Integer, List<FRect>> corniceX = new ArrayCache2();
Cache2<Outer, Integer, List<FRect>> sillX = new ArrayCache2();
Cache2<Outer, Integer, List<FRect>> balX = new ArrayCache2();
out.height = in.stream().mapToDouble(mf -> mf.height).average().getAsDouble();
out.groundFloorHeight = in.stream().mapToDouble(mf -> mf.groundFloorHeight).average().getAsDouble();
for (int i = 0; i < ids; i++) {
int yay = 0, nay = 0;
int ii = i;
List<FRect> found = in.stream().map(mf -> m2i2r.get(mf, ii)).filter(x -> x != null).flatMap(l -> l.stream()).collect(Collectors.toList());
Point2d avg = found.stream().map(r -> r.getCenter()).collect(new Point2DMeanCollector());
for (MiniFacade mf : in) {
List<FRect> r = m2i2r.get(mf, i);
if (mf.contains(avg)) {
if (r.isEmpty()) {
if (mf.left + 3 < avg.x && mf.left + mf.width - 3 > avg.x)
nay++;
} else
yay++;
}
}
if (yay >= nay) {
// if we believe it exists add it as average of observed sizes
FRect o;
if (dimensionSpread(found) > 1.4) {
// scattered -> union (typically shop windows)
o = new FRect(found.get(0));
for (FRect n : found) o.setFrom(o.union(n));
} else
// about same size: average position: windows on a grid
o = new FRect(average(found.toArray(new FRect[found.size()])));
{
FRect t = found.get(0);
o.f = t.f;
o.id = i;
o.outer = null;
o.attachedHeight.get(Feature.SILL).d = averageAttached(o, Feature.SILL, found);
o.attachedHeight.get(Feature.CORNICE).d = averageAttached(o, Feature.CORNICE, found);
o.attachedHeight.get(Feature.BALCONY).d = averageAttached(o, Feature.BALCONY, found);
if (t.f == Feature.WINDOW || t.f == Feature.SHOP) {
for (FRect r : found) {
corniceX.get(r.outer, r.yi).add(o);
sillX.get(r.outer, r.yi).add(o);
balX.get(r.outer, r.yi).add(o);
}
}
}
out.rects.put(o.f, o);
}
}
spreadAttachedOverGrid(Feature.SILL, sillX);
spreadAttachedOverGrid(Feature.CORNICE, corniceX);
spreadAttachedOverGrid(Feature.BALCONY, balX);
fixOverlaps(out);
mergeRemoveSmall(out);
DRectangle mr = out.getAsRect();
// ensure everything is comfortably within the bounds
mr.width -= 0.2;
mr.x += 0.1;
for (Feature f : Feature.values()) {
// clip to all
Iterator<FRect> rit = out.rects.get(f).iterator();
while (rit.hasNext()) {
FRect r = rit.next();
DRectangle section = r.intersect(mr);
if (section == null || section.area() < 0.5)
rit.remove();
else
r.setFrom(section);
}
}
{
// door height
Double hf = Double.valueOf(0);
while (out.groundFloorHeight < 6 && ((hf = horizontalEmpty(out, out.groundFloorHeight)) != null)) out.groundFloorHeight = hf + 0.3;
if (out.groundFloorHeight >= 6)
// no ground floor!
out.groundFloorHeight = 0;
}
return out;
}
Aggregations