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

367
LINES

< > BotCompany Repo | #724 // Reproducing with boxes

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

Libraryless. Click here for Pure Java version (8633L/57K/207K).

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

Author comment

Began life as a copy of #671

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #724
Snippet name: Reproducing with boxes
Eternal ID of this version: #724/2
Text MD5: 1956f845025d299caeeff78cf968c0f4
Transpilation MD5: 4bf9f0b903b28d9af03f523d00816e8c
Author: stefan
Category:
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-05-06 16:26:21
Source code size: 9043 bytes / 367 lines
Pitched / IR pitched: No / No
Views / Downloads: 675 / 736
Version history: 1 change(s)
Referenced in: [show references]