不使用ConvolveOp的高斯滤波器 [英] Gaussian Filter without using ConvolveOp
问题描述
我正在尝试在不使用ConvolveOp的情况下创建一个guassian过滤器。
我有很多问题试图让它工作,我已经得到一个灰度过滤器工作,但对于这一个我有问题找到一个像素8邻居的位置,所以我可以应用过滤。这是我到目前为止所拥有的。这是获得每个像素的正确方法吗?
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);
}
}
}
}
推荐答案
卷积本质上是一个四重嵌套循环:两个循环遍历图像中的像素,并且在每个像素处,两个循环遍历内核中的像素。
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 );
}
}
这篇关于不使用ConvolveOp的高斯滤波器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!