图像处理之双线性插值原理和实现
雙線性內插原理:
由于圖像數據組成為等間距橫向和縱向分布的像素點構成,點與點之間間距為一個像素,那么對圖像的內插,就可以當做在每個像素內橫向和縱向均勻增加點,每個點的像素值則由周圍四個點確定。
假設當點P(x,y)位于P1(x1,y1)、P2(x2,y2)、P3(x3,y3)和P4(x4,y4)四個點構成的矩陣內,如圖所示:
設定四個點像素值為p1、p2、p3、p4,中間P點像素為p,P點像素值通過P1-P4四個點像素進行擬合。這里采用距離加權的方法對內插點像素進行賦值,即通過計算P點坐標與其他幾個點距離來確定每個值所占權重,假設P點剛好位于矩陣中心,那么p剛好等于p1-p4的均值。
問題的核心在于如何計算P點與周圍四個點距離,由于P點在矩陣內,假設一個矩陣邊長為1,x和y與周圍點坐標的差值都小于等于1,那么可以通過如下公式來計算p點像素值:
p=p1 * [(1 - |x - x1|) * (1 - |y - y1|)] + p2 * [(1 - |x - x2|) * (1 - |y - y2|)] + p3 * [(1 - |x - x3|) * (1 - |y-y3|)] + p4 * [(1 -|x - x4|) * (1 - |y-y4|)]
通過以上公式,當P點位于矩陣中心時,x-x1=0.5,y-y1=0.5,P1點權重為0.5*0.5=0.25,P2到P4點權重也一樣是0.25,如果P點剛好位于P1-P4點任意一點上,通過公式計算結果也是p1-p4。
代碼:
double result = p1 * ((1 - Math.abs(x - x1)) * (1 - Math.abs(y - y1)))+ p2 * ((1 - Math.abs(x - x2)) * (1 - Math.abs(y - y2)))+ p3 * ((1 - Math.abs(x - x3)) * (1 - Math.abs(y - y3))) + p4 * ((1 - Math.abs(x - x4)) * (1 - Math.abs(y - y4)));假設P1 = 100.25, p2= 120.23, p3 = 103.49, p4 = 105.66,P點坐標為(0.2,0.3),計算結果p=112.217,四個點均值為107.4075,P點坐標最接近P2點,P2點最高,因此P點像素大于均值也更符合預期。
圖像雙線性內插的實現:
測試代碼:
import java.awt.image.BufferedImage; import java.io.File;import javax.imageio.ImageIO;/*** 雙線性內插* * @author chen**/ public class BilinearInterpolation {public void interpolation(File inputFile, File destFile, int interpolation) throws Exception {BufferedImage inImage = ImageIO.read(inputFile);int width = inImage.getWidth();int height = inImage.getHeight();int destWidth = (width - 1) * interpolation;int destHeight = (height - 1) * interpolation;destFile.createNewFile();BufferedImage destImage = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);for (int i = 0; i < destWidth; i++) {for (int j = 0; j < destHeight; j++) {double x = (double) i / (double) interpolation;double y = (double) j / (double) interpolation;int x1 = (int) x;int x2 = x1;int x3 = x1 + 1;int x4 = x3;int y1 = (int) y + 1;int y2 = y1 - 1;int y3 = y2;int y4 = y1;int p1 = inImage.getRGB(x1, y1);int p2 = inImage.getRGB(x2, y2);int p3 = inImage.getRGB(x3, y3);int p4 = inImage.getRGB(x4, y4);int R = caculateValue(x, y, x1, x2, x3, x4, y1, y2, y3, y4, (p1 >> 16) & 0xff, (p2 >> 16) & 0xff,(p3 >> 16) & 0xff, (p4 >> 16) & 0xff);int G = caculateValue(x, y, x1, x2, x3, x4, y1, y2, y3, y4, (p1 >> 8) & 0xff, (p2 >> 8) & 0xff,(p3 >> 8) & 0xff, (p4 >> 8) & 0xff);int B = caculateValue(x, y, x1, x2, x3, x4, y1, y2, y3, y4, p1 & 0xff, p2 & 0xff, p3 & 0xff,p4 & 0xff);int rgb = (255 & 0xff) << 24 | (R & 0xff) << 16 | ( G & 0xff) << 8| ( B & 0xff);destImage.setRGB(i, j, rgb);}}ImageIO.write(destImage, "JPG", destFile);}private int caculateValue(double x, double y, int x1, int x2, int x3, int x4, int y1, int y2, int y3, int y4,double p1, double p2, double p3, double p4) {int result = (int) (p1 * ((1 - Math.abs(x - x1)) * (1 - Math.abs(y - y1)))+ p2 * ((1 - Math.abs(x - x2)) * (1 - Math.abs(y - y2)))+ p3 * ((1 - Math.abs(x - x3)) * (1 - Math.abs(y - y3)))+ p4 * ((1 - Math.abs(x - x4)) * (1 - Math.abs(y - y4))));return result;}public static void main(String[] args) throws Exception {new BilinearInterpolation().interpolation(new File("C:\\Users\\admin\\Desktop\\test\\1.png"),new File("C:\\Users\\admin\\Desktop\\test\\11.jpg"), 10);} }?
總結
以上是生活随笔為你收集整理的图像处理之双线性插值原理和实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 匀光匀色--直方图匹配算法实现与应用
- 下一篇: 图像处理之添加图像水印