Java code - compile time optimisation - java

I am new to programming and have programmed a java program that calculates the voronoi diagram for random points and draws it on a picture - 1080 x 1920 pixels. Here you can see the result
The problem is that it takes nearly four minutes to compile the code. Please help me with code optimization. Below you can find the code:
class Voronoi {
private static Random r;
private static KDTree<Integer> kd;
private static double[][] keys;
private static int counter;
private static int x;
public static void main(String[] args) throws IOException,
KeySizeException, KeyDuplicateException {
BufferedImage img = null;
Scanner sc = new Scanner(System.in);
x = sc.nextInt();
// input an image
img = ImageIO.read(new File("input.jpg"));
// get image Height and Width
int w = img.getWidth();
int h = img.getHeight();
// make array with equal size like the image and populate it with the 0
// make an empty array and populate it
int[][] empty = new int[h][w];
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
empty[row][col] = 0;
}
}
// make a D-dimensional KD-tree
keys = new double[x][2];
kd = new KDTree<Integer>(2);
ArrayList<Color> b = new ArrayList<Color>();
int[] totalBlue = new int[x];
int[] totalGreen = new int[x];
int[] totalRed = new int[x];
int[] counter_sec = new int[x];
// Generate random centers and populate them with 1
for (int i = 0; i < x; i++) {
generateCentre(empty, h, w);
// b.add(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
}
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
double[] array = new double[2];
array[0] = i;
array[1] = j;
Color c = new Color(img.getRGB(j, i));
totalBlue[kd.nearest(array)] = totalBlue[kd.nearest(array)]
+ c.getBlue();
totalRed[kd.nearest(array)] = totalRed[kd.nearest(array)]
+ c.getRed();
totalGreen[kd.nearest(array)] = totalGreen[kd.nearest(array)]
+ c.getGreen();
// img.setRGB(j, i, b.get(kd.nearest(array)).getRGB());
counter_sec[kd.nearest(array)] = counter_sec[kd.nearest(array)] + 1;
}
}
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
double[] array = new double[2];
array[0] = i;
array[1] = j;
Color c = new Color(img.getRGB(j, i));
// img.setRGB(j, i, b.get(kd.nearest(array)).getRGB());
Color color = new Color(totalRed[kd.nearest(array)]/counter_sec[kd.nearest(array)], totalGreen[kd.nearest(array)]/counter_sec[kd.nearest(array)],totalBlue[kd.nearest(array)]/counter_sec[kd.nearest(array)]);
img.setRGB(j, i, color.getRGB());
}
}
File outputfile = new File("image.jpg");
ImageIO.write(img, "jpg", outputfile);
System.out.println(totalRed[0]/counter_sec[0]+" "+totalGreen[0]/counter_sec[0]+" "+totalBlue[0]/counter_sec[0]);
}
public static void generateCentre(int[][] empty, int h, int w)
throws KeySizeException, KeyDuplicateException {
r = new Random();
int height = r.nextInt(h);
int width = r.nextInt(w);
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
if (row == height && col == width && empty[height][width] == 0) {
empty[height][width] = 1;
keys[counter][0] = row;
keys[counter][2] = col;
kd.insert(keys[counter], counter);
}/*else if (row == height && col == width
&& empty[height][width] != 0) {
generateCentre(empty, h, w);
}*/
}
}
System.out.println(kd.search(keys[counter]));
if (counter < x) {
counter++;
}
}
}

Although I don't claim a full understanding of your code, I see one potentially large cause of slowdown:
totalBlue[kd.nearest(array)] = totalBlue[kd.nearest(array)]
+ c.getBlue();
totalRed[kd.nearest(array)] = totalRed[kd.nearest(array)]
+ c.getRed();
totalGreen[kd.nearest(array)] = totalGreen[kd.nearest(array)]
+ c.getGreen();
// img.setRGB(j, i, b.get(kd.nearest(array)).getRGB());
counter_sec[kd.nearest(array)] = counter_sec[kd.nearest(array)] + 1;
You seem to be repeatedly calling kd.nearest(array), which is probably not a very cheap operation. You should call that once and store it in a local variable. I would rewrite your key loop as follows:
double[] coords = new double[2];
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
coords[0] = i;
coords[1] = j;
final int nearest = kd.nearest(coords);
final Color c = new Color(img.getRGB(j, i));
totalBlue[nearest] += c.getBlue();
totalRed[nearest] += c.getRed();
totalGreen[nearest] += c.getGreen();
counter_sec[nearest]++;
}
}
Here I have utilized the += and ++ operators to make things shorter and more readable. I have also hoisted your coordinates array outside the loop because it can be safely reused at each iteration. This reduces GC time, but more importantly it helps CPU caches.
Apply the same changes to your second loop, where you generate the output image.

Related

Java implement cross correlation 2d image

enter image description here
Can i implement the cross-correlation in the same way as the convolution?
I want to implement the formula in as in the picture, where Li the kernel in 4 different direction filters; Ci is the magnitude map for direction i. So what I did is to find the cross-correlation in the four directions separately and add them up. I learned that the cross correlation can be the same as convolution in image line sharping; s as the result should be stroke line of an image but what I actually get are discrete points. I am not sure if I implemented the formula correctly. Please help
private static void sharpTheLine(){
int[][] cC_0= crossCorrelation(KERNEL_0,CMap_0);
int[][] cC_45=crossCorrelation(KERNEL_45,CMap_45);
int[][] cC_90=crossCorrelation(KERNEL_90,CMap_90);
int[][] cC_135=crossCorrelation(KERNEL_135,CMap_135);
//generate S
for(int i=0; i<imageWidth; i++){
for(int j =0; j<imageHight; j++) {
SMap[i][j] = cC_0[i][j]+cC_45[i][j]+cC_90[i][j]+cC_135[i][j];
}
}
}
private static int[][] crossCorrelation(int [][] kernel,int[][] CMapVal){
int horizontalWalk = imageWidth - K_R;
int verticalWalk = imageHight - K_C;
int res[][]=new int[imageWidth][imageHight];
for (int i = 0; i < horizontalWalk; i++) {
for (int j = 0; j < verticalWalk; j++) {
int sample[][] = new int[K_R][K_C];
for (int k = i; k < K_R + i; k++) {
for (int m = j; m < K_C + j; m++) {
sample[k - i][m - j] = CMapVal[k][m];
OnePixelConvolution(sample, i, j, kernel, res);
}
}
}
}
return res;
}
private static void OnePixelConvolution(int[][] sample, int x, int y, int [][]kernel, int [][] res) {
int resrgb = 0;
for (int i = 0; i < K_R; i++) {
for (int j = 0; j < K_C; j++) {
resrgb = resrgb + sample[i][j] * kernel[i][j];
}
}
res[x][y] = resrgb;
}

How to generate row-major and column-major matrices in java?

I am trying to work through an assignment that is asking me to create a method in Java that, when given a desired height and width, create a row- or column- major matrix.
Here is what I have so far:
public static int[][] increasingMatrix(int width, int height, boolean format){
if (format) { // generate row-major matrix
int[][] array = new int[height][];
int count = 0;
for (int i = 0; i < height; i++) {
array[i] = new int[width];
for (int j = 0; j < width; j++) {
array[i][j] = count;
count++;
}
}
return array;
} else {
int[][] array = new int[width][];
int count = 0;
for (int i = 0; i < width; i++) {
array[i] = new int [height];
for (int j = 0; j < height; j++) {
array[j][i] = count;
count ++;
}
}
return array;
}
}
However, when I go and try to run tests on the generated array, the column-major matrix (from what I can tell) is being generated incorrectly. The row-major matrix seems to generate correctly.
Can you see anything that I am doing wrong? I have stared at this for hours but cant seem to get any breakthroughs.
Thanks!
Your code is wrong. The first index in the matrix is always the width.
Remember: a matrix is an array of arrays. The first index is the width of the matrix, the second is the height.
Try this:
if(format) {
return buildRowMajorMatrix(width, height);
} else {
return buildColumnMajorMatrix(width, height);
}
Where buildRowMajorMatrix looks like:
private int[][] buildRowMajorMatrix(int width, int height) {
int[][] matrix = new int[width][height];
int cellValue = 0;
for(int columnIndex = 0 ; columnIndex < width ; columnIndex++) {
for(int rowIndex = 0 ; rowIndex < height ; rowIndex++, cellValue++) {
matrix[columnIndex][rowIndex] = cellValue;
}
}
return matrix;
}
And buildColumnMajorMatrix looks like:
private int[][] buildColumnMajorMatrix(int width, int height) {
int[][] matrix = new int[width][height];
int cellValue = 0;
for(int rowIndex = 0 ; rowIndex < height ; rowIndex++) {
for(int columnIndex = 0 ; columnIndex < width ; columnIndex++, cellValue++) {
matrix[columnIndex][rowIndex] = cellValue;
}
}
return matrix;
}
In else condition:
else {
int[][] array = new int[width][];
int count = 0;
for (int i = 0; i < width; i++) {
array[i] = new int [height];
for (int j = 0; j < height; j++) {
array[j][i] = count;
count ++;
}
}
return array;
}
You are trying trying to iterate through arrays (rows of matrix, j-index) that are not yet initialized. To implement column-major matrix you need to first initialize all rows (or switch to more complex algorithm).
Also I think width and height of matrix in both formats should be same. Row- and column-majority only says whether we fill matrix iterating by columns or rows, but I guess wording of the task leaves room for interpretation.
My solution:
public static int[][] increasingMatrix(int width, int height, boolean format){
int[][] array = new int[height][width]; // Java's shortcut generating regular array of arrays for you
int count = 0;
if (format) { // generate row-major matrix
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
array[i][j] = count;
count++;
}
}
} else {
for (int j = 0; j < width; j++)) {
for (int i = 0; i < height; i++ {
array[i][j] = count;
count++;
}
}
}
return array;
}

Make a Grid from a string in a text file

I have three run arguments that are min width, max width and the text file name. The text files are filled with one long string of random characters. I want to put each character into a grid spot. But all I get back is the string itself from the file. How do I make the grid?
class GridCipher{
static int minGridWidth;
static int maxGridWidth;
static File inputFile;
public static void main(String[] args) throws FileNotFoundException {
if (handleArguments(args))
processInput();
}
static final String usage = "Usage: GridWriter min_width max_width input_file_name";
static boolean handleArguments(String[] args) {
// Check for correct number of arguments
if (args.length != 3) {
System.out.println("Wrong number of command line arguments.");
System.out.println(usage);
return false;
}
try {
minGridWidth = Integer.parseInt(args[0]);
maxGridWidth = Integer.parseInt(args[1]);
} catch (NumberFormatException ex) {
System.out.println("min_width and max_width must be integers.");
System.out.println(usage);
return false;
}
inputFile = new File(args[2]);
if (!inputFile.canRead()) {
System.out.println("The file " + args[2] + " cannot be opened for input.");
return false;
}
return true;
}
static void processInput() throws FileNotFoundException {
Scanner input = new Scanner(inputFile);
String line = input.nextLine();
int length = line.length(); // number of characters.
// Try each width in the appropriate range
for (int width = minGridWidth; width <= maxGridWidth; width++) {
// Determine heigth of grid
int height = line.length() / width;
// Add one to height if there's a partial last row
if (line.length() % width != 0)
height += 1;
loadUnloadGrid(line, width, height);
}
}
static void loadUnloadGrid(String line, int width, int height) {
char grid[][] = new char[height][width];
// Determine number long columns
int longColumn = line.length() % width;
if (longColumn == 0)
longColumn = width;
//Load the input data into the grid by column
int charCount = 0;
for (int c = 0; c < width; c++) {
for (int r = 0; r < height; r++) {
if (r < height - 1 || c < longColumn) {
grid[r][c] = line.charAt(charCount);
charCount += 1;
}
}
}
// Output data from the grid by rows
for (int r = 0; r < height - 1; r++) {
for (int c = 0; c < width; c++) {
System.out.print(grid[r][c]);
}
}
// Special handling for last row
for (int c = 0; c < longColumn; c++) {
System.out.print(grid[height - 1][c]);
}
System.out.println("\"");
}
}
If the text file has ABCDE, I just get back ABCDE. I would like the characters in a grid determined by my min and max width.
If I understand you correctly you want ABCDEFG into
A B C
D E F
G
but in the fragment writing it on screen you miss new line character
// Output data from the grid by rows
for (int r = 0; r < height - 1; r++) {
for (int c = 0; c < width; c++) {
System.out.print(grid[r][c]);
}
}
should be
// Output data from the grid by rows
for (int r = 0; r < height - 1; r++) {
for (int c = 0; c < width; c++) {
System.out.print(grid[r][c]);
}
System.out.println();
}
Printing grid is not correct in your program.
Change below to
// Output data from the grid by rows
for (int r = 0; r < height - 1; r++) {
for (int c = 0; c < width; c++) {
System.out.print(grid[r][c]);
}
}
this code
for(char[] arr : grid) {
System.out.println(Arrays.toString(arr));
}

I need to replicate the image

So this program needs to do a few things with the image. I started writing method called replicate and what it needs to do is to take in num1 and num2, and then duplicate the image left-right num1 times, and then replicate the picture num2 times top to bottom. So like the same a small image would act as desktop wallpaper, it's repeat itself. I am not allowed to use image buffer. thank you
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
public class ImageTool {
// THIS METHOD MAY BE CALLED, BUT MUST NOT BE MODIFIED!
//
public static int[][] readGrayscaleImage(String filename) {
int [][] result = null;
try {
File imageFile = new File(filename);
BufferedImage image = ImageIO.read(imageFile);
int height = image.getHeight();
int width = image.getWidth();
result = new int[height][width];
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb = image.getRGB(x, y);
result[y][x] = rgb & 0xff;
}
}
}
catch (IOException ioe) {
System.err.println("Problems reading file named " + filename);
System.exit(1);
}
return result;
}
// THIS METHOD MAY BE CALLED, BUT MUST NOT BE MODIFIED!
//
public static void writeGrayscaleImage(String filename, int[][] array) {
int width = array[0].length;
int height = array.length;
try {
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb = array[y][x];
rgb |= rgb << 8;
rgb |= rgb << 16;
image.setRGB(x, y, rgb);
}
}
File imageFile = new File(filename);
ImageIO.write(image, "jpg", imageFile);
}
catch (IOException ioe) {
System.err.println("Problems writing file named " + filename);
System.exit(1);
}
}
public static void main (String [] args) {
if (args.length < 1) {
System.out.println("Invalid program execution");
System.out.println("Please provide command");
System.exit(-1);
}
if (args[0].equals("--dump")){
String fileName = args[1];
int [][] image = readGrayscaleImage(fileName);
print2dArray(image);
} else if (args[0].equals("--reflectV")){
String fileName = args[1];
int [][] image = readGrayscaleImage(fileName);
int [][] reflected = reflectV(image);
String outputFilename = args[2];
writeGrayscaleImage(outputFilename, reflected);
} else if (args[0].equals("--reflectH")){
String fileName = args[1];
int [][] image = readGrayscaleImage(fileName);
int [][] reflected = reflectH(image);
String outputFilename = args[2];
writeGrayscaleImage(outputFilename, reflected);
} else if (args[0].equals("--ascii")){
String fileName=args[1];
int [][] image = readGrayscaleImage(fileName);
ascii(image);
} else if (args[0].equals("--replicate")) {
String fileName = args[2];
int [][] image = readGrayscaleImage(fileName);
double factor = args[0];
String outputFilename = args[3];
writeGrayscaleImage(outputFilename, reflected);
}
}
public static void replicate(double num1, double num2, int[][]arr) {
double length = num1 * arr.length;
double height = num2 * arr[0].length;
int[][]newArr = new int[length][height];
for(int i = 0; i <= newArr.length; i++){
for(int j = 0; j <= arr.length; j++){
newArr[i][j]=arr[i][j];
}
}
}
public static void ascii (int[][]arr) {
int rows = arr.length;
int cols = arr[0].length;
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
if(arr[i][j] >= 0 && arr[i][j] <= 25){
System.out.print("M");
} else if(arr[i][j]>=26 && arr[i][j] <=50){
System.out.print("$");
} else if(arr[i][j]>=51 && arr[i][j] <= 76){
System.out.print("0");
} else if(arr[i][j]>=77 && arr[i][j] <=102){
System.out.print("|");
} else if(arr[i][j]>=103 && arr[i][j]<=127){
System.out.print("*");
} else if (arr[i][j]>=128 && arr[i][j]<=152){
System.out.print(":");
} else if (arr[i][j]>=153 && arr[i][j]<=178){
System.out.print("=");
} else if (arr[i][j]>=179 && arr[i][j]<=204){
System.out.print("\'");
} else if (arr[i][j]>=205 && arr[i][j]<=230){
System.out.print(".");
} else if (arr[i][j]>=231 && arr[i][j]<=255){
System.out.print(" ");
}
}
System.out.println();
}
}
public static void print2dArray(int[][] arr) {
for (int i = 0; i <arr.length; i++){
//System.out.println(Arrays.toString(arr[i]));
for (int j = 0; j< arr[i].length; j++){
System.out.format("%3d, " , arr[i][j]);
}
System.out.println();
}
}
public static int [][] reflectV (int [][] arr) {
int rows = arr.length;
int cols = arr[0].length;
int [][] reflected = new int[rows][cols];
for (int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++) {
reflected [i][j] = arr[i][cols-j-1];
}
}
//go through arr and reverse values in each row
return reflected;
}
public static int [][] reflectH (int [][] arr) {
int rows = arr.length;
int cols = arr[0].length;
int [][] reflected = new int[rows][cols];
for (int i = 0; i < cols; i++){
for(int j = 0; j < rows; j++) {
reflected [j][i] = arr[cols-j-1][i];
}
}
//go through arr and reverse values in each row
return reflected;
}
}
This should be the solution:
public static int[][] replicate(double num1, double num2, int[][]arr) {
double length = num1 * arr.length;
double height = num2 * arr[0].length;
int[][]newArr = new int[(int) length][(int) height];
for(int i = 0; i < newArr.length; i++){
for(int j = 0; j < newArr[i].length; j++){
newArr[i][j]=arr[i % arr.length][j % arr[0].length];
}
}
return newArr;
}
Test input:
1 2 3
4 5 6
7 8 9
The method calculates the output array as follows (num1=1.8d and num2=1.8d):
1 2 3 1 2
4 5 6 4 5
7 8 9 7 8
1 2 3 1 2
4 5 6 4 5
Please note that I have changed the signature of the method. It now returns the resulting array.

Image Processing: averaging filter on a grayscale image

I am working on an assignment that asking us to Develop a program that perform averaging filter on a grayscale image with different filter sizes 3x3, 5x5...11x11
First I developed a matrix class in Java:
final public class Matrix {
private final int M; // number of rows
private final int N; // number of columns
private final double[][] data; // M-by-N array
// create M-by-N matrix of 0's
public Matrix(int M, int N) {
this.M = M;
this.N = N;
data = new double[M][N];
}
// create matrix based on 2d array
public Matrix(double [][] data) {
M = data.length;
N = data[0].length;
this.data = new double[M][N];
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
this.data[i][j] = data[i][j];
}
public static Matrix filter(int M, int N) {
Matrix A = new Matrix(M, N);
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
A.data[i][j] = (1.0/9.0);
return A;
}
// copy constructor
private Matrix(Matrix A) { this(A.data); }
// return C = A + B
public Matrix plus(Matrix B) {
Matrix A = this;
if (B.M != A.M || B.N != A.N) throw new RuntimeException("Illegal matrix dimensions.");
Matrix C = new Matrix(M, N);
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
C.data[i][j] = A.data[i][j] + B.data[i][j];
return C;
}
// return C = A - B
public Matrix minus(Matrix B) {
Matrix A = this;
if (B.M != A.M || B.N != A.N) throw new RuntimeException("Illegal matrix dimensions.");
Matrix C = new Matrix(M, N);
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
C.data[i][j] = A.data[i][j] - B.data[i][j];
return C;
}
public boolean eq(Matrix B) {
Matrix A = this;
if (B.M != A.M || B.N != A.N) throw new RuntimeException("Illegal matrix dimensions.");
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
if (A.data[i][j] != B.data[i][j]) return false;
return true;
}
// return C = A * B
public Matrix multiply(Matrix B) {
Matrix A = this;
if (A.N != B.M) throw new RuntimeException("Illegal matrix dimensions.");
Matrix C = new Matrix(A.M, B.N);
for (int i = 0; i < C.M; i++)
for (int j = 0; j < C.N; j++)
for (int k = 0; k < A.N; k++)
C.data[i][j] += (A.data[i][k] * B.data[k][j]);
return C;
}
public double average (){
double sum=0.0;
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
sum = sum + data[i][j];
}
}
return sum;
}
public void show() {
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++)
System.out.printf("%9.4f ", data[i][j]);
System.out.println();
}
}
}
Then I developed my Image filtering application as follows:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
*
* #author Yousra
*/
public class ImgfilterApplication {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Please Enter Your Image Path Here ...");
Scanner myscanner = new Scanner(System.in);
String path = myscanner.next();
BufferedImage img = getImage(path);
int filtersize = 3;
BufferedImage outimg = TDfilter(img, filtersize);
JFrame frame = new JFrame();
JLabel image = new JLabel(new ImageIcon("imageName.png"));
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(new ImageIcon(img)));
frame.getContentPane().add(new JLabel(new ImageIcon(outimg)));
frame.pack();
frame.setVisible(true);
}
public static BufferedImage TDfilter (BufferedImage img, int filtersize){
int w = img.getWidth();
int h = img.getHeight();
WritableRaster cr=img.getRaster();
WritableRaster wr=img.copyData(null);
double[][] imgarray = Img2D(img);
double[][] x = new double[filtersize][filtersize];
Matrix filter = Matrix.filter(filtersize, filtersize);
filter.show();
Matrix imgm = new Matrix(w,h);;
Matrix result;
for (int ii = 0; ii < w; ii++)
for (int jj = 0; jj < h; jj++) {
for (int i = ii; i < filtersize + ii; i++) {
for (int j = jj; j < filtersize + jj; j++) {
if (i - filtersize / 2 < 0 || i - filtersize / 2 >= w || j- filtersize / 2 < 0 || j- filtersize / 2 >= h) {
x[i-ii][j-jj] = 0;
// imgm = new Matrix(x);
} else {
x[i-ii][j-jj] = imgarray[i - filtersize / 2][j - filtersize / 2];
};
}
}
imgm = new Matrix(x);
result = imgm.multiply(filter);
double value = result.average();
wr.setSample(ii, jj, 0, value);
}
BufferedImage img2= new BufferedImage(w, h, img.getType());
img2.setData(wr);
return img2;
}
public static double [][] Img2D(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
double[][] imgarray = new double[w][h] ;
Raster raster = img.getData();
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
imgarray[i][j] = raster.getSample(i, j, 0);
}
}
return imgarray;
}
public static BufferedImage getImage(String imageName) {
try {
File input = new File(imageName);
BufferedImage image = ImageIO.read(input);
return image;
} catch (IOException ie) {
System.out.println("Error:" + ie.getMessage());
}
return null;
}
}
This suppose to make the image more blurry, yet it makes it blurry in parts and negative in others in a random pattern. Can You please help :(
I didn't bother digging through you code. Better post pseudo representation of you algorithm.
Well to address the issue with negative parts of image, this happens when there is an number overflow; e.g. you are trying to make pixel with value 256 depending on used data structures and language, it might happen that the byte roll over 256 and instead the pixel gets value 0.
You need to check that all values you are assigning to image are in range <0-255> for 8-bit grayscale.
I figured out what was wrong. I made the filter a matrix and I multiplied the filter matrix by the image filter then I got the average of the resulting matrix.
To correct this is to pass the filter over the whole image and multiply each pixel by the number that is inside the filter then add it all up.

Categories