An International Platform for perspectives that transcend the traditional Divides between the Humanities and stem    

Wandering Elephant

Wandering Elephant

elephant.jpg

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;
       }
   }
Lounging Panda

Lounging Panda

Prowling Bear

Prowling Bear