问题
I am trying to create a guassian filter without using ConvolveOp. I am having a lot of problems trying to get this to work, i have gotten a grey scale filter to work, but for this one i am having problems finding the location of a pixels 8 neighbors, so i can apply the filter. here is what i have so far. Is this the right way to approach getting each of the pixels?
public class Gaussian implements Filter {
public void filter(PixelImage pi) {
Pixel[][] data = pi.getData();
Pixel[][] original = data;
int kernel_rows = 3;
int kernel_cols = 3;
// define kernel here (double loop), these are the 1/16, 2/16, etc...
// values that you're multiplying the image pixels by
double[][] kernel = {{1,2,1},
{2,4,2},
{1,2,1}};
// iterate over each pixel in the image
for (int row = 0; row < pi.getHeight(); row ++) {
for (int col = 0; col < pi.getWidth(); col++) {
// iterate over each pixel in the kernel
for (int row_offset = 0 ; row_offset < kernel_rows ; row_offset++ ) {
for (int col_offset = 0 ; col_offset < kernel_cols ; col_offset++ ) {
// subtract by half the kernel size to center the kernel
// on the pixel in question
// ** you'll have to modify to account for boundary conditions **
int row_index = row + row_offset - kernel_rows/2;
int col_index = col + col_offset - kernel_cols/2;
int r =0;
int g =0;
int b =0;
r += (data[row_index][col_index].red * kernel[row_offset][col_offset])/16;
g += (data[row_index][col_index].green * kernel[row_offset][col_offset])/16;
b += (data[row_index][col_index].blue * kernel[row_offset][col_offset])/16;
Pixel temp =new Pixel( r, g, b );
original[row][col] = temp;
}
}
data = original;
pi.setData(data);
}
}
}
}
回答1:
A convolution is essentially a quadruple nested loop: two to loop through the pixels in the image and, at each pixel, two to loop over the pixels in the kernel.
So you can clean up your code significantly with something like this:
int kernel_rows = 3;
int kernel_cols = 3;
// define kernel here (double loop), these are the 1/16, 2/16, etc...
// values that you're multiplying the image pixels by
double[][] kernel = ...
// iterate over each pixel in the image
// leave a kernel_rows/2 sized gap around the edge of the image
// so that we don't run into IndexOutOfBounds exceptions
// when performing the convolution
for (int row = kernel_rows/2; row < pi.getHeight() - kernel_rows/2; row ++) {
for (int col = kernel_cols/2; col < pi.getWidth() - kernel_cols/2; col++) {
int r = 0;
int g = 0;
int b = 0;
// iterate over each pixel in the kernel
for (int row_offset = 0 ; row_offset < kernel_rows ; row_offset++ ) {
for (int col_offset = 0 ; col_offset < kernel_cols ; col_offset++ ) {
// subtract by half the kernel size to center the kernel
// on the pixel in question
int row_index = row + row_offset - kernel_row/2;
int col_index = col + col_offset - kernel_cols/2
r += data[row_index][col_index].red * kernel[row_offset][col_offset];
g += data[row_index][col_index].green * kernel[row_offset][col_offset];
b += data[row_index][col_index].blue * kernel[row_offset][col_offset];
}
}
data[row][col] = new Pixel( r, g, b );
}
}
来源:https://stackoverflow.com/questions/10150739/gaussian-filter-without-using-convolveop