我目前正在做一个项目,需要我阅读图像并放大它们。
我目前正在使用最近邻算法来放大我的图像,但我正在尝试使用双线性插值,发现很难实现。
这是我目前的 NN 算法:
public void doThumbnailResize() {
resizedImage = new BufferedImage(55, 55, BufferedImage.TYPE_3BYTE_BGR);
int h = resizedImage.getHeight(), h2 = image1.getHeight();
int w = resizedImage.getWidth(), w2 = image1.getWidth();
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
float y = j * ((float) h2 / (float) h);
float x = i * ((float) w2 / (float) w);
resizedImage.setRGB(i, j, image1.getRGB((int) x, (int) y));
}
}
image_icon.setIcon(new ImageIcon(resizedImage));
}
我发现很难在网上找到材料,并且想知道是否有人可以指出我正确的方向,也许还有一些伪代码。
提前谢谢。
双线性插值基本上适用于插值 4 个像素的正方形。您首先要查找最近的邻居,即目标像素映射到哪个源像素,以及相对于该像素的位置。然后,创建一个宽高一个目标像素大小的框,并检查该框与哪些像素相交(最多 4 个),并计算该重叠与框大小的关系。然后,该百分比将应用于颜色并添加到最终颜色中。
例:
假设我们有一个这样的 9x9 图像(每个字符表示一个像素):
ABC
DEF
GHI
现在我们想将其放大到 4x4 并计算第一个像素的插值 (0/0):
- 目标像素的相对大小为 (3/4,3/4),即每个目标像素跨越源像素宽度和高度的 0.75
- 像素 A 的纹理坐标范围为 (0,0) 到 (0.333,0.333)
- 我们的第一个目标像素的中心位于 (0.125,0.125) (1/宽度 * 0.5, 1/高度 * 0.5),因此目标框将跨越坐标 (0.0, 0.0) 到 (0.25,0.25)
- 如您所见,我们的第一个目标像素完全位于源像素 A 内,从而获得 A 的颜色。
现在对于第二个像素 (1/0):
- 第二个目标像素的中心位于 (0.375,0.125),因此跨越坐标 (0.25,0.0) 到 (0.5,0.25)
- 如您所见,这将重叠源像素 A、B、D 和 E
- 目标框的面积为 0.25 * 0.25 = 0.0625
- 与 A 重叠的面积为 (0.333-0.25) * (0.25 - 0) ~= 0.02075
- 因此,我们大约 33% 的目标像素框与 A 重叠
- B 的重叠为 ((0.5-0333) * (0.25 - 0))/0.0625 ~= 67%
- 因此,目标像素的颜色将是 A 颜色的 33% + B 颜色的 67%
让我们考虑另一个像素,这次(1/1):
- A 的重叠为:((0.333 - 0.25)
- * (0.333 - 0.25))/0.0625 ~= 11%
- B 的重叠将是:((0.5-0.333) * (0.333 - 0.25))/0.0625 ~= 22%
- D 的重叠为:((0.333 - 0.25) * (0.5-0.333) )/0.0625 ~= 22%
- E 的重叠将是:((0.5-0.333) * (0.5-0.333) )/0.0625 ~= 45%
- 因此,目标像素 (1/1) 的颜色将为 11% A + 22% B + 22% D + 45% E