图像的放大与缩小(2)——双线性插值放大与均值缩小
2019獨角獸企業重金招聘Python工程師標準>>>
概述
基于上一節“等距采樣法”實現圖片放大與縮小的缺點。要對其進行改進,對圖像的縮小則可以用“局部均值法”,對于圖像的放大則可以用“雙線性插值法”。
效果如下:
?? ? ?
? ? ? ? ? ? ? ? ? ?2048*1536縮小為100*80時的效果 ? ? ? ? ? ? ??100*80放大到600*400的效果
局部均值法縮小圖像
(1)計算采樣間隔
設原圖的大小為W*H,將其放大(縮小)為(k1*W)*(K2*H),則采樣區間為
ii=1/k1;?????? jj=1/k2;
當k1==k2時為等比例縮小;當k1!=k2時為不等比例放大(縮小);當k1<1 && k2<1時為圖片縮小,k1>1 && k2>1時圖片放大。
(2)求出局部子塊
設原圖為F(x,y)(i=1,2,……W; j=1,2,……H),縮小的圖像為G(x,y)(x=1,2, ……M; y=1,2,……N,其中M=W*k1,N=H*k2),則有原圖像局部子塊為
f’(x,y)?= f(ii*i, jj*j) ? ? ? ?…… f(ii*i + ii-1, jj*j)
? ? ? ? ? ? ? ? …… ? ? ? ? ? ? ? ? ? ……
? ? ? ? ? ? ?f(ii*i, jj*j+jj-1) …… f(ii*i + ii-1, jj*j+jj-1)
(3)求出縮小的圖像
G(x, y) = f’(x,y)的均值
例:
縮小后的圖像
?
?
例如g11=(f11 +f12 + f21 + f22)/4
?
算法源代碼(java)
/*** 局部均值的圖像縮小* @param img 要縮小的圖像對象* @param m 縮小后圖像的寬* @param n 縮小后圖像的高* @return 返回處理后的圖像對象*/public static BufferedImage shrink(BufferedImage img, int m, int n) {float k1 = (float)m/img.getWidth();float k2 = (float)n/img.getHeight(); return shrink(img, k1, k2);}/*** 局部均值的圖像縮小* @param img 要縮小的圖像對象* @param k1 要縮小的列比列* @param k2 要縮小的行比列* @return 返回處理后的圖像對象*/public static BufferedImage shrink(BufferedImage img, float k1, float k2) {if(k1 >1 || k2>1) {//如果k1 >1 || k2>1則是圖片放大,不是縮小System.err.println("this is shrink image funcation, please set k1<=1 and k2<=1!");return null;} float ii = 1/k1; //采樣的行間距float jj = 1/k2; //采樣的列間距 int dd = (int)(ii*jj); //int m=0 , n=0; int imgType = img.getType();int w = img.getWidth();int h = img.getHeight();int m = (int) (k1*w);int n = (int) (k2*h);int[] pix = new int[w*h];pix = img.getRGB(0, 0, w, h, pix, 0, w);System.out.println(w + " * " + h);System.out.println(m + " * " + n);int[] newpix = new int[m*n];for(int j=0; j<n; j++) {for(int i=0; i<m; i++) {int r = 0, g=0, b=0;ColorModel cm = ColorModel.getRGBdefault(); for(int k=0; k<(int)jj; k++) {for(int l=0; l<(int)ii; l++) {r = r + cm.getRed(pix[(int)(jj*j+k)*w + (int)(ii*i+l)]);g = g + cm.getGreen(pix[(int)(jj*j+k)*w + (int)(ii*i+l)]);b = b + cm.getBlue(pix[(int)(jj*j+k)*w + (int)(ii*i+l)]);}}r = r/dd;g = g/dd;b = b/dd;newpix[j*m + i] = 255<<24 | r<<16 | g<<8 | b;//255<<24 | r<<16 | g<<8 | b 這個公式解釋一下,顏色的RGB在內存中是//以二進制的形式保存的,從右到左1-8位表示blue,9-16表示green,17-24表示red//所以"<<24" "<<16" "<<8"分別表示左移24,16,8位//newpix[j*m + i] = new Color(r,g,b).getRGB();}}BufferedImage imgOut = new BufferedImage( m, n, imgType);imgOut.setRGB(0, 0, m, n, newpix, 0, m); return imgOut;}
? /*** 局部均值的圖像縮小* @param img 要縮小的圖像對象* @param m 縮小后圖像的寬* @param n 縮小后圖像的高* @return 返回處理后的圖像對象*/public static BufferedImage shrink(BufferedImage img, int m, int n) {float k1 = (float)m/img.getWidth();float k2 = (float)n/img.getHeight(); return shrink(img, k1, k2);}/*** 局部均值的圖像縮小* @param img 要縮小的圖像對象* @param k1 要縮小的列比列* @param k2 要縮小的行比列* @return 返回處理后的圖像對象*/public static BufferedImage shrink(BufferedImage img, float k1, float k2) {if(k1 >1 || k2>1) {//如果k1 >1 || k2>1則是圖片放大,不是縮小System.err.println("this is shrink image funcation, please set k1<=1 and k2<=1!");return null;} float ii = 1/k1; //采樣的行間距float jj = 1/k2; //采樣的列間距 int dd = (int)(ii*jj); //int m=0 , n=0; int imgType = img.getType();int w = img.getWidth();int h = img.getHeight();int m = (int) (k1*w);int n = (int) (k2*h);int[] pix = new int[w*h];pix = img.getRGB(0, 0, w, h, pix, 0, w);System.out.println(w + " * " + h);System.out.println(m + " * " + n);int[] newpix = new int[m*n];for(int j=0; j<n; j++) {for(int i=0; i<m; i++) {int r = 0, g=0, b=0;ColorModel cm = ColorModel.getRGBdefault(); for(int k=0; k<(int)jj; k++) {for(int l=0; l<(int)ii; l++) {r = r + cm.getRed(pix[(int)(jj*j+k)*w + (int)(ii*i+l)]);g = g + cm.getGreen(pix[(int)(jj*j+k)*w + (int)(ii*i+l)]);b = b + cm.getBlue(pix[(int)(jj*j+k)*w + (int)(ii*i+l)]);}}r = r/dd;g = g/dd;b = b/dd;newpix[j*m + i] = 255<<24 | r<<16 | g<<8 | b;//255<<24 | r<<16 | g<<8 | b 這個公式解釋一下,顏色的RGB在內存中是//以二進制的形式保存的,從右到左1-8位表示blue,9-16表示green,17-24表示red//所以"<<24" "<<16" "<<8"分別表示左移24,16,8位//newpix[j*m + i] = new Color(r,g,b).getRGB();}}BufferedImage imgOut = new BufferedImage( m, n, imgType);imgOut.setRGB(0, 0, m, n, newpix, 0, m); return imgOut;}
雙線性差值法放圖像
子塊四個頂點的坐標分別設為(0,0)、(1,0)、(0,1)、(1,1),對應的帶處理的像素的坐標(c1,c2),0<c1<1, 0<y<1.則f(x,y)由上到下得到
例,原圖的像素矩陣如下。
將其放大成2.5*1.2倍,雙線性插值發,填充頂點如下:
(1)
?
(2)
1? 2? 3? 4? 5? 6? 7? 7
2? 3? 4? 5? 7? 8? 8? 8
3? 4? 5? 6? 7? 8? 9? 9
3? 4? 5? 6? 7? 8? 9? 9
(3)
算法源代碼(java)
轉載于:https://my.oschina.net/verynix/blog/365861
總結
以上是生活随笔為你收集整理的图像的放大与缩小(2)——双线性插值放大与均值缩小的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java编写提升性能的代码
- 下一篇: SSH框架总结(框架分析+环境搭建+实例