Warning: session_start(): open(/var/lib/php/sessions/sess_l4l89rvh89cjkbjgnb508iqce6, 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
// multi-resolution image search
// uses only one prototype image
cmodule ImageRecogSpike {
switchable S prototypeImageID = #1102884;
switchable S inputImageID = #1102883;
switchable bool showResizedProtos;
switchable int numberOfCandidatesToShow = 3;
// how big do we think the prototype is in the whole image
// (percentage by height)
transient double assumedPrototypeHeightPercentage = 70;
transient L widths = ll(1, 2, 4, 8, 16, 32, 64, 128);
transient new L integralImages;
transient BWIntegralImage baseImage;
transient JTabbedPane tabs = jTabbedPane();
transient BWImage prototypeImage;
transient new L levels; // recognizers for each granularity
class OneLevel extends SteppableAndBest {
IBWIntegralImage ii; // scaled integral image
BWImage image; // scaled image
BWImage prototype; // scaled prototype
float minSimilarity = 0.5f;
ImageSurface is;
new Map allScores;
// candidates are top-left corner of rect to try in our coordinates
L candidatesQueue = syncLinkedList();
new Set candidatesTried;
Iterator candidatesStream;
*(IBWIntegralImage *ii) {
image = iBWIntegralImageToBWImage(ii);
// get assumed height of prototype in scaled-down image
int ph = iround(ii.getHeight()*assumedPrototypeHeightPercentage/100.0);
// resize prototype
prototype = bwResizeToHeightSmooth(prototypeImage, ph);
if (showResizedProtos)
addTab(tabs, "proto " + ii.getWidth(),
jFullCenterScroll(jPixelatedZoomedImageSurface(4.0, prototype)));
candidatesStream = mapI rectTopLeftCorner(allSubRectsOfSizeIterator(prototype.getWidth(), prototype.getHeight(),
imageRect(image)));
}
int height() { ret ii.getHeight(); }
public bool step() {
Pt p = nextCandidate();
if (p != null) ret true with tryCandidate(p);
false;
}
Pt nextCandidate() {
try object Pt p = popFirst(candidatesQueue);
ret nextFromIterator(candidatesStream);
}
void tryCandidate(Pt p) {
if (!candidatesTried.add(p)) ret;
int x = p.x, y = p.y, wp = prototype.getWidth(), hp = prototype.getHeight();
float maxError = (1f-minSimilarity)*wp*hp;
float diff = bwImageSectionsSimilarity(image, prototype, x, y, maxError);
if (diff <= maxError)
putInBestAndMap(best, allScores, new Rect(x, y, wp, hp), 1-diff/(wp*hp);
}
void showBest() {
overlaySelectionsOnImageSurface(is, nBest(numberOfCandidatesToShow));
}
L nBest(int n) {
ret topTenKeysByValue(n, allScores);
}
}
start-thread {
dm_watchField numberOfCandidatesToShow(r showBest);
if (baseImage == null)
baseImage = BWIntegralImage(loadImage2(inputImageID));
if (prototypeImage == null)
prototypeImage = loadBWImage(prototypeImageID);
for (int w : widths) {
IBWIntegralImage ii = scaledIBWIntegralImage(baseImage, w);
integralImages.add(ii);
ImageSurface is = jPixelatedZoomedImageSurface(
doubleRatio(baseImage.getWidth(), w), iBWIntegralImageToBWImage(ii));
addTab(tabs, "w=" + w, jFullCenterScroll(is));
levels.add(setAll(new OneLevel(ii), +is));
}
addTab(tabs, "Prototype", jFullCenterScroll(jPixelatedZoomedImageSurface(4, prototypeImage)));
time "Recognition" {
//fullSearch();
twoLevels(16, 128, 5);
}
showBest();
}
void fullSearch {
print("Steps: " + stepAll_roundRobin(levels));
}
void twoLevels(int width1, int width2, int candidatesToUse) {
int pixelsPerSpiral = sqr(width2/width1*2);
int i1 = indexOf(widths, width1), i2 = indexOf(widths, width2);
if (i1 < 0) fail("Width " + width1 + " not in list: " + widths);
if (i2 < 0) fail("Width " + width2 + " not in list: " + widths);
OneLevel lvl1 = levels.get(i1), lvl2 = levels.get(i2);
// Full search in level 1
stepAll(lvl1);
// Circle around n best candidates found in level 1
L candidates = scaleBetweenLevels(lvl1, lvl2, lvl1.nBest(candidatesToUse));
for (Pt p : combineIterators_roundRobin(map(candidates, c ->
pixelSpiral(c, lvl2.width, lvl2.height(), pixelsPerSpiral))))
lvl2.tryCandidate(p);
}
Pt scaleBetweenLevels(OneLevel lvl1, OneLevel lvl2, Pt p) {
ret scalePt(doubleRatio(lvl2.width, lvl1.width), p);
}
L scaleBetweenLevels(OneLevel lvl1, OneLevel lvl2, Iterable l) {
ret map(l, p -> scaleBetweenLevels(lvl1, lvl2, p));
}
void showBest {
for (OneLevel l : levels) l.showBest();
}
visual withCenteredButtons(tabs,
withLabel("# of candidates to show:", dm_fieldSpinner numberOfCandidatesToShow(1, 100)));
}