Advertisement
Guest User

Untitled

a guest
Jun 25th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.15 KB | None | 0 0
  1. package assignment07;
  2.  
  3. import ij.IJ;
  4. import ij.ImagePlus;
  5. import ij.gui.Overlay;
  6. import ij.gui.Roi;
  7. import ij.gui.ShapeRoi;
  8. import ij.plugin.filter.PlugInFilter;
  9. import ij.process.FloatProcessor;
  10. import ij.process.ImageProcessor;
  11. import javafx.util.Pair;
  12.  
  13. import java.awt.*;
  14. import java.util.ArrayList;
  15. import java.util.Collections;
  16. import java.util.Comparator;
  17. import java.util.List;
  18. import java.util.stream.Collectors;
  19.  
  20. // Linear and normalized did not produce good results. Euclidean worked reliably on Ramses image and PCB image.
  21. // Running time highly depends on the size of the area of interest.
  22. public class Correlation_Based_Matching implements PlugInFilter {
  23. private static final int LIMIT_OF_MARKS = 7;
  24. @Override
  25. public int setup(String s, ImagePlus imagePlus) {
  26. return DOES_8G + DOES_8C + NO_CHANGES;
  27. }
  28.  
  29. @Override
  30. public void run(ImageProcessor ip) {
  31. ImageProcessor reference = ip.crop();
  32. if (reference.getPixelCount() == ip.getPixelCount()) {
  33. IJ.error("Please select area for the reference image");
  34. return;
  35. }
  36.  
  37. (new ImagePlus("Reference image", reference)).show();
  38.  
  39. FloatProcessor img = ip.convertToFloatProcessor();
  40. FloatProcessor ref = reference.convertToFloatProcessor();
  41.  
  42. float[][] imgArr = img.getFloatArray();
  43. float[][] refArr = ref.getFloatArray();
  44.  
  45. float[][] sqrDiffSumScore = testAndDrawCorrelation(SQR_DIFF_SUM, refArr, imgArr, "Sqr Diff Sum");
  46. List<Pair<Integer, Integer>> sqrDiffExtremas = findLocalExtrema(sqrDiffSumScore, LIMIT_OF_MARKS, true);
  47. displayLocalExtrema(sqrDiffExtremas, ip, ref.getWidth(), ref.getHeight(), "Sqr Diff Sum");
  48.  
  49.  
  50. float[][] linearCrossCorrScore = testAndDrawCorrelation(LINEAR_CROSS_CORR, refArr, imgArr, "Linear Cross Corr");
  51. List<Pair<Integer, Integer>> linearCrossCorrExtremas =
  52. findLocalExtrema(linearCrossCorrScore, LIMIT_OF_MARKS, false);
  53. displayLocalExtrema(linearCrossCorrExtremas, ip, ref.getWidth(), ref.getHeight(), "Linear Cross Corr");
  54.  
  55. float[][] normCrossCorrScore = testAndDrawCorrelation(NORM_CROSS_CORR, refArr, imgArr, "Norm Cross Corr");
  56. List<Pair<Integer, Integer>> normCrossCorrExtremas =
  57. findLocalExtrema(normCrossCorrScore, LIMIT_OF_MARKS, false);
  58. displayLocalExtrema(normCrossCorrExtremas, ip, ref.getWidth(), ref.getHeight(), "Norm Cross Corr");
  59.  
  60. }
  61.  
  62. private float[][] testAndDrawCorrelation(CorrelationCalculator calculator, float[][] ref, float[][] img, String imgName) {
  63. int scoreRows = img.length - ref.length;
  64. int scoreCols = img[0].length - ref[0].length;
  65.  
  66. IJ.showProgress(0, scoreRows * scoreCols);
  67. float[][] correlationScore = new float[scoreRows][scoreCols];
  68. for (int i = 0; i < scoreRows; i++) {
  69. for (int j = 0; j < scoreCols; j++) {
  70. correlationScore[i][j] = calculator.correlation(ref, img, i, j);
  71. IJ.showProgress(i * scoreCols + j, scoreRows * scoreCols);
  72. }
  73. }
  74. FloatProcessor correlationImageProcessor = new FloatProcessor(correlationScore);
  75. (new ImagePlus(imgName, correlationImageProcessor)).show();
  76. return correlationScore;
  77. }
  78.  
  79. private interface CorrelationCalculator {
  80. float correlation(float[][] ref, float[][] img, int row, int col);
  81. }
  82.  
  83. private static final CorrelationCalculator SQR_DIFF_SUM =
  84. (ref, img, row, col) -> {
  85. float ans = 0;
  86. for (int i = 0; i < ref.length; i++) {
  87. for (int j = 0; j < ref[i].length; j++) {
  88. ans += sqr(img[row + i][col + j] - ref[i][j]);
  89. }
  90. }
  91. return (float) Math.sqrt(ans);
  92. };
  93.  
  94. private static final CorrelationCalculator LINEAR_CROSS_CORR =
  95. (ref, img, row, col) -> {
  96. float ans = 0;
  97. for (int i = 0; i < ref.length; i++) {
  98. for (int j = 0; j < ref[i].length; j++) {
  99. ans += img[row + i][col + j] * ref[i][j];
  100. }
  101. }
  102. return ans;
  103. };
  104.  
  105. private static final CorrelationCalculator NORM_CROSS_CORR =
  106. (ref, img, row, col) -> {
  107. float denRef = 0, denImg = 0;
  108. for (int i = 0; i < ref.length; i++) {
  109. for (int j = 0; j < ref[i].length; j++) {
  110. denRef += sqr(ref[i][j]);
  111. denImg += sqr(img[row + i][col + j]);
  112. }
  113. }
  114. return LINEAR_CROSS_CORR.correlation(ref, img, row, col)
  115. / ((float) Math.sqrt(denRef) * (float) Math.sqrt(denImg));
  116. };
  117.  
  118. private List<Pair<Integer, Integer>> findLocalExtrema(float[][] scores, int limit, boolean isMinima) {
  119. int rows = scores.length;
  120. int cols = scores[0].length;
  121.  
  122. ArrayList<Pair<Integer, Integer>> localExtremas = new ArrayList<>();
  123. for (int i = 0; i < rows; i++) {
  124. for (int j = 0; j < cols; j++) {
  125. boolean isExtrema = true;
  126. for (int di = -1; di <= 1; di++) {
  127. for (int dj = -1; dj <= 1; dj++) {
  128. if (di != 0 || dj != 0) {
  129. int neighb_i = i + di;
  130. int neighb_j = j + dj;
  131. if (0 <= neighb_i && neighb_i < rows && 0 <= neighb_j && neighb_j < cols) {
  132. if (!compare(isMinima, scores[i][j], scores[neighb_i][neighb_j])) {
  133. isExtrema = false;
  134. }
  135. }
  136. }
  137. }
  138. }
  139.  
  140. if (isExtrema) {
  141. localExtremas.add(new Pair<>(i, j));
  142. }
  143. }
  144. }
  145.  
  146. localExtremas =
  147. localExtremas
  148. .stream()
  149. .sorted(Comparator.comparingDouble(p -> scores[p.getKey()][p.getValue()]))
  150. .limit(limit)
  151. .collect(Collectors.toCollection(ArrayList::new));
  152. if (!isMinima) {
  153. Collections.reverse(localExtremas);
  154. }
  155.  
  156. return localExtremas;
  157. }
  158.  
  159. private void displayLocalExtrema(
  160. List<Pair<Integer, Integer>> extremas, ImageProcessor ip, int rectW, int rectH, String imgName) {
  161. Overlay oly = new Overlay();
  162. for (Pair<Integer, Integer> extrema : extremas) {
  163. Roi rectRoi = new ShapeRoi(
  164. new Rectangle(extrema.getKey(), extrema.getValue(), rectW, rectH));
  165. rectRoi.setStrokeWidth(0.8f);
  166. rectRoi.setStrokeColor(Color.blue);
  167. oly.add(rectRoi);
  168. }
  169.  
  170. ImageProcessor copy = ip.duplicate();
  171. ImagePlus asd = new ImagePlus(imgName, copy);
  172. asd.setOverlay(oly);
  173. asd.show();
  174. }
  175.  
  176. private static boolean compare(boolean isMinima, float a, float b) {
  177. if (isMinima) {
  178. return a <= b;
  179. }
  180. return a >= b;
  181. }
  182.  
  183. private static float sqr(float t) {
  184. return t * t;
  185. }
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement