拉普拉斯是使用二阶微分锐化图像,以3*3滤波器中心像素与上下左右像素计算差值,计算公式为:
一阶微分梯度锐化,以3*3滤波器中心像素上方三个像素之和减去下方三个像素之和的绝对值,与左边三个像素减去右边三个像素之和的绝对值,将两个绝对值相加作为中心像素值,公式:
通过java代码实现两种锐化算法,代码如下:
package ImageFilter;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class ImageSharpen {
// singleton
private static ImageSharpen imageSharpen = new ImageSharpen();
private ImageSharpen() {
}
public static ImageSharpen getInstance() {
return imageSharpen;
}
/**
* 图像锐化 二阶微分锐化,拉普拉斯算子 定义一个3*3滤波器,计算中心像素与上下左右四个像素差值
*
* @param image
*/
public BufferedImage lapLaceSharpDeal(BufferedImage image) {
BufferedImage tempImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
for (int i = 1; i < image.getWidth() - 1; i++) {
for (int j = 1; j < image.getHeight() - 1; j++) {
int rgb = image.getRGB(i, j);
int rgb1 = image.getRGB(i - 1, j);
int rgb2 = image.getRGB(i + 1, j);
int rgb3 = image.getRGB(i, j - 1);
int rgb4 = image.getRGB(i, j + 1);
int[] R = new int[] { (rgb1 >> 16) & 0xff, (rgb2 >> 16) & 0xff, (rgb3 >> 16) & 0xff,
(rgb4 >> 16) & 0xff, (rgb >> 16) & 0xff };
int[] G = new int[] { (rgb1 >> 8) & 0xff, (rgb2 >> 8) & 0xff, (rgb3 >> 8) & 0xff, (rgb4 >> 8) & 0xff,
(rgb >> 8) & 0xff };
int[] B = new int[] { rgb1 & 0xff, rgb2 & 0xff, rgb3 & 0xff, rgb4 & 0xff, rgb & 0xff };
double dR = R[0] + R[1] + R[2] + R[3] - 4 * R[4];
double dG = G[0] + G[1] + G[2] + G[3] - 4 * G[4];
double dB = B[0] + B[1] + B[2] + B[3] - 4 * B[4];
double r = R[4] - dR;
double g = G[4] - dG;
double b = B[4] - dB;
rgb = (255 & 0xff) << 24 | (clamp((int) r) & 0xff) << 16 | (clamp((int) g) & 0xff) << 8
| (clamp((int) b) & 0xff);
tempImage.setRGB(i, j, rgb);
}
}
return tempImage;
}
/**
* 一阶微分梯度锐化
*/
public BufferedImage degreeSharpDeal(BufferedImage image) {
BufferedImage tempImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
for (int i = 1; i < image.getWidth() - 1; i++) {
for (int j = 1; j < image.getHeight() - 1; j++) {
List<Integer> rList = new ArrayList<>();
List<Integer> gList = new ArrayList<>();
List<Integer> bList = new ArrayList<>();
for (int x = -1; x < 2; x++) {
for (int y = -1; y < 2; y++) {
int rgb = image.getRGB(i + x, j + y);
int R = (rgb >> 16) & 0xff;
int G = (rgb >> 8) & 0xff;
int B = rgb & 0xff;
rList.add(R);
gList.add(G);
bList.add(B);
}
}
int r = getResult(rList);
int g = getResult(gList);
int b = getResult(bList);
r = rList.get(4) + r / 4;
g = gList.get(4) + g / 4;
b = bList.get(4) + b / 4;
int rgb = (255 & 0xff) << 24 | (clamp(r) & 0xff) << 16 | (clamp(g) & 0xff) << 8 | (clamp(b) & 0xff);
tempImage.setRGB(i, j, rgb);
}
}
return tempImage;
}
// 执行一阶微分计算
private int getResult(List<Integer> list) {
int result = Math.abs(list.get(0) + list.get(3) + list.get(6) - list.get(2) - list.get(5) - list.get(8))
+ Math.abs(list.get(0) + list.get(1) + list.get(2) - list.get(6) - list.get(7) - list.get(8));
return result;
}
// 判断a,r,g,b值,大于256返回256,小于0则返回0,0到256之间则直接返回原始值
private int clamp(int rgb) {
if (rgb > 255)
return 255;
if (rgb < 0)
return 0;
return rgb;
}
}
测试类:
package ImageFilter;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class test {
public static void main(String[] args) throws Exception{
File input = new File("E:/桌面/AverageFilter/1.jpg");
File output = new File("E:/桌面/AverageFilter/3.jpg");
BufferedImage image = ImageIO.read(input);
BufferedImage image2 = ImageSharpen.getInstance().degreeSharpDeal(image);
ImageIO.write(image2, "jpg", output);
}
}
原图:
拉普拉斯锐化结果:
一阶微分梯度锐化结果:
原图是一张比较模糊的图像,对比两种锐化方式,不难看出,拉普拉斯锐化效果明显,但是容易加重噪点;一阶微分梯度锐化对于图像较平坦区域有所保留,对图像边缘锐化效果更加突出,因此在图像分割和边缘检测方面会用到更多梯度处理。