Advertisement
Elandiro

G&A 3

Apr 20th, 2013
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.85 KB | None | 0 0
  1. package gna;
  2.  
  3. import java.awt.Point;
  4. import java.util.HashSet;
  5. import java.util.Iterator;
  6. import java.util.LinkedList;
  7. import java.util.PriorityQueue;
  8. import java.util.Queue;
  9.  
  10. /**
  11. * Implement the methods stitch, seam and floodfill.
  12. *
  13. * @author Michael Claes
  14. */
  15. public class Stitcher {
  16.  
  17. public static final int IMAGE1 = 0;
  18. public static final int IMAGE2 = 1;
  19. public static final int SEAM = 2;
  20.  
  21. private int[][] mask;
  22.  
  23. /**
  24. * Return the sequence of positions on the seam. The first position in the
  25. * sequence is (0, 0) and the last is (width - 1, height - 1). Each position
  26. * on the seam must be adjacent to its predecessor and successor (if any).
  27. * Positions that are diagonally adjacent are considered adjacent.
  28. *
  29. * <code>image1</code> and <code>image2</code> are both non-null and have
  30. * equal dimensions.
  31. */
  32. public Iterable<Position> seam(int[][] image1, int[][] image2) {
  33. LinkedList<Position> linkList = new LinkedList<Position>();
  34. Position first = new Position(0, 0);
  35. int width = image1.length, height = image1[0].length;
  36. Position last = new Position(width - 1, height - 1);
  37. Position current = first;
  38. HashSet<Position> checked = new HashSet<Position>();
  39. ColorCodeComparator colorComp = new ColorCodeComparator();
  40. PriorityQueue<Position> pq = new PriorityQueue<>(10, colorComp);
  41.  
  42. while (!current.equals(last)) {
  43. Iterator<Position> adjacentIterator = current.getAdjacent(last,
  44. image1, image2).iterator();
  45. while (adjacentIterator.hasNext()) {
  46. Position next = adjacentIterator.next();
  47. if (!checked.contains(next) && !pq.contains(next)) {
  48. pq.offer(next);
  49. }
  50. }
  51. checked.add(current);
  52. current = pq.poll();
  53. }
  54. // als einde bereikt is wordt de seam ingevuld in linkList en
  55. // teruggegeven
  56. linkList.addFirst(current);
  57. while (linkList.peek().getPrevious() != null) {
  58. linkList.addFirst(linkList.peek().getPrevious());
  59. }
  60. return linkList;
  61. }
  62.  
  63. /**
  64. * Apply the floodfill algorithm described in the assignment to mask. You
  65. * can assume the mask contains a seam from the upper left corner to the
  66. * bottom right corner.
  67. */
  68. public void floodfill(int[][] mask) {
  69.  
  70. Queue<Point> queue = new LinkedList<Point>();
  71. queue.add(new Point(0, mask[0].length - 1));
  72.  
  73. while (!queue.isEmpty()) {
  74. Point p = queue.poll();
  75. if (mask[p.x][p.y] == 0) {
  76. mask[p.x][p.y] = 1;
  77.  
  78. Point p1 = null, p2 = null, p3 = null, p4 = null;
  79.  
  80. try {
  81. if (p.x - 1 < 0) {
  82. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  83. throw (e);
  84. }
  85. p1 = new Point(p.x - 1, p.y);
  86. } catch (ArrayIndexOutOfBoundsException e) {
  87. }
  88. try {
  89. if (p.x + 1 >= mask.length) {
  90. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  91. throw (e);
  92. }
  93. p2 = new Point(p.x + 1, p.y);
  94. } catch (ArrayIndexOutOfBoundsException e) {
  95. }
  96. try {
  97. if (p.y - 1 < 0) {
  98. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  99. throw (e);
  100. }
  101. p3 = new Point(p.x, p.y - 1);
  102. } catch (ArrayIndexOutOfBoundsException e) {
  103. }
  104. try {
  105. if (p.y + 1 >= mask[0].length) {
  106. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  107. throw (e);
  108. }
  109. p4 = new Point(p.x, p.y + 1);
  110. } catch (ArrayIndexOutOfBoundsException e) {
  111. }
  112. if (!(p1 == null))
  113. queue.add(p1);
  114. if (!(p2 == null))
  115. queue.add(p2);
  116. if (!(p3 == null))
  117. queue.add(p3);
  118. if (!(p4 == null))
  119. queue.add(p4);
  120.  
  121. }
  122. }
  123. }
  124.  
  125. /**
  126. * Return the mask to stitch two images together. The seam runs from the
  127. * upper left to the lower right corner, with the rightmost part coming from
  128. * the first image. A pixel in the mask is 0 on the places where
  129. * <code>img1</code> should be used, and 1 where <code>img2</code> should be
  130. * used. On the seam record a value of 2.
  131. *
  132. * ImageCompositor will only call this method (not seam and floodfill) to
  133. * stitch two images.
  134. *
  135. * <code>image1</code> and <code>image2</code> are both non-null and have
  136. * equal dimensions.
  137. */
  138. public int[][] stitch(int[][] image1, int[][] image2) {
  139. // use seam and floodfill to implement this method
  140. mask = new int[image1.length][image1[0].length];
  141. LinkedList<Position> linkList = new LinkedList<Position>();
  142. long first = System.currentTimeMillis();
  143. linkList = (LinkedList<Position>) seam(image1, image2);
  144. long time = System.currentTimeMillis() - first;
  145. System.out.println("Seam works! It takes " + time / 1000 + " seconds.");
  146. Position current = null;
  147.  
  148. while (!linkList.isEmpty()) {
  149. current = linkList.poll();
  150. int x, y;
  151. x = current.getX();
  152. y = current.getY();
  153. mask[x][y] = 2;
  154. System.out.println("x: " + x + " y: " + y);
  155. }
  156.  
  157. floodfill(mask);
  158.  
  159. return mask;
  160. }
  161. }
  162.  
  163. package gna;
  164.  
  165. import java.util.ArrayList;
  166.  
  167. public class Position {
  168. private final int x, y, totalCost;
  169. private final Position previous;
  170.  
  171. public Position(int x, int y) {
  172. this(x, y, 0, null);
  173. }
  174.  
  175. public Position(int x, int y, int totalCost, Position previous) {
  176. this.x = x;
  177. this.y = y;
  178. this.totalCost = totalCost;
  179. this.previous = previous;
  180. }
  181.  
  182. public int getX() {
  183. return x;
  184. }
  185.  
  186. public int getY() {
  187. return y;
  188. }
  189.  
  190. public int getTotalCost() {
  191. return totalCost;
  192. }
  193.  
  194. public Position getPrevious() {
  195. return previous;
  196. }
  197.  
  198. public boolean isAdjacentTo(Position other) {
  199. return Math.abs(x - other.x) <= 1 && Math.abs(y - other.y) <= 1
  200. && !this.equals(other);
  201. }
  202.  
  203. @Override
  204. public int hashCode() {
  205. final int prime = 31;
  206. int result = 1;
  207. result = prime * result + x;
  208. result = prime * result + y;
  209. return result;
  210. }
  211.  
  212. @Override
  213. public boolean equals(Object obj) {
  214. if (this == obj)
  215. return true;
  216. if (obj == null)
  217. return false;
  218. if (getClass() != obj.getClass())
  219. return false;
  220. Position other = (Position) obj;
  221. if (x != other.x)
  222. return false;
  223. if (y != other.y)
  224. return false;
  225. return true;
  226. }
  227.  
  228. public Iterable<Position> getAdjacent(Position last, int[][] image1,
  229. int[][] image2) {
  230. ArrayList<Position> adjacent = new ArrayList<Position>();
  231. int currentX = this.getX();
  232. int currentY = this.getY();
  233.  
  234. try {
  235. if (currentX - 1 < 0) {
  236. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  237. throw e;
  238. }
  239. Position left = new Position(currentX - 1, currentY,
  240. this.getTotalCost()
  241. + ImageCompositor.pixelSqDistance(
  242. image1[currentX - 1][currentY],
  243. image2[currentX - 1][currentY]), this);
  244. adjacent.add(left);
  245. } catch (ArrayIndexOutOfBoundsException e) {
  246. }
  247. try {
  248. if (currentX + 1 > last.getX()) {
  249. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  250. throw e;
  251. }
  252. Position right = new Position(currentX + 1, currentY,
  253. this.getTotalCost()
  254. + ImageCompositor.pixelSqDistance(
  255. image1[currentX + 1][currentY],
  256. image2[currentX + 1][currentY]), this);
  257. adjacent.add(right);
  258. } catch (ArrayIndexOutOfBoundsException e) {
  259. }
  260. try {
  261. if (currentY - 1 < 0) {
  262. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  263. throw e;
  264. }
  265. Position up = new Position(currentX, currentY - 1,
  266. this.getTotalCost()
  267. + ImageCompositor.pixelSqDistance(
  268. image1[currentX][currentY - 1],
  269. image2[currentX][currentY - 1]), this);
  270. adjacent.add(up);
  271. } catch (ArrayIndexOutOfBoundsException e) {
  272. }
  273. try {
  274. if (currentY + 1 > last.getY()) {
  275. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  276. throw e;
  277. }
  278. Position down = new Position(currentX, currentY + 1,
  279. this.getTotalCost()
  280. + ImageCompositor.pixelSqDistance(
  281. image1[currentX][currentY + 1],
  282. image2[currentX][currentY + 1]), this);
  283. adjacent.add(down);
  284. } catch (ArrayIndexOutOfBoundsException e) {
  285. }
  286. try {
  287. if (currentX - 1 < 0 || currentY - 1 < 0) {
  288. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  289. throw e;
  290. }
  291. Position upperLeft = new Position(currentX - 1, currentY - 1,
  292. this.getTotalCost()
  293. + ImageCompositor.pixelSqDistance(
  294. image1[currentX - 1][currentY - 1],
  295. image2[currentX - 1][currentY - 1]), this);
  296. adjacent.add(upperLeft);
  297. } catch (ArrayIndexOutOfBoundsException e) {
  298. }
  299. try {
  300. if (currentX + 1 > last.getX() || currentY - 1 < 0) {
  301. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  302. throw e;
  303. }
  304. Position upperRight = new Position(currentX + 1, currentY - 1,
  305. this.getTotalCost()
  306. + ImageCompositor.pixelSqDistance(
  307. image1[currentX + 1][currentY - 1],
  308. image2[currentX + 1][currentY - 1]), this);
  309. adjacent.add(upperRight);
  310. } catch (ArrayIndexOutOfBoundsException e) {
  311. }
  312. try {
  313. if (currentX - 1 < 0 || currentY + 1 > last.getY()) {
  314. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  315. throw e;
  316. }
  317. Position lowerLeft = new Position(currentX - 1, currentY + 1,
  318. this.getTotalCost()
  319. + ImageCompositor.pixelSqDistance(
  320. image1[currentX - 1][currentY + 1],
  321. image2[currentX - 1][currentY + 1]), this);
  322. adjacent.add(lowerLeft);
  323. } catch (ArrayIndexOutOfBoundsException e) {
  324. }
  325. try {
  326. if (currentX + 1 > last.getX() || currentY + 1 > last.getY()) {
  327. ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
  328. throw e;
  329. }
  330. Position lowerRight = new Position(currentX + 1, currentY + 1,
  331. this.getTotalCost()
  332. + ImageCompositor.pixelSqDistance(
  333. image1[currentX + 1][currentY + 1],
  334. image2[currentX + 1][currentY + 1]), this);
  335. adjacent.add(lowerRight);
  336. } catch (ArrayIndexOutOfBoundsException e) {
  337. }
  338.  
  339. return adjacent;
  340. }
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement