Java 使用 3x3 高斯核模糊图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20746172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Blur an image using 3x3 Gaussian kernel?
提问by Taylor
I want to create a method to blur a 24 bit image using 3x3 Gaussian kernel.
我想创建一种使用 3x3 高斯内核模糊 24 位图像的方法。
I was given the following things.
我得到了以下东西。
The 3x3 Gaussian kernel:
3x3 高斯核:
A is the original image and B is the resulting image.
A 是原始图像,B 是结果图像。
B(i,j) =
1/16 * A(i-1,j-1) +1/8 * A(i,j-1) +1/16 * A(i+1,j-1) +1/8 * A(i-1,j) +1/4 * A(i,j) +1/8 *A(i+1,j) +1/16 * A(i-1,j+1) +1/8 * A(i,j+1) +1/16 * A(i+1,j+1)
The method:
方法:
public static BufferedImage gaussianBlur(Image img)
where img is a reference variable of an input image.
The returned value is an address of an object of the resulting image.
其中 img 是输入图像的参考变量。
返回值是结果图像的对象的地址。
Should I divided the image into 9 parts to implement this method?
我应该将图像分成 9 个部分来实现这个方法吗?
回答by herohuyongtao
You don't need to divide it to 9 parts. At least, I don't see a good reason to do this.
您不需要将其分成 9 个部分。至少,我看不出这样做的充分理由。
But you'd better be careful during this process, remember to copy image data to somewhere and always use this data for computation for new image, avoid to use new image data to compute new image.
但是在这个过程中你最好小心一点,记得将图像数据复制到某个地方,并始终使用这些数据来计算新图像,避免使用新图像数据来计算新图像。
Also, I don't understand why you need to write your own function to Gaussian blur a image. This can be easily be done as follows:
另外,我不明白为什么您需要编写自己的函数来对图像进行高斯模糊处理。这可以很容易地完成,如下所示:
float[] matrix = {
1/16f, 1/8f, 1/16f,
1/8f, 1/4f, 1/8f,
1/16f, 1/8f, 1/16f,
};
BufferedImageOp op = new ConvolveOp( new Kernel(3, 3, matrix) );
blurredImage = op.filter(sourceImage, destImage);
回答by A_P
Don't divide it into parts. what if you have big image. what you should do is to first write a function that checks if the filter is within the image bounds. in C it would be some thing like this:
不要把它分成几部分。如果你有大图像怎么办。您应该做的是首先编写一个函数来检查过滤器是否在图像边界内。在 C 中,它会是这样的:
int filterWithinImage(Matrix m1, Matrix m2, int i, int j) {
int b; //min number of pixels that the center of the filter needs to be
// away from any border of the image to be inbounds
/***********************odd size filter only*************************/
//when filter size is odd there is well defined convenient center
// of the filter
if (isOdd(m2.height) && isOdd(m2.width)) {
//to check the bounds subtract 1 from the width and divide by 2
b = (m2.width - 1) / 2;
//look at the left border
if ((j - b)<0) return 0;
//top border
if ((i - b)<0) return 0;
//right border
if ((j + b)>(m1.width-1)) return 0;
//bottom border
if ((i + b)>(m1.height -1)) return 0;
}
return 1;
}
than write separate function for calculating the intensities:
比编写单独的函数来计算强度:
double calculateValue(Matrix m1,Matrix m2,int imagei, int imagej) {
double out = 0;//return value
int i, j, fli, flj; //for iterating over the filter
int b = (m2.height -1) / 2;//max number that we add to the center coordinates
//to get to the edge of the filter
fli = 0; flj = 0;
for(i = imagei - b; i < imagei + b +1; i++) {
for(j = imagej - b; j < imagej + b +1; j++) {
// if (i == 599)
//printf("calc func image i: %d, image j %d, b %d, filter i %d, filter j %d\n",
// i,j,b,fli,flj);
out += m1.map[i][j] * m2.map[fli][flj++];
}
fli++;
flj=0;
}
return out;
}
then just write applyFilter m2 is the filter that you need to rotate 180 degrees.Matrix applyFilter(Matrix m1, Matrix m2) { int x,y; //rotate filter firstMatrix rotFilter = createMatrix(m2.height,m2.width); for (x = 0; x < m2.height; x++) for (y = 0; y < m2.width; y++) { rotFilter.map[y][x] = m2.map[m2.height-y-1][m2.width-x-1]; }
然后只需写 applyFilter m2 是您需要旋转 180 度的过滤器。矩阵 applyFilter(Matrix m1, Matrix m2) { int x,y; //先旋转过滤器Matrix rotFilter = createMatrix(m2.height,m2.width); for (x = 0; x < m2.height; x++) for (y = 0; y < m2.width; y++) { rotFilter.map[y][x] = m2.map[m2.height-y-1 ][m2.width-x-1]; }
Matrix mOut = createMatrix(m1.height, m1.width);
int i,j;
for (i = 0; i < m1.height; i++) {
for (j = 0; j < m1.width; j++) {
if (!filterWithinImage(m1,rotFilter,i,j)) { //filter is out of bounds
mOut.map[i][j] = 0;
}
else {
mOut.map[i][j] = calculateValue(m1,rotFilter,i,j);
}
}
}
return mOut;
}
this is a general approach that would have to modified to fit java data structures, but the algorithms are the same.
这是一种必须修改以适应 java 数据结构的通用方法,但算法是相同的。