!752 static BWImage img; static ImageSurface is2; static float threshold = 0.9f; p { img = loadBWImage("#1005702"); update(); } svoid update() { float[] f = columnBrightnesses(img); quickShowZoomedImage(img.toRGB()); //showZoomedImage(brightnessesAsImage(f).toRGB()); L streaks = makeStreaks(f, threshold); //printStruct(f); //printStruct(streaks); print("Threshold: " + threshold + ", streaks: " + l(streaks)); RGBImage vis = visualizeStreaks(img, streaks).toRGB(); if (is2 == null) { is2 = showZoomedImage(vis); addToWindowAndPack(is2, liveSlider(threshold/10000f*9999f, voidfunc(float x) { threshold = x*10000f/9999f; update(); })); } else is2.setImage(vis); } // f: voidfunc(float) static JSlider liveSlider(float def, final O f) { final int max = 9999; final JSlider slider = new JSlider(0, max, iround(def*max)); slider.addChangeListener(new ChangeListener { int lastValue = slider.getValue(); public void stateChanged(ChangeEvent e) { int value = slider.getValue(); if (value != lastValue) { lastValue = value; pcallF(f, value/(float) max); } } }); ret slider; } sclass Streak { int from, to; // to = exclusive *() {} *(int *from, int *to) {} } static L makeStreaks(float[] f, float threshold) { new L l; int j = -1; for (int i = 0; i < l(f); i++) if (f[i] < threshold) { // start / continue streak if (j < 0) j = i; } else { if (j >= 0) { // end streak l.add(new Streak(j, i)); j = -1; } } if (j >= 0) l.add(new Streak(j, l(f))); ret l; } static float[] columnBrightnesses(BWImage img) { int w = img.getWidth(), h = img.getHeight(); float[] f = new float[w]; for x to w: f[x] = (float) img.clip(x, 0, 1, h).averageBrightness(); ret f; } static BWImage brightnessesAsImage(float[] f) { int w = f.length, h = 20; BWImage img = new BWImage(w, h); for y to h: for x to w: img.setPixel(x, y, f[x]); ret img; } static float[] streaksToFloats(int w, L l) { float[] f = new float[w]; for (Streak s : l) for (int i = s.from; i < s.to; i++) f[i] = 1f; ret f; } /*static streaksToGaps(int w, L l) { ret makeStreaks(streaksToFloats(w, l), 0.5f); }*/ /*static BWImage visualizeStreaks(BWImage img, L streaks) { int gap = 5; float gapColor = 0.5f; int w = img.getWidth(), h = img.getHeight(); L gaps = streaksToGaps(w, streaks); int n = l(gaps); int w2 = w+n*gap; BWImage im = new BWImage(w2, gapColor); copyBWImage(img, ret im; }*/ static BWImage visualizeStreaks(BWImage img, L streaks) { float gapColor = 0.5f; int w = img.getWidth(), h = img.getHeight(); BWImage im = new BWImage(w, h*2, gapColor); float[] f = streaksToFloats(w, streaks); for x to w: copyBWImage(img, x, 0, im, x, (int) (f[x]*h), 1, h); ret im; }