拉普拉斯滤波器产生奇怪的结果 (Java)
Laplacian filter produces weird results (Java)
我正在尝试应用
[-1][-1][-1]
[-1][8][-1]
[-1][-1][-1]
3*3 拉普拉斯滤镜到此处著名照片(png 扩展名)的灰度版本。
我主要是用BufferedImage
class来处理图片。这是拉普拉斯滤波器方法。
private BufferedImage measureContrast(BufferedImage image) {
BufferedImage grayScale = createGrayscaleImage(image);
BufferedImage copy = copyImage(grayScale);
int width = image.getWidth();
int height = image.getHeight();
int sum=0;
int a;
//3*3 Laplacian filter (-1,-1,-1), (-1,8,-1), (-1,-1,-1)
for(int y=1;y<height-1;y++)
for(int x=1;x<width-1;x++) {
sum = (-1*(grayScale.getRGB(x-1, y-1)&0xff)) + (-1*(grayScale.getRGB(x, y-1)&0xff)) + (-1*(grayScale.getRGB(x+1, y-1)&0xff))
+ (-1*(grayScale.getRGB(x-1, y)&0xff)) + (8*(grayScale.getRGB(x,y)&0xff)) + (-1*(grayScale.getRGB(x+1, y)&0xff)) +
(-1*(grayScale.getRGB(x-1, y+1)&0xff)) + (-1*(grayScale.getRGB(x, y+1)&0xff)) + (-1*(grayScale.getRGB(x+1, y+1)&0xff));
a = ((grayScale.getRGB(x, y)>>24)&0xff);
copy.setRGB(x, y, ((a<<24)|(sum<<16)|(sum<<8)|(sum)));
}
return copy;
如果我运行那个代码,结果就是这样
这显然是错误的。图像中突然出现奇怪的粗线。
我可以保证灰度版本是正确的,因为当我在应用过滤器之前 运行 以下代码时,输出给出了完美的灰度图像。
private BufferedImage measureContrast(BufferedImage image) {
BufferedImage grayScale = createGrayscaleImage(image);
BufferedImage copy = copyImage(grayScale); /*rest of the code is commented*/
return copy;
几个小时以来,我一直在努力寻找问题所在,但我认为代码没有任何问题...任何见解都将不胜感激。提前致谢!
为了复制图像,我使用了以下代码。我从 stack overflow 中的一个选择的答案中借用了它,所以我认为它不会错。
BufferedImage copyImage(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
另外,结果图是这样打印的
BufferedImage Contrast = measureContrast(image);
//write image
try {
ImageIO.write(Contrast, "png", new File(outputPath));
System.out.println("Printing complete");
}catch(IOException e) {
System.out.println("File Printing Error: "+e);
}
为了以防万一,这里给出灰度图的制作方法
private BufferedImage createGrayscaleImage(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
BufferedImage copy = copyImage(image);
int p=0, a=0, r=0, g=0, b=0, avg=0;
for(int y=0;y<height;y++)
for(int x=0;x<width;x++) {
p=image.getRGB(x, y);
a=(p>>24)&0xff;
r=(p>>16)&0xff;
g=(p>>8)&0xff;
b=p&0xff;
avg = (r+g+b)/3;
p = (a<<24) | (avg<<16) | (avg<<8) | avg;
copy.setRGB(x, y, p);
}
return copy;
}
private BufferedImage measureContrast(BufferedImage image) {
BufferedImage grayScale = createGrayscaleImage(image);
BufferedImage copy = copyImage(grayScale);
int width = image.getWidth();
int height = image.getHeight();
int sum=0;
int a;
//3*3 Laplacian filter (-1,-1,-1), (-1,8,-1), (-1,-1,-1)
for(int y=1;y<height-1;y++)
for(int x=1;x<width-1;x++) {
sum = (-1*(grayScale.getRGB(x-1, y-1)&0xff)) + (-1*(grayScale.getRGB(x, y-1)&0xff)) + (-1*(grayScale.getRGB(x+1, y-1)&0xff))
+ (-1*(grayScale.getRGB(x-1, y)&0xff)) + (8*(grayScale.getRGB(x,y)&0xff)) + (-1*(grayScale.getRGB(x+1, y)&0xff)) +
(-1*(grayScale.getRGB(x-1, y+1)&0xff)) + (-1*(grayScale.getRGB(x, y+1)&0xff)) + (-1*(grayScale.getRGB(x+1, y+1)&0xff));
a = ((grayScale.getRGB(x, y)>>24)&0xff);
copy.setRGB(x, y, ((a<<24)|(sum<<16)|(sum<<8)|(sum)));
}
return copy;
这个方法是错误的。我应该考虑 sum 何时为负值。所以我在嵌套的 for 循环中添加了 sum = (sum>0)?sum:0;
以确保在这些情况下像素值为 0。
我正在尝试应用
[-1][-1][-1]
[-1][8][-1]
[-1][-1][-1]
3*3 拉普拉斯滤镜到此处著名照片(png 扩展名)的灰度版本。
我主要是用BufferedImage
class来处理图片。这是拉普拉斯滤波器方法。
private BufferedImage measureContrast(BufferedImage image) {
BufferedImage grayScale = createGrayscaleImage(image);
BufferedImage copy = copyImage(grayScale);
int width = image.getWidth();
int height = image.getHeight();
int sum=0;
int a;
//3*3 Laplacian filter (-1,-1,-1), (-1,8,-1), (-1,-1,-1)
for(int y=1;y<height-1;y++)
for(int x=1;x<width-1;x++) {
sum = (-1*(grayScale.getRGB(x-1, y-1)&0xff)) + (-1*(grayScale.getRGB(x, y-1)&0xff)) + (-1*(grayScale.getRGB(x+1, y-1)&0xff))
+ (-1*(grayScale.getRGB(x-1, y)&0xff)) + (8*(grayScale.getRGB(x,y)&0xff)) + (-1*(grayScale.getRGB(x+1, y)&0xff)) +
(-1*(grayScale.getRGB(x-1, y+1)&0xff)) + (-1*(grayScale.getRGB(x, y+1)&0xff)) + (-1*(grayScale.getRGB(x+1, y+1)&0xff));
a = ((grayScale.getRGB(x, y)>>24)&0xff);
copy.setRGB(x, y, ((a<<24)|(sum<<16)|(sum<<8)|(sum)));
}
return copy;
如果我运行那个代码,结果就是这样
这显然是错误的。图像中突然出现奇怪的粗线。
我可以保证灰度版本是正确的,因为当我在应用过滤器之前 运行 以下代码时,输出给出了完美的灰度图像。
private BufferedImage measureContrast(BufferedImage image) {
BufferedImage grayScale = createGrayscaleImage(image);
BufferedImage copy = copyImage(grayScale); /*rest of the code is commented*/
return copy;
几个小时以来,我一直在努力寻找问题所在,但我认为代码没有任何问题...任何见解都将不胜感激。提前致谢!
为了复制图像,我使用了以下代码。我从 stack overflow 中的一个选择的答案中借用了它,所以我认为它不会错。
BufferedImage copyImage(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
另外,结果图是这样打印的
BufferedImage Contrast = measureContrast(image);
//write image
try {
ImageIO.write(Contrast, "png", new File(outputPath));
System.out.println("Printing complete");
}catch(IOException e) {
System.out.println("File Printing Error: "+e);
}
为了以防万一,这里给出灰度图的制作方法
private BufferedImage createGrayscaleImage(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
BufferedImage copy = copyImage(image);
int p=0, a=0, r=0, g=0, b=0, avg=0;
for(int y=0;y<height;y++)
for(int x=0;x<width;x++) {
p=image.getRGB(x, y);
a=(p>>24)&0xff;
r=(p>>16)&0xff;
g=(p>>8)&0xff;
b=p&0xff;
avg = (r+g+b)/3;
p = (a<<24) | (avg<<16) | (avg<<8) | avg;
copy.setRGB(x, y, p);
}
return copy;
}
private BufferedImage measureContrast(BufferedImage image) {
BufferedImage grayScale = createGrayscaleImage(image);
BufferedImage copy = copyImage(grayScale);
int width = image.getWidth();
int height = image.getHeight();
int sum=0;
int a;
//3*3 Laplacian filter (-1,-1,-1), (-1,8,-1), (-1,-1,-1)
for(int y=1;y<height-1;y++)
for(int x=1;x<width-1;x++) {
sum = (-1*(grayScale.getRGB(x-1, y-1)&0xff)) + (-1*(grayScale.getRGB(x, y-1)&0xff)) + (-1*(grayScale.getRGB(x+1, y-1)&0xff))
+ (-1*(grayScale.getRGB(x-1, y)&0xff)) + (8*(grayScale.getRGB(x,y)&0xff)) + (-1*(grayScale.getRGB(x+1, y)&0xff)) +
(-1*(grayScale.getRGB(x-1, y+1)&0xff)) + (-1*(grayScale.getRGB(x, y+1)&0xff)) + (-1*(grayScale.getRGB(x+1, y+1)&0xff));
a = ((grayScale.getRGB(x, y)>>24)&0xff);
copy.setRGB(x, y, ((a<<24)|(sum<<16)|(sum<<8)|(sum)));
}
return copy;
这个方法是错误的。我应该考虑 sum 何时为负值。所以我在嵌套的 for 循环中添加了 sum = (sum>0)?sum:0;
以确保在这些情况下像素值为 0。