Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

455
LINES

< > BotCompany Repo | #725 // Reproducing with boxes v2 (with individual diffs, developing)

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Transpiled version (1651L) is out of date.

1  
!636
2  
!standard functions
3  
!quicknew
4  
!ctex
5  
!* constructor
6  
7  
import java.awt.*;
8  
import java.awt.image.*;
9  
import java.util.List;
10  
import javax.imageio.*;
11  
12  
!include #2000447 // image classes
13  
14  
public class main {
15  
  static RGBImage originalImage;
16  
  static int imageWidth = 200;
17  
  
18  
  // XXX - main reproduce function
19  
  static Reproducer reproducer =
20  
    /*new Layers(
21  
      new RandomSolid())
22  
      .add(2, RandomBox.class)
23  
    .varyBest;*/
24  
    new OptimizeIndividual(new RandomBox());
25  
    
26  
  static abstract class Img {
27  
    RGBImage img;
28  
    
29  
    *(RGBImage *img) {}
30  
    
31  
    int getWidth() { return img.getWidth(); }
32  
    int getHeight() { return img.getHeight(); }
33  
    //abstract void setPixel(int x, int y, int rgb);
34  
    
35  
    abstract void setPixel(int x, int y, RGB rgb);/* {
36  
      setPixel(x, y, rgb.asInt());
37  
    }*/
38  
  }
39  
  
40  
  static class Painting extends Img {
41  
    *(RGBImage img) { super(img); }
42  
    
43  
    void setPixel(int x, int y, RGB rgb) {
44  
      img.setPixel(x, y, rgb);
45  
    }
46  
  }
47  
    
48  
  static class Diffing extends Img {
49  
    int pixelsDiffed;
50  
    double totalDiff;
51  
    
52  
    *(RGBImage img) { super(img); }
53  
54  
    // assumes each pixel is written only once!
55  
    void setPixel(int x, int y, RGB rgb) {
56  
      totalDiff += pixelDiff(img.getPixel(x, y), rgb);
57  
      pixelsDiffed++;
58  
    }
59  
    
60  
    double getScore() {
61  
      int totalPixels = img.getWidth()*img.getHeight();
62  
      int emptyPixels = totalPixels-pixelsDiffed;
63  
      double innerQuality = totalDiff/Math.max(pixelsDiffed, 1);
64  
      double outerQuality = 0.8; // makes objects shrink or grow
65  
      double result = mix(innerQuality, outerQuality, emptyPixels/(double) totalPixels);
66  
      System.out.println("inner=" + innerQuality + ", outer=" + outerQuality + ", pixels diffed=" + pixelsDiffed + ", result=" + result);
67  
      return result;
68  
    }
69  
  }
70  
71  
  static abstract class Base {
72  
    abstract Base copy();
73  
    
74  
    abstract void vary();
75  
    
76  
    Base copyVary() {
77  
      Base copy = copy();
78  
      copy.vary();
79  
      return copy;
80  
    }
81  
  }
82  
  
83  
  static abstract class Overlay extends Base {
84  
    abstract Overlay copy();
85  
    abstract void renderOn(Img image);
86  
  }
87  
  
88  
  // Params must be immutable!
89  
  static abstract class Params extends Base {
90  
    RGBImage originalImage;
91  
    abstract Params copy();
92  
    abstract RGBImage render();
93  
94  
    void baseClone(Params p) {
95  
      p.originalImage = originalImage;
96  
    }
97  
    
98  
    RGBImage rendered;
99  
    RGBImage getImage() {
100  
      if (rendered == null)
101  
        rendered = render();
102  
      return rendered;
103  
    }
104  
    
105  
    double score = 2.0;
106  
    double getScore() {
107  
      if (score == 2.0)
108  
        score = calcScore();
109  
      return score;
110  
    }
111  
    
112  
    double calcScore() {
113  
      return diff(originalImage, getImage());
114  
    }
115  
    
116  
    boolean isBetterThan(Params p) {
117  
      return getScore() < p.getScore();
118  
    }
119  
  }
120  
  
121  
  static class Box extends Overlay {
122  
    double cx, cy, w, h;
123  
    RGB color;
124  
125  
    Box copy() {
126  
      Box p = new Box();
127  
      p.cx = cx;
128  
      p.cy = cy;
129  
      p.w = w;
130  
      p.h = h;
131  
      p.color = color;
132  
      return p;
133  
    }
134  
    
135  
    public String toString() {
136  
      return "Box " + cx + " " + cy + " " + w + " " + h + " " + color;
137  
    }
138  
139  
    void renderOn(Img image) {
140  
      box(image, this);
141  
    }
142  
    
143  
    void vary() {
144  
      int s = random(5);
145  
      if (s == 0)
146  
        cx = vary01(cx);
147  
      else if (s == 1)
148  
        cy = vary01(cy);
149  
      else if (s == 2)
150  
        w = vary01(w);
151  
      else if (s == 3)
152  
        h = vary01(h);
153  
      else
154  
        color = varyColor(color);
155  
    }
156  
  }
157  
  
158  
  static class Solid extends Overlay {
159  
    RGB col;
160  
    
161  
    *() {}
162  
    *(RGB *col) {}
163  
    
164  
    Solid copy() {
165  
      new Solid p;
166  
      p.col = col;
167  
      return p;
168  
    }
169  
    
170  
    public String toString() {
171  
      return "Solid " + col;
172  
    }
173  
174  
    void renderOn(Img image) {
175  
      int w = image.getWidth(), h = image.getHeight();
176  
      for (int y = 0; y < h; y++)
177  
        for (int x = 0; x < w; x++)
178  
          image.setPixel(x, y, col);
179  
    }
180  
    
181  
    void vary() {
182  
      col = varyColor(col);
183  
    }
184  
  }
185  
  
186  
  interface Reproducer {
187  
    public Params reproduce(RGBImage original);
188  
  }
189  
  
190  
  interface OverlayReproducer {
191  
    public Overlay reproduce(RGBImage original);
192  
  }
193  
  
194  
  static class RandomBox implements OverlayReproducer {
195  
    int n = -1;
196  
    public Overlay reproduce(RGBImage original) {
197  
      ++n;
198  
      new Box p;
199  
      p.cx = random();
200  
      p.cy = random();
201  
      p.w = random()*0.1;
202  
      p.h = random()*0.1;
203  
      if (n % 2 == 0)
204  
        p.color = randomColor();
205  
      else
206  
        p.color = probeRandomPixel(original);
207  
      return p;
208  
    }
209  
  }
210  
  
211  
  static class RandomSolid implements OverlayReproducer {
212  
    int n = -1;
213  
    public Overlay reproduce(RGBImage original) {
214  
      ++n;
215  
      new Solid p;
216  
      if (n % 2 == 0) {
217  
        p.col = randomColor();
218  
      } else {
219  
        p.col = probeRandomPixel(original);
220  
      }
221  
      return p;
222  
    }
223  
  }
224  
  
225  
  static class WhiteSolid implements OverlayReproducer {
226  
    public Overlay reproduce(RGBImage original) {
227  
      Solid p = new Solid();
228  
      p.col = new RGB(Color.white);
229  
      return p;
230  
    }
231  
  }
232  
  
233  
  static class VaryBest implements Reproducer {
234  
    Reproducer base;
235  
    Params best;
236  
    
237  
    VaryBest(Reproducer base) {
238  
      this.base = base;
239  
    }
240  
    
241  
    public Params reproduce(RGBImage original) {
242  
      Params p = base.reproduce(original);
243  
      if (best == null || p.isBetterThan(best))
244  
        best = p;
245  
      Params variation = (Params) best.copyVary();
246  
      //System.out.println("Best: " + best.getScore() + ", variation: " + variation.getScore());
247  
      if (variation.isBetterThan(best)) {
248  
        //System.out.println("Using variation, diff=" + (best.getScore()-variation.getScore()));
249  
        best = variation;
250  
      }
251  
      return best;
252  
    }
253  
    
254  
    void reset() {
255  
      best = null;
256  
    }
257  
  }
258  
  
259  
  static class Layered extends Params {
260  
    Layers myMaker;
261  
    Overlay[] list;
262  
    
263  
    Layered(Layers myMaker, Overlay... list) {
264  
      this.myMaker = myMaker;
265  
      this.list = list;
266  
    }
267  
    
268  
    Layered copy() {
269  
      Layered p = new Layered(myMaker, new Overlay[list.length]);
270  
      baseClone(p);
271  
      for (int i = 0; i < list.length; i++)
272  
        p.list[i] = (Overlay) list[i].copy();
273  
      return p;
274  
    }
275  
    
276  
    public String toString() {
277  
      StringBuilder buf = new StringBuilder("layered{");
278  
      for (int i = 0; i < list.length; i++) {
279  
        if (i != 0)
280  
          buf.append(", ");
281  
        buf.append(list[i]);
282  
      }
283  
      return buf + "}";
284  
    }
285  
286  
    RGBImage render() {
287  
      RGBImage image = new RGBImage(originalImage.getWidth(), originalImage.getHeight(), Color.white);
288  
      Painting img = new Painting(image);
289  
      for (int i = 0; i < list.length; i++)
290  
        list[i].renderOn(img);
291  
      return image;
292  
    }
293  
    
294  
    void vary() {
295  
      int i = random(list.length);
296  
      if (random(2) == 0 || myMaker == null) {
297  
        //System.out.println("Varying layer " + i);
298  
        list[i] = (Overlay) list[i].copyVary();
299  
      } else {
300  
        //double score = getScore();
301  
        OverlayReproducer maker = myMaker.list[i];
302  
        list[i] = maker.reproduce(originalImage);
303  
        //System.out.println("Exchanging layer " + i + " from " + maker + ", improvement: " + (score-getFreshScore()));
304  
      }
305  
    }
306  
  }
307  
308  
  static class Layers implements Reproducer {
309  
    OverlayReproducer[] list;
310  
    long ntry = -1;
311  
    int stepTime = 0/*500*/;
312  
    VaryBest varyBest = new VaryBest(this);
313  
    
314  
    Layers(OverlayReproducer... list) {
315  
      this.list = list;
316  
    }
317  
    
318  
    Layers add(int n, Class<? extends OverlayReproducer> xClass) ctex {
319  
      OverlayReproducer l[] = new OverlayReproducer[list.length+n];
320  
      System.arraycopy(list, 0, l, 0, list.length);
321  
      for (int i = 0; i < n; i++)
322  
        l[list.length+i] = xClass.newInstance();
323  
      list = l;
324  
      return this;
325  
    }
326  
    
327  
    public Params reproduce(RGBImage original) {
328  
      ++ntry;
329  
      int n = this.list.length;
330  
      if (stepTime != 0) {
331  
        // build up image gradually to optimize lower layers first
332  
        n = (int) Math.min(n, ntry/stepTime+1);
333  
        varyBest.reset();
334  
      }
335  
      Overlay[] list = new Overlay[n];
336  
      for (int i = 0; i < n; i++)
337  
        list[i] = this.list[i].reproduce(original);
338  
      Layered result = new Layered(this, list);
339  
      result.originalImage = original;
340  
      return result;
341  
    }
342  
  }
343  
  
344  
  static Params reproduce(RGBImage original) {
345  
    int w = original.getWidth(), h = original.getHeight();
346  
    return reproducer.reproduce(original);
347  
  }
348  
  
349  
  static class OptimizeIndividual implements Reproducer {
350  
    OverlayReproducer producer;
351  
    double bestScore;
352  
    Overlay best;
353  
    
354  
    *(OverlayReproducer *producer) {}
355  
356  
    public Params reproduce(RGBImage original) {
357  
      Overlay overlay = producer.reproduce(original);
358  
      double score = scoreOverlay(overlay, original);
359  
      if (best == null || score <= bestScore) {
360  
        best = overlay;
361  
        bestScore = score;
362  
      }
363  
      Layered result = new Layered(null, new Solid(new RGB(Color.white)), best);
364  
      result.originalImage = original;
365  
      return result;
366  
    }
367  
  }
368  
  
369  
  static double scoreOverlay(Overlay overlay, RGBImage original) {
370  
    Diffing d = new Diffing(original);
371  
    overlay.renderOn(d);
372  
    return d.getScore();
373  
  }
374  
375  
  psvm {
376  
    String imageID = "#1000332"; // Picture of two coins
377  
    
378  
    for (int i = 0; i < args.length; i++) {
379  
      String arg = args[i];
380  
      if (arg.equals("width"))
381  
        imageWidth = Integer.parseInt(args[++i]);
382  
      else if (isSnippetID(arg))
383  
        imageID = arg;
384  
    }
385  
    
386  
    final String _imageID = imageID;
387  
    
388  
    JFrame frame = new JFrame("A JavaX Frame");
389  
    
390  
    JPanel grid = new JPanel(new GridLayout(2, 1));
391  
    
392  
    final ImageSurface imageSurface = new ImageSurface();
393  
    final ImageSurface original = new ImageSurface();
394  
    grid.add(imageSurface);
395  
    grid.add(original);
396  
    
397  
    frame.add(grid);
398  
    frame.setBounds(100, 100, 100+imageWidth+20, 300);
399  
    frame.setVisible(true);
400  
    exitOnFrameClose(frame);
401  
    
402  
    new Thread() {
403  
      public void run() {
404  
        originalImage = loadImage(_imageID);
405  
        originalImage = resizeToWidth(originalImage, imageWidth);
406  
        original.setImage(originalImage);
407  
        
408  
        reproduceOpenEnd(originalImage, imageSurface);
409  
      }
410  
    }.start();
411  
  }
412  
  
413  
  static void reproduceOpenEnd(RGBImage original, ImageSurface imageSurface) {
414  
    Params best = null;
415  
    long lastPrint = 0, lastN = 0;
416  
    for (long ntry = 1; ; ntry++) {
417  
      long now = System.currentTimeMillis();
418  
      if (now >= lastPrint+1000) {
419  
        long tps = (ntry-lastN)*1000/(now-lastPrint);
420  
        lastPrint = now;
421  
        lastN = ntry;
422  
        String s = "Try " + ntry + " (" + tps + "/s)";
423  
        if (best == null)
424  
          System.out.println(s);
425  
        else {
426  
          System.out.println("Best: " + best);
427  
          System.out.println(s + ", score: " + formatDouble(best.getScore()*100, 2) + "%, structure size: " + structureSize(best, Params.class));
428  
        }
429  
      }
430  
      Params p = reproduce(original);
431  
      if (best == null || p != null && p.getScore() < best.getScore()) {
432  
        //System.out.println("New best! " + p.getScore());
433  
        best = p;
434  
        imageSurface.setImage(p.getImage());
435  
      }
436  
      
437  
      if (p != null && p.getScore() == 0.0)
438  
        break;
439  
    }
440  
  }
441  
  
442  
  static void box(Img img, Box p) {
443  
    int w = img.getWidth(), h = img.getHeight();
444  
    double x1 = normalize(p.cx-p.w), x2 = normalize(p.cx+p.w);
445  
    double y1 = normalize(p.cy-p.h), y2 = normalize(p.cy+p.h);
446  
    int xx1 = round(x1*(w-1)), xx2 = round(x2*(w-1));
447  
    int yy1 = round(y1*(h-1)), yy2 = round(y2*(h-1));
448  
    
449  
    for (int yy = yy1; yy <= yy2; yy++)
450  
      for (int xx = xx1; xx <= xx2; xx++)
451  
        img.setPixel(xx, yy, p.color);
452  
  }
453  
  
454  
  !include #1000522  
455  
}

Author comment

Began life as a copy of #724

download  show line numbers  debug dex  old transpilations   

Travelled to 16 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, teubizvjbppd, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #725
Snippet name: Reproducing with boxes v2 (with individual diffs, developing)
Eternal ID of this version: #725/1
Text MD5: 27793811e786eb0b192ee9eb12accb29
Author: stefan
Category:
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-08-10 18:06:04
Source code size: 12214 bytes / 455 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 542 / 537
Referenced in: [show references]