Wandering Elephant
Computer program performs Breadth-First-Search to find color patches in an image and replaces those patches with a pattern along with a corresponding color. The original Github repository can be found here: https://github.com/BitLorax/blackbox/blob/master/src/Main.java
Appendix (Computer Program)
import java.awt.*;import java.io.*;import java.awt.image.BufferedImage;import java.util.*;import javax.imageio.ImageIO;import javax.swing.*;public class Main {   private static String refPath = "";   private static String compPath = "database";   private static int INF = 200000000;   private static int PIC_CNT = 5640;   private static int[][] MAX_RANGE = {{70, 50}, {50, 20}}; //{base, deviation}   private static int MAX_HSIZE = 300;   private static int LIM = 110;   private static int[] dx = {0, 1, 0, -1};   private static int[] dy = {-1, 0, 1, 0};   private static int width, height;   private static BufferedImage ref, collage, sections;   private static boolean[][] visited;   private static File fRef;   private static File[] imgs;   private static Color[] avgs = new Color[PIC_CNT + 1];   private static JFrame f = new JFrame();   private static JLabel jl;   private static JFrame fS = new JFrame();   private static JLabel jSL;   public static void main(String[] args) {       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       fS.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       Scanner sc = new Scanner(System.in);       refPath = sc.nextLine();       try {           fRef = new File(refPath);           ref = ImageIO.read(fRef);           System.out.println("Loading success");       } catch (IOException e) {           System.out.println("Loading failed");           return;       }       width = ref.getWidth(); height = ref.getHeight();       visited = new boolean[width + 1][height + 1];       try {           File f = new File(compPath); imgs = f.listFiles();           PIC_CNT = imgs.length;           BufferedReader in = new BufferedReader(new FileReader("src/avgs.txt"));           for (int i = 0; i < PIC_CNT; i++) {               StringTokenizer st = new StringTokenizer(in.readLine());               avgs[i] = new Color(Integer.parseInt(st.nextToken()),                                 Integer.parseInt(st.nextToken()),                                 Integer.parseInt(st.nextToken()));           }       } catch (IOException e) {           System.out.println("Failed to load avgs.txt");           return;       }       collage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);       sections = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);       jl = new JLabel(new ImageIcon(collage));       jSL = new JLabel(new ImageIcon(sections));       f.getContentPane().add(jl); fS.getContentPane().add(jSL);       f.pack(); fS.pack();       f.setVisible(true); fS.setVisible(true);       System.out.println("Generating collage");       try {           boolean d = false;           while (!d) {               d = true;               for (int i = 0; i < width; i++) {                   for (int j = 0; j < height; j++) {                       if (!visited[i][j]) {                           bfs(new Coord(i, j));                           d = false;                       }                   }               }           }       } catch (IOException e) {           System.out.println("Failed to generate collage");           return;       }       System.out.println();       System.out.print("Save? (y/n) ");       String s = sc.nextLine();       if (s.equals("y")) {           File out = new File("out/production/artwork/" + fRef.getName());           try {               ImageIO.write(collage, "jpg", out);               System.out.println("Saving success");           } catch (IOException e) {               System.out.println("Saving failed");           }       }   }   static void bfs(Coord s) throws IOException {       ArrayList<Coord> pixels = new ArrayList<>();       int[] sum = {0, 0, 0};       Coord tl = new Coord(INF, INF), br = new Coord(-INF, -INF);       int k = (int)(Math.random() * MAX_RANGE.length);       int size = 0;       Queue<Coord> q = new LinkedList<>();       q.add(s);       while (!q.isEmpty()) {           Coord cur = q.remove();           if (visited[cur.x][cur.y]) continue;           if (getDist(s, cur) > MAX_RANGE[k][0] + Math.random() * (MAX_RANGE[k][1])) continue;           System.out.print("\r");           System.out.print(size);           tl.x = Math.min(tl.x, cur.x); tl.y = Math.min(tl.y, cur.y);           br.x = Math.max(br.x, cur.x); br.y = Math.max(br.y, cur.y);           Color curC = new Color(ref.getRGB(cur.x, cur.y));           size++; pixels.add(cur);           changeVisited(cur.x, cur.y, true);           sum[0] += curC.getRed();           sum[1] += curC.getGreen();           sum[2] += curC.getBlue();           outer : for (int i = 0; i < 4; i++) {               Coord next = new Coord(cur.x + dx[i], cur.y + dy[i]);               if (next.x < 0 || next.x >= width || next.y < 0 || next.y >= height) continue;               if (visited[next.x][next.y]) continue;               for (Coord p : pixels)                   if (diff(new Color(ref.getRGB(next.x, next.y)), new Color(ref.getRGB(p.x, p.y))) > LIM)                       continue outer;               q.add(next);           }       }       //fill small holes       for (int i = tl.x; i <= br.x; i++) {           outer : for (int j = tl.y; j <= br.y; j++) {               ArrayList<Coord> hPixels = new ArrayList<>();               if (visited[i][j]) continue;               int hSize = 0;               q = new LinkedList<>();               q.add(new Coord(i, j));               while (!q.isEmpty()) {                   Coord cur = q.remove();                   if (cur.x < 0 || cur.x >= width || cur.y < 0 || cur.y >= height) continue;                   if (visited[cur.x][cur.y]) continue;                   hSize++;                   hPixels.add(cur);                   changeVisited(cur.x, cur.y, true);                   if (hSize > MAX_HSIZE) {                       for (Coord p : hPixels) {                           changeVisited(p.x, p.y, false);                       }                       continue outer;                   }                   for (int l = 0; l < 4; l++) {                       q.add(new Coord(cur.x + dx[l], cur.y + dy[l]));                   }               }               for (Coord p : hPixels) {                   pixels.add(p);               }           }       }       Color avg = new Color(sum[0] / size, sum[1] / size, sum[2] / size);       BufferedImage img = ImageIO.read(imgs[getPic(avg)]);       Coord shift = new Coord(0, 0);       shift.x = (int)(Math.random() * Math.max(0, img.getWidth() - br.x - 1));       shift.y = (int)(Math.random() * Math.max(0, img.getHeight() - br.y - 1));       for (Coord p : pixels) {           Coord mapped = new Coord(p.x - tl.x + shift.x, p.y - tl.y + shift.y);           if (mapped.x >= img.getWidth() || mapped.y >= img.getHeight() || mapped.x < 0 || mapped.y < 0)               changeVisited(p.x, p.y, false);           else collage.setRGB(p.x, p.y, img.getRGB(mapped.x, mapped.y));       }       jl.setIcon(new ImageIcon(collage));       jSL.setIcon(new ImageIcon(sections));   }   static int getPic(Color avg) {       int ret = 0;       for (int i = 0; i < PIC_CNT; i++)           if (diff(avgs[i], avg) < diff(avgs[ret], avg)) ret = i;       return ret;   }   static int getDist(Coord a, Coord b) {       return (int)Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));   }   static int diff(Color a, Color b) {       return Math.abs(a.getRed() - b.getRed()) +              Math.abs(a.getGreen() - b.getGreen()) +              Math.abs(a.getBlue() - b.getBlue());   }   static void changeVisited(int x, int y, boolean s) {       visited[x][y] = s;       sections.setRGB(x, y, ((s) ? 16077122 : 0));   }   static class Coord {       int x, y;       Coord(int a, int b) {           x = a; y = b;       }   }
 
             
      