Add files via upload

This commit is contained in:
charlesbvll 2019-10-01 01:22:32 +02:00 committed by GitHub
parent 40f34b7d38
commit e214ed157b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 970 additions and 0 deletions

104
Collector.java Normal file
View File

@ -0,0 +1,104 @@
package main;
import java.util.ArrayList;
public class Collector {
/**
* Find the row, column coordinates of the best element (biggest or smallest) for the given matrix
*
* @param matrix : an 2D array of doubles
* @param smallestFirst : a boolean, indicates if the smallest element is the best or not (biggest is then the best)
* @return an array of two integer coordinates, row first and then column
*/
public static int[] findBest(double[][] matrix, boolean smallestFirst) {
int tempi = 0;
int tempj = 0;
if (smallestFirst) {
double temp = 255;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (matrix[i][j] < temp) {
temp = matrix[i][j];
tempi = i;
tempj = j;
}
}
}
} else {
double temp = 0;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (matrix[i][j] > temp) {
temp = matrix[i][j];
tempi = i;
tempj = j;
}
}
}
}
int best[] = new int[]{tempi, tempj};
return best;
}
/**
* Find the row, column coordinate-pairs of the n best (biggest or smallest) elements of the given matrix
*
* @param n : an integer, the number of best elements we want to find
* @param matrix : an 2D array of doubles
* @param smallestFirst : a boolean, indicates if the smallest element is the best or not (biggest is the best)
* @return an array of size n containing row, column-coordinate pairs
*/
public static int[][] findNBest(int n, double[][] matrix, boolean smallestFirst) {
double temp[][] = matrix;
int array[][] = new int[n][2];
for (int i = 0; i < n; i++) {
int[] best = findBest(temp, smallestFirst);
for (int j = 0; j < 2; j++)
array[i][j] = best[j];
if (smallestFirst) {
temp[best[0]][best[1]] = Double.POSITIVE_INFINITY;
} else {
temp[best[0]][best[1]] = Double.NEGATIVE_INFINITY;
}
}
return array;
}
/**
* BONUS
* Notice : Bonus points are underpriced !
* <p>
* Sorts all the row, column coordinates based on their pixel value
* Hint : Use recursion !
*
* @param matrix : an 2D array of doubles
* @return A list of points, each point is an array of length 2.
*/
public static ArrayList<int[]> quicksortPixelCoordinates(double[][] matrix) {
// TODO implement me correctly for "underpriced" bonus!
return new ArrayList<int[]>();
}
/**
* BONUS
* Notice : Bonus points are underpriced !
* <p>
* Use a quick sort to find the row, column coordinate-pairs of the n best (biggest or smallest) elements of the given matrix
* Hint : return the n first or n last elements of a sorted ArrayList
*
* @param n : an integer, the number of best elements we want to find
* @param matrix : an 2D array of doubles
* @param smallestFirst : a boolean, indicate if the smallest element is the best or not (biggest is the best)
* @return an array of size n containing row, column-coordinate pairs
*/
public static int[][] findNBestQuickSort(int n, double[][] matrix, boolean smallestFirst) {
// TODO implement me correctly for underpriced bonus!
return new int[][]{};
}
}

71
DistanceBasedSearch.java Normal file
View File

@ -0,0 +1,71 @@
package main;
public class DistanceBasedSearch {
/**
* Computes the mean absolute error between two RGB pixels, channel by channel.
*
* @param patternPixel : a integer, the second RGB pixel.
* @param imagePixel : a integer, the first RGB pixel.
* @return a double, the value of the error for the RGB pixel pair. (an integer in [0, 255])
*/
public static double pixelAbsoluteError(int patternPixel, int imagePixel) {
double sum = Math.abs(ImageProcessing.getRed(patternPixel) - ImageProcessing.getRed(imagePixel)) +
Math.abs(ImageProcessing.getGreen(patternPixel) - ImageProcessing.getGreen(imagePixel)) +
Math.abs(ImageProcessing.getBlue(patternPixel) - ImageProcessing.getBlue(imagePixel));
return sum / 3.0;
}
/**
* Computes the mean absolute error loss of a RGB pattern if positioned
* at the provided row, column-coordinates in a RGB image
*
* @param row : a integer, the row-coordinate of the upper left corner of the pattern in the image.
* @param col : a integer, the column-coordinate of the upper left corner of the pattern in the image.
* @param pattern : an 2D array of integers, the RGB pattern to find
* @param image : an 2D array of integers, the RGB image where to look for the pattern
* @return a double, mean absolute error value at position (row, col) between the pattern and the part of
* the base image that is covered by the pattern, if the pattern is shifted by x and y.
* should return -1 if the denominator is -1
*/
public static double meanAbsoluteError(int row, int col, int[][] pattern, int[][] image) {
assert pattern.length != 0 : "pattern contains no pixel";
assert image.length != 0 : "image contains no pixel";
assert row < image.length - pattern.length : "Motif non contenu entierement";
assert col < image[0].length - pattern[0].length : "Motif non contenu entierement";
double sum = 0;
for (int i = 0; i < pattern.length; i++) {
for (int j = 0; j < pattern[0].length; j++) {
sum += pixelAbsoluteError(pattern[i][j], image[row + i][col + j]);
}
}
double size = pattern.length * pattern[0].length;
double eam = sum / size;
return eam;
}
/**
* Compute the distanceMatrix between a RGB image and a RGB pattern
*
* @param pattern : an 2D array of integers, the RGB pattern to find
* @param image : an 2D array of integers, the RGB image where to look for the pattern
* @return a 2D array of doubles, containing for each pixel of a original RGB image,
* the distance (meanAbsoluteError) between the image's window and the pattern
* placed over this pixel (upper-left corner)
*/
public static double[][] distanceMatrix(int[][] pattern, int[][] image) {
assert pattern.length != 0 : "pattern contains no pixel";
assert image.length != 0 : "image contains no pixel";
int W = image[0].length;
int w = pattern[0].length;
int H = image.length;
int h = pattern.length;
double[][] matrix = new double[H - h][W - w];
for (int i = 0; i < H - h; i++) {
for (int j = 0; j < W - w; j++) {
matrix[i][j] = meanAbsoluteError(i, j, pattern, image);
}
}
return matrix;
}
}

180
Helper.java Normal file
View File

@ -0,0 +1,180 @@
package main;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* Provide simple tools to read, write and show pictures.
*/
public final class Helper {
/**
* Draws a rectangle over a RGB image
*
* @param r : an integer, the vertical coordinate (col) of the upper left corner.
* @param c : an integer, the horizontal coordinate (row) of the upper left corner.
* @param w : an integer, the width of the rectangle.
* @param h : an integer, the height of the rectangle.
* @param dst : a 2D integer array, the RGB image on which to draw the rectangle.
* @param color: an integer representing the RBG value of the line color of the rectangle
* @param strokeWidth: width of pencil stroke
*/
public static void drawBox(int r, int c, int w, int h, int[][] dst, int strokeWidth, int color) {
if (strokeWidth < 1) strokeWidth = 1;
for (int row = r; row < r + h && row < dst.length; ++row) {
for (int col = c; col < c + w && col < dst[0].length; ++col) {
if (row < r + strokeWidth || row >= r + h - strokeWidth ||
col < c + strokeWidth || col >= c + w - strokeWidth) {
dst[row][col] = color;
}
}
}
}
/**
* Draws a red rectangle over a RGB image
*
* @param r : an integer, the vertical coordinate (col) of the upper left corner.
* @param c : an integer, the horizontal coordinate (row) of the upper left corner.
* @param w : an integer, the width of the rectangle.
* @param h : an integer, the height of the rectangle.
* @param dst : a 2D integer array, the RGB image on which to draw the rectangle.
*/
public static void drawBox(int r, int c, int w, int h, int[][] dst) {
drawBox(r, c, w, h, dst, w / 15, 255 << 16);
}
// Convert specified BufferedImage into an array
private static int[][] fromBufferedImage(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
int[][] array = new int[height][width];
for (int row = 0; row < height; ++row) {
for (int col = 0; col < width; ++col) {
array[row][col] = image.getRGB(col, row) & 0xffffffff;
}
}
return array;
}
// Convert specified array into a BufferedImage
private static BufferedImage toBufferedImage(int[][] array) {
int width = array[0].length;
int height = array.length;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int row = 0; row < height; ++row) {
for (int col = 0; col < width; ++col) {
image.setRGB(col, row, array[row][col] | 0xff000000);
}
}
return image;
}
/**
* Reads specified image from disk.
*
* @param path : a String, the Input file path
* @return HxW integer array of packed RGB colors, or <code>null</code> on failure
* @see #write
*/
public static int[][] read(String path) {
try {
BufferedImage image = ImageIO.read(new File(path));
return fromBufferedImage(image);
} catch (IOException e) {
System.out.println(e);
System.out.println("Path: " + path);
System.exit(1);
return null;
}
}
/**
* Writes specified image to disk.
*
* @param path : a String, the Output file path
* @param array HxW array of packed RGB colors
* @return {@code true} if write operation was successful, {@code false} otherwise
* @see #read
*/
public static boolean write(String path, int[][] array) {
// Convert array to Java image
BufferedImage image = toBufferedImage(array);
// Get desired file format
int index = path.lastIndexOf('.');
if (index < 0)
return false;
String extension = path.substring(index + 1);
// Export image
try {
return ImageIO.write(image, extension, new File(path));
} catch (IOException e) {
return false;
}
}
/**
* Shows specified image in a window.
*
* @param array : a HxW integer array of packed RGB colors
* @param title : a String, the title to be displayed
*/
public static void show(int[][] array, String title) {
// Convert array to Java image
final BufferedImage image = toBufferedImage(array);
// Create a panel to render this image
@SuppressWarnings("serial")
JPanel panel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, Math.max(getWidth(), 100), Math.max(getHeight(), 100), null, null);
}
};
// Create a frame to hold this panel
final JFrame frame = new JFrame(title);
frame.add(panel);
frame.getContentPane().setPreferredSize(new Dimension(Math.max(image.getWidth(), 300), Math.max(image.getHeight(), 300)));
frame.pack();
// Register closing event
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
frame.setVisible(false);
synchronized (frame) {
frame.notifyAll();
}
}
});
// Show this frame
frame.setVisible(true);
// Wait for close operation
try {
synchronized (frame) {
while (frame.isVisible())
frame.wait();
}
} catch (InterruptedException e) {
// Empty on purpose
}
frame.dispose();
}
}

155
ImageProcessing.java Normal file
View File

@ -0,0 +1,155 @@
package main;
public final class ImageProcessing {
/**
* Checks wether or not a RGB component is between 0 and 255 and returns the right value.
*
* @param value : an integer.
* @return an integer, between 0 and 255
*/
public static int checkInt(int value) {
if (value < 0)
value = 0;
if (value > 255)
value = 255;
return value;
}
/**
* Returns red component from given packed color.
*
* @param rgb : a 32-bits RGB color
* @return an integer, between 0 and 255
* @see #getGreen
* @see #getBlue
* @see #getRGB(int, int, int)
*/
public static int getRed(int rgb) {
return (rgb >> 16) & 0xff;
}
/**
* Returns green component from given packed color.
*
* @param rgb : a 32-bits RGB color
* @return an integer between 0 and 255
* @see #getRed
* @see #getBlue
* @see #getRGB(int, int, int)
*/
public static int getGreen(int rgb) {
return (rgb >> 8) & 0xff;
}
/**
* Returns blue component from given packed color.
*
* @param rgb : a 32-bits RGB color
* @return an integer between 0 and 255
* @see #getRed
* @see #getGreen
* @see #getRGB(int, int, int)
*/
public static int getBlue(int rgb) {
return rgb & 0xff;
}
/**
* Returns the average of red, green and blue components from given packed color.
*
* @param rgb : 32-bits RGB color
* @return a double between 0 and 255
* @see #getRed
* @see #getGreen
* @see #getBlue
* @see #getRGB
*/
public static double getGray(int rgb) {
return ((getRed(rgb) + getBlue(rgb) + getGreen(rgb)) / 3.0);
}
/**
* Returns packed RGB components from given red, green and blue components.
*
* @param red : an integer
* @param green : an integer
* @param blue : an integer
* @return a 32-bits RGB color
* @see #getRed
* @see #getGreen
* @see #getBlue
*/
public static int getRGB(int red, int green, int blue) {
return checkInt(red) << 16 | checkInt(green) << 8 | checkInt(blue);
}
/**
* Returns packed RGB components from given gray-scale value.
*
* @param gray : an integer
* @return a 32-bits RGB color
* @see #getGray
*/
public static int getRGB(double gray) {
int g = (int) Math.round(gray);
return checkInt(g) << 16 | checkInt(g) << 8 | checkInt(g);
}
/**
* Converts packed RGB image to gray-scale image.
*
* @param image : a HxW integer array
* @return a HxW double array
* @see #encode
* @see #getGray
*/
public static double[][] toGray(int[][] image) {
double[][] img = new double[image.length][image[0].length];
for (int i = 0; i < image.length; i++) {
for (int j = 0; j < image[0].length; j++) {
img[i][j] = getGray(image[i][j]);
}
}
return img;
}
/**
* Converts gray-scale image to packed RGB image.
*
* @param channels : a HxW double array
* @return a HxW integer array
* @see #decode
* @see #getRGB(double)
*/
public static int[][] toRGB(double[][] gray) {
int[][] img = new int[gray.length][gray[0].length];
for (int i = 0; i < gray.length; i++) {
for (int j = 0; j < gray[0].length; j++) {
img[i][j] = getRGB(gray[i][j]);
}
}
return img;
}
/**
* Convert an arbitrary 2D double matrix into a 2D integer matrix
* which can be used as RGB image
*
* @param matrix : the arbitrary 2D double array to convert into integer
* @param min : a double, the minimum value the matrix could theoretically contains
* @param max : a double, the maximum value the matrix could theoretically contains
* @return an 2D integer array, containing a RGB mapping of the matrix
*/
public static int[][] matrixToRGBImage(double[][] matrix, double min, double max) {
int[][] imageRGB = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
imageRGB[i][j] = getRGB(255.0 * ((matrix[i][j] - min) / (max - min)));
}
}
return imageRGB;
}
}

271
Main.java Normal file
View File

@ -0,0 +1,271 @@
package main;
/**
* @author Charles BEAUVILLE and Mike Sinsoillier
* <p>
* Where is Charlie Project
*/
public final class Main {
public static void main(String[] args) {
testGetRed();
testGrayscale();
testGetGreen();
testGetBlue();
testGetGray();
testGetRGB();
testFindBest();
testFindNBest();
pixelAbsoluteError();
testToGray();
testToRGB();
testDistanceBasedSearch();
testSimilarityBasedSearch();
testNCCPatternEqualImage();
testSimilarityPatternEqualImage();
testSimilaritySimple();
findCharlie();
}
/*
* Tests for Class ImageProcessing
*/
public static void testGetRed() {
int color = 0b11110000_00001111_01010101;
int ref = 0b11110000;
int red = ImageProcessing.getRed(color);
if (red == ref) {
System.out.println("Test red passed");
} else {
System.out.println("Test red failed. Returned value = " + red + " Expected value = " + ref);
}
}
public static void testGrayscale() {
System.out.println("Test Grayscale");
int[][] image = Helper.read("images/food.png");
double[][] gray = ImageProcessing.toGray(image);
Helper.show(ImageProcessing.toRGB(gray), "test bw");
}
public static void testGetGreen() {
int color = 0b11110000_00001111_01010101;
int ref = 0b00001111;
int green = ImageProcessing.getGreen(color);
if (green == ref) {
System.out.println("Test green passed");
} else {
System.out.println("Test green failed. Returned value = " + green + " Expected value = " + ref);
}
}
public static void testGetBlue() {
int color = 0b11110000_00001111_01010101;
int ref = 0b01010101;
int blue = ImageProcessing.getBlue(color);
if (blue == ref) {
System.out.println("Test blue passed");
} else {
System.out.println("Test blue failed. Returned value = " + blue + " Expected value = " + ref);
}
}
public static void testGetGray() {
int color = 0b11110000_00001111_01010101;
int ref = 0b01110001;
double gray = ImageProcessing.getGray(color);
if (Math.round(gray) == ref) {
System.out.println("Test gray passed");
} else {
System.out.println("Test gray failed. Returned value = " + gray + " Expected value = " + ref);
}
}
public static void testGetRGB() {
int ref = 0b11110000_00001111_01010101;
int red = 0b11110000;
int green = 0b00001111;
int blue = 0b01010101;
int RGB = ImageProcessing.getRGB(red, green, blue);
if (RGB == ref) {
System.out.println("Test RGB 1 passed");
} else {
System.out.println("Test RGB 1 failed. Returned value = " + RGB + " Expected value = " + ref);
}
int rgb = ImageProcessing.getRGB(127.0);
int ref2 = 0x7f7f7f;
if (rgb == ref2) {
System.out.println("Test RGB 2 passed");
} else {
System.out.println("Test RGB 2 failed. Returned value = " + rgb + " Expected value = " + ref2);
}
}
public static void testToGray() {
System.out.println("Test toGray");
double[][] ref = new double[][] {{0b01110001}, {0b01110001},{0b01110001}};
int [][] image = new int[][] {{0b01110001_01110001_01110001}, {0b01110001_01110001_01110001},{0b01110001_01110001_01110001}};
double[][] toGray = ImageProcessing.toGray(image);
for(int i=0 ; i<toGray.length; i++) {
for(int j =0 ; j<toGray[0].length ; j++) {
if ((ref[i][j]==toGray[i][j])) {
System.out.println("Test passed");
} else {
System.out.println("Test failed.");
}
}
}
}
public static void testToRGB() {
System.out.println("Test toRGB");
int[][] ref = new int[][] {{0b01110001_01110001_01110001}, {0b01110001_01110001_01110001},{0b01110001_01110001_01110001}};
double [][] image = new double[][] {{0b01110001}, {0b01110001},{0b01110001}};
int[][] toRGB = ImageProcessing.toRGB(image);
for(int i=0 ; i<toRGB.length; i++) {
for(int j =0 ; j<toRGB[0].length ; j++) {
if ((ref[i][j]==toRGB[i][j])) {
System.out.println("Test passed");
} else {
System.out.println("Test failed.");
}
}
}
}
/*
* Tests for Class Collector
*/
public static void testFindBest() {
System.out.println("Test findBest");
double[][] t = new double[][]{{20, 30, 10, 50, 32}, {28, 39, 51, 78, 91}};
int[] coords = Collector.findBest(t, false);
System.out.println("Coordonnes : " + coords);
}
public static void testFindNBest() {
System.out.println("Test findNBest");
double[][] t = new double[][]{{20, 30, 10, 50, 32}, {28, 39, 51, 78, 91}};
int[][] coords = Collector.findNBest(10, t, true);
for (int[] a : coords) {
int r = a[0];
int c = a[1];
System.out.println("Row=" + r + " Col=" + c + " Val=" + t[r][c]);
}
}
/*
* Tests for Class DistanceBasedSearch
*/
public static void pixelAbsoluteError() {
int color = 0b11110000_00001111_01010101;
int color2 = 0b11010000_00101011_01010001;
int ref = 21;
int AE = (int) DistanceBasedSearch.pixelAbsoluteError(color, color2);
if (AE == ref) {
System.out.println("Test AE passed");
} else {
System.out.println("Test AE failed. Returned value = " + AE + " Expected value = " + ref);
}
}
public static void testDistanceBasedSearch() {
System.out.println("Test DistanceBasedSearch");
int[][] food = Helper.read("images/food.png");
int[][] onions = Helper.read("images/onions.png");
double[][] distance = DistanceBasedSearch.distanceMatrix(onions, food);
int[] p = Collector.findBest(distance, true);
Helper.drawBox(p[0], p[1], onions[0].length, onions.length, food);
Helper.show(food, "Found!");
}
/*
* Tests for Class SimilarityBasedSearch
*/
public static void testSimilarityBasedSearch() {
System.out.println("Test SimilarityBasedSearch");
int[][] food = Helper.read("images/food.png");
int[][] onions = Helper.read("images/onions.png");
double[][] foodGray = ImageProcessing.toGray(food);
double[][] onionsGray = ImageProcessing.toGray(onions);
double[][] similarity = SimilarityBasedSearch.similarityMatrix(onionsGray, foodGray);
int[][] best = Collector.findNBest(8, similarity, false);
for (int[] a : best) {
int r = a[0];
int c = a[1];
Helper.drawBox(r, c, onions[0].length, onions.length, food);
}
Helper.show(food, "Found again!");
}
public static void findCharlie() {
System.out.println("Find Charlie");
int[][] beach = Helper.read("images/charlie_beach.png");
int[][] charlie = Helper.read("images/charlie.png");
double[][] beachGray = ImageProcessing.toGray(beach);
double[][] charlieGray = ImageProcessing.toGray(charlie);
System.out.println("Compute Similarity Matrix: expected time about 2 min");
double[][] similarity = SimilarityBasedSearch.similarityMatrix(charlieGray, beachGray);
System.out.println("Find N Best");
int[] best = Collector.findBest(similarity, false);
double max = similarity[best[0]][best[1]];
Helper.show(ImageProcessing.matrixToRGBImage(similarity, -1, max), "Similarity");
Helper.drawBox(best[0], best[1], charlie[0].length, charlie.length, beach);
System.out.println("drawBox at (" + best[0] + "," + best[1] + ")");
Helper.show(beach, "Found again!");
}
/*
* Tests for extreme cases
*/
public static void testNCCPatternEqualImage() {
double[][] pattern = {{0, 0, 0},
{0, 255, 0},
{0, 0, 0}};
double similarity = SimilarityBasedSearch.normalizedCrossCorrelation(0, 0, pattern, pattern);
if (similarity == 1.0) {
System.out.println("PASSED");
} else {
System.out.println("ERROR: expected value 1.0 but was " + similarity);
}
}
public static void testSimilarityPatternEqualImage() {
double[][] pattern = {{0, 255}};
double[][] similarity = SimilarityBasedSearch.similarityMatrix(pattern, pattern);
if (similarity.length == 1) {
if (similarity[0][0] == 1.0) {
System.out.println("PASSED");
} else {
System.out.println("ERROR: expected value 1.0 but was " + similarity[0][0]);
}
} else {
System.out.println("ERROR: expected length 1 but was " + similarity.length);
}
}
public static void testSimilaritySimple() {
double[][] image = {{3, 2, 2, 2},
{0, 3, 0, 0}};
double[][] pattern = {{0, 3, 0}};
double[][] similarity = SimilarityBasedSearch.similarityMatrix(pattern, image);
if (similarity.length == 2 && similarity[0].length == 2) {
if (similarity[0][0] == -0.5 && similarity[0][1] == -1.0 &&
similarity[1][0] == 1.0 && similarity[1][1] == -0.5) {
System.out.println("PASSED");
} else {
System.out.println("ERROR: wrong values");
}
} else {
System.out.println("ERROR: incorrect size");
}
}
}

16
Program.java Normal file
View File

@ -0,0 +1,16 @@
package main;
public class Program {
public static void main(String[] args) {
System.out.println("Loading files...");
int[][] image = Helper.read("images/charlie_beach.png");
int[][] pattern = Helper.read("images/charlie.png");
System.out.println("Searching...");
double[][] distance = DistanceBasedSearch.distanceMatrix(pattern, image);
System.out.println("Processing...");
int[] p = Collector.findBest(distance, true);
Helper.drawBox(p[0], p[1], pattern[0].length, pattern.length, image);
Helper.show(image, "Found!");
}
}

57
SignatureChecks.java Normal file
View File

@ -0,0 +1,57 @@
package main;
/**
* Check if the signatures of all required functions are correct
* This file should complied but not run ! (i.e, not indicate any error)
* For your own good, please do not change anything inside this file !
* Check this file is complied before submit your project on moodle
*/
public class SignatureChecks {
@SuppressWarnings("unused")
public static void main(String[] argv) {
int[][] image = new int[0][0];
double[][] grayImage = new double[0][0];
int rgb = 0;
int red = 0;
int green = 0;
int blue = 0;
double gray = 0;
double factor = 0;
int intResult;
double doubleResult;
boolean boolResult;
//ImageProcessing
intResult = ImageProcessing.getRed(rgb);
intResult = ImageProcessing.getGreen(rgb);
intResult = ImageProcessing.getBlue(rgb);
doubleResult = ImageProcessing.getGray(rgb);
intResult = ImageProcessing.getRGB(red, green, blue);
intResult = ImageProcessing.getRGB(gray);
grayImage = ImageProcessing.toGray(image);
image = ImageProcessing.toRGB(grayImage);
int[][] img = ImageProcessing.matrixToRGBImage(grayImage, 0, 255);
//Collector
int[] best = Collector.findBest(grayImage, false);
int[][] nBests = Collector.findNBest(3, grayImage, false);
//DistanceBasedSearch
double error = DistanceBasedSearch.pixelAbsoluteError(0xffffff, 0x000000);
error = DistanceBasedSearch.meanAbsoluteError(0, 0, image, image);
double[][] res = DistanceBasedSearch.distanceMatrix(image, image);
//CrossCorrelation
double m = SimilarityBasedSearch.mean(res);
SimilarityBasedSearch.normalizedCrossCorrelation(0, 0, grayImage, grayImage);
SimilarityBasedSearch.similarityMatrix(grayImage, grayImage);
}
}

116
SimilarityBasedSearch.java Normal file
View File

@ -0,0 +1,116 @@
package main;
public class SimilarityBasedSearch {
/**
* Computes the mean value of a gray-scale image given as a 2D array
*
* @param image : a 2D double array, the gray-scale Image
* @return a double value between 0 and 255 which is the mean value
*/
public static double mean(double[][] image) {
assert image.length != 0 : "image contains no pixel";
double sum = 0;
for (int i = 0; i < image.length; i++) {
for (int j = 0; j < image[0].length; j++) {
sum += image[i][j];
}
}
return sum / ((double) image.length * image[0].length);
}
/**
* Computes the mean value of a part of an image
*
* @param matrix : a 2D array of double, the gray-scale image we want to calculate the mean value of a part
* @param row : a integer, the row-coordinate of the upper left corner of the pattern in the image.
* @param column : a integer, the column-coordinate of the upper left corner of the pattern in the image.
* @param width : a integer, the width of the window.
* @param height : a integer, the height of the window.
* @return a double, the mean value of the specified part of the input matrix
*/
static double windowMean(double[][] matrix, int row, int col, int width, int height) {
double[][] temp = new double[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
temp[i][j] = matrix[i + row][j + col];
}
}
return mean(temp);
}
/**
* Computes the Normalized Cross Correlation of a gray-scale pattern if positioned
* at the provided row, column-coordinate in a gray-scale image
*
* @param row : a integer, the row-coordinate of the upper left corner of the pattern in the image.
* @param column : a integer, the column-coordinate of the upper left corner of the pattern in the image.
* @param pattern : an 2D array of doubles, the gray-scale pattern to find
* @param image : an 2D array of double, the gray-scale image where to look for the pattern
* @return a double, the Normalized Cross Correlation value at position (row, col) between the pattern and the part of
* the base image that is covered by the pattern, if the pattern is shifted by x and y.
* should return -1 if the denominator is 0
*/
public static double normalizedCrossCorrelation(int row, int col, double[][] pattern, double[][] image) {
assert image.length != 0 : "image contains no pixel";
assert pattern.length != 0 : "pattern contains no pixel";
double wmean = windowMean(image, row, col, pattern.length, pattern[0].length);
double m = mean(pattern);
double sum1 = 0, sum2 = 0, sum3 = 0;
for (int i = 0; i < pattern.length; i++) {
for (int j = 0; j < pattern[0].length; j++) {
sum1 += (image[row + i][col + j] - wmean) * (pattern[i][j] - m);
sum2 += (image[row + i][col + j] - wmean) * (image[row + i][col + j] - wmean);
sum3 += (pattern[i][j] - m) * (pattern[i][j] - m);
}
}
double result;
if ((Math.sqrt(sum2 * sum3)) == 0)
result = -1;
else
result = sum1 / (Math.sqrt(sum2 * sum3));
return result;
}
/**
* Compute the similarityMatrix between a gray-scale image and a gray-scale pattern
*
* @param pattern : an 2D array of doubles, the gray-scale pattern to find
* @param image : an 2D array of doubles, the gray-scale image where to look for the pattern
* @return a 2D array of doubles, containing for each pixel of a original gray-scale image,
* the similarity (normalized cross-correlation) between the image's window and the pattern
* placed over this pixel (upper-left corner)
*/
public static double[][] similarityMatrix(double[][] pattern, double[][] image) {
assert pattern.length != 0 : "pattern contains no pixel";
assert image.length != 0 : "image contains no pixel";
int W = image[0].length;
int w = pattern[0].length;
int H = image.length;
int h = pattern.length;
double[][] matrix = new double[H - h + 1][W - w + 1];
for (int i = 0; i < H - h + 1; i++) {
for (int j = 0; j < W - w + 1; j++) {
matrix[i][j] = normalizedCrossCorrelation(i, j, pattern, image);
}
}
return matrix;
}
}