Search code examples
javaimage-processingpanoramasimage-stitching

Creating walkable N-E-S-W world from photos


I have a set of 100 photos from a 40x40m area outside in the woods.

The 40x40 area was divided up into 10m sections so there are 25 locations where pictures were taken. At each location, a picture was taken facing each of the four compass locations: north, east, south, and west.

Any suggestions on how to go about stitching these photos together, sort of like how google maps lets you walk down the street in street view?

Thanks!


Solution

  • I would store the images in a three-dimensional array like this:

    image[x][y][direction];
    

    Then, use a key or mouse listener to change the x and y position of the viewer. So, for example, if your images are named "0_0_N.jpg" (etc) in the same directory as your class, you might do something like this:

    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    
    public class View {
        private static final char[] DIRECTION_NAME = { 'N', 'E', 'S', 'W' };
        private static final int[] DIRECTION_X = { 0, 1, 0, -1 };
        private static final int[] DIRECTION_Y = { 1, 0, -1, 0 };
        private static final int WIDTH = 5;
        private static final int HEIGHT = 5;
    
        private final JLabel label;
        private final ImageIcon[][][] images;
        private int x;
        private int y;
        private int direction;
    
        public View() throws IOException {
            images = new ImageIcon[WIDTH][HEIGHT][4];
            for(int x = 0; x < WIDTH; x++) {
                for(int y = 0; y < HEIGHT; y++) {
                    for(int direction = 0; direction < 4; ++direction) {
                        String name = x + "_" + y + "_" + DIRECTION_NAME[direction] + ".jpg";
                        images[x][y][direction] = new ImageIcon(ImageIO.read(View.class.getResourceAsStream(name)));
                    }
                }
            }
    
            label = new JLabel();
            label.setIcon(images[0][0][0]);
    
            JFrame frame = new JFrame("View");
            frame.getContentPane().add(label);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
    
            label.addKeyListener(new KeyAdapter() {
                public void keyReleased(KeyEvent e) {
                    switch(e.getKeyCode()) {
                    case KeyEvent.VK_LEFT:
                        direction = (direction + 3) % 4;
                        break;
                    case KeyEvent.VK_RIGHT:
                        direction = (direction + 1) % 4;
                        break;
                    case KeyEvent.VK_UP:
                    {
                        int newX = x + DIRECTION_X[direction];
                        int newY = y + DIRECTION_Y[direction];
                        if(newX >= 0 && newX < WIDTH && newY >= 0 && newY < HEIGHT) {
                            x = newX;
                            y = newY;
                        }
                        break;
                    }
                    }
                    label.setIcon(images[x][y][direction]);
                }
            });
            label.requestFocus();
        }
    
        public static void main(String[] args) throws IOException {
            new View();
        }
    }