Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package gna;
- import java.awt.Point;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.LinkedList;
- import java.util.PriorityQueue;
- import java.util.Queue;
- /**
- * Implement the methods stitch, seam and floodfill.
- *
- * @author Michael Claes
- */
- public class Stitcher {
- public static final int IMAGE1 = 0;
- public static final int IMAGE2 = 1;
- public static final int SEAM = 2;
- private int[][] mask;
- /**
- * Return the sequence of positions on the seam. The first position in the
- * sequence is (0, 0) and the last is (width - 1, height - 1). Each position
- * on the seam must be adjacent to its predecessor and successor (if any).
- * Positions that are diagonally adjacent are considered adjacent.
- *
- * <code>image1</code> and <code>image2</code> are both non-null and have
- * equal dimensions.
- */
- public Iterable<Position> seam(int[][] image1, int[][] image2) {
- LinkedList<Position> linkList = new LinkedList<Position>();
- Position first = new Position(0, 0);
- int width = image1.length, height = image1[0].length;
- Position last = new Position(width - 1, height - 1);
- Position current = first;
- HashSet<Position> checked = new HashSet<Position>();
- ColorCodeComparator colorComp = new ColorCodeComparator();
- PriorityQueue<Position> pq = new PriorityQueue<>(10, colorComp);
- while (!current.equals(last)) {
- Iterator<Position> adjacentIterator = current.getAdjacent(last,
- image1, image2).iterator();
- while (adjacentIterator.hasNext()) {
- Position next = adjacentIterator.next();
- if (!checked.contains(next) && !pq.contains(next)) {
- pq.offer(next);
- }
- }
- checked.add(current);
- current = pq.poll();
- }
- // als einde bereikt is wordt de seam ingevuld in linkList en
- // teruggegeven
- linkList.addFirst(current);
- while (linkList.peek().getPrevious() != null) {
- linkList.addFirst(linkList.peek().getPrevious());
- }
- return linkList;
- }
- /**
- * Apply the floodfill algorithm described in the assignment to mask. You
- * can assume the mask contains a seam from the upper left corner to the
- * bottom right corner.
- */
- public void floodfill(int[][] mask) {
- Queue<Point> queue = new LinkedList<Point>();
- queue.add(new Point(0, mask[0].length - 1));
- while (!queue.isEmpty()) {
- Point p = queue.poll();
- if (mask[p.x][p.y] == 0) {
- mask[p.x][p.y] = 1;
- Point p1 = null, p2 = null, p3 = null, p4 = null;
- try {
- if (p.x - 1 < 0) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw (e);
- }
- p1 = new Point(p.x - 1, p.y);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (p.x + 1 >= mask.length) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw (e);
- }
- p2 = new Point(p.x + 1, p.y);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (p.y - 1 < 0) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw (e);
- }
- p3 = new Point(p.x, p.y - 1);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (p.y + 1 >= mask[0].length) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw (e);
- }
- p4 = new Point(p.x, p.y + 1);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- if (!(p1 == null))
- queue.add(p1);
- if (!(p2 == null))
- queue.add(p2);
- if (!(p3 == null))
- queue.add(p3);
- if (!(p4 == null))
- queue.add(p4);
- }
- }
- }
- /**
- * Return the mask to stitch two images together. The seam runs from the
- * upper left to the lower right corner, with the rightmost part coming from
- * the first image. A pixel in the mask is 0 on the places where
- * <code>img1</code> should be used, and 1 where <code>img2</code> should be
- * used. On the seam record a value of 2.
- *
- * ImageCompositor will only call this method (not seam and floodfill) to
- * stitch two images.
- *
- * <code>image1</code> and <code>image2</code> are both non-null and have
- * equal dimensions.
- */
- public int[][] stitch(int[][] image1, int[][] image2) {
- // use seam and floodfill to implement this method
- mask = new int[image1.length][image1[0].length];
- LinkedList<Position> linkList = new LinkedList<Position>();
- long first = System.currentTimeMillis();
- linkList = (LinkedList<Position>) seam(image1, image2);
- long time = System.currentTimeMillis() - first;
- System.out.println("Seam works! It takes " + time / 1000 + " seconds.");
- Position current = null;
- while (!linkList.isEmpty()) {
- current = linkList.poll();
- int x, y;
- x = current.getX();
- y = current.getY();
- mask[x][y] = 2;
- System.out.println("x: " + x + " y: " + y);
- }
- floodfill(mask);
- return mask;
- }
- }
- package gna;
- import java.util.ArrayList;
- public class Position {
- private final int x, y, totalCost;
- private final Position previous;
- public Position(int x, int y) {
- this(x, y, 0, null);
- }
- public Position(int x, int y, int totalCost, Position previous) {
- this.x = x;
- this.y = y;
- this.totalCost = totalCost;
- this.previous = previous;
- }
- public int getX() {
- return x;
- }
- public int getY() {
- return y;
- }
- public int getTotalCost() {
- return totalCost;
- }
- public Position getPrevious() {
- return previous;
- }
- public boolean isAdjacentTo(Position other) {
- return Math.abs(x - other.x) <= 1 && Math.abs(y - other.y) <= 1
- && !this.equals(other);
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + x;
- result = prime * result + y;
- return result;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Position other = (Position) obj;
- if (x != other.x)
- return false;
- if (y != other.y)
- return false;
- return true;
- }
- public Iterable<Position> getAdjacent(Position last, int[][] image1,
- int[][] image2) {
- ArrayList<Position> adjacent = new ArrayList<Position>();
- int currentX = this.getX();
- int currentY = this.getY();
- try {
- if (currentX - 1 < 0) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw e;
- }
- Position left = new Position(currentX - 1, currentY,
- this.getTotalCost()
- + ImageCompositor.pixelSqDistance(
- image1[currentX - 1][currentY],
- image2[currentX - 1][currentY]), this);
- adjacent.add(left);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (currentX + 1 > last.getX()) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw e;
- }
- Position right = new Position(currentX + 1, currentY,
- this.getTotalCost()
- + ImageCompositor.pixelSqDistance(
- image1[currentX + 1][currentY],
- image2[currentX + 1][currentY]), this);
- adjacent.add(right);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (currentY - 1 < 0) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw e;
- }
- Position up = new Position(currentX, currentY - 1,
- this.getTotalCost()
- + ImageCompositor.pixelSqDistance(
- image1[currentX][currentY - 1],
- image2[currentX][currentY - 1]), this);
- adjacent.add(up);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (currentY + 1 > last.getY()) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw e;
- }
- Position down = new Position(currentX, currentY + 1,
- this.getTotalCost()
- + ImageCompositor.pixelSqDistance(
- image1[currentX][currentY + 1],
- image2[currentX][currentY + 1]), this);
- adjacent.add(down);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (currentX - 1 < 0 || currentY - 1 < 0) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw e;
- }
- Position upperLeft = new Position(currentX - 1, currentY - 1,
- this.getTotalCost()
- + ImageCompositor.pixelSqDistance(
- image1[currentX - 1][currentY - 1],
- image2[currentX - 1][currentY - 1]), this);
- adjacent.add(upperLeft);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (currentX + 1 > last.getX() || currentY - 1 < 0) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw e;
- }
- Position upperRight = new Position(currentX + 1, currentY - 1,
- this.getTotalCost()
- + ImageCompositor.pixelSqDistance(
- image1[currentX + 1][currentY - 1],
- image2[currentX + 1][currentY - 1]), this);
- adjacent.add(upperRight);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (currentX - 1 < 0 || currentY + 1 > last.getY()) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw e;
- }
- Position lowerLeft = new Position(currentX - 1, currentY + 1,
- this.getTotalCost()
- + ImageCompositor.pixelSqDistance(
- image1[currentX - 1][currentY + 1],
- image2[currentX - 1][currentY + 1]), this);
- adjacent.add(lowerLeft);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- try {
- if (currentX + 1 > last.getX() || currentY + 1 > last.getY()) {
- ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
- throw e;
- }
- Position lowerRight = new Position(currentX + 1, currentY + 1,
- this.getTotalCost()
- + ImageCompositor.pixelSqDistance(
- image1[currentX + 1][currentY + 1],
- image2[currentX + 1][currentY + 1]), this);
- adjacent.add(lowerRight);
- } catch (ArrayIndexOutOfBoundsException e) {
- }
- return adjacent;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement