srecord noeq ImageSimilarityAtScale( IIntegralImage img1, IIntegralImage img2, int featureSize // smallest block size looked at (in pixels) ) extends Probabilistic { int channels; LookAtClip root; record LookAtClip(Rect r) { new L children; run { double sum = 0; for i to channels: sum += sqr( img1.rectSum(r, channel)-img2.rectSum(r, channel)); double diff = sqrt(sum)/area(r); submitDifference(r, diff); if (r.w > r.h) { if (r.w > featureSize) splitHorizontally(); } else if (r.h > featureSize) splitVertically(); } } void splitHorizontally { split(asList(splitRectInHorizontalHalves())); } void splitVertically { split(asList(splitRectInVerticalHalves())); } void split(L parts) { double p = 0.99; // TODO: do something smarter (recurse earlier in "interesting" areas) children = map(parts, r -> new LookAtClip(r)); scheduleAll(p, children); } } void submitDifference(Rect r, double diff) { } run { assertEqualsVerbose("Sizes of compared images have to be equal", img1.getSize(), img2.getSize()); assertEqualsVerbose("Channel counts of compared images have to be equal", channels = img1.nChannels(), img2.nChannels()); schedule(root = new LookAtClip(imageRect(img1))); } }