概述
基于上一节“等距采样法”实现图片放大与缩小的缺点。要对其进行改进,对图像的缩小则可以用“局部均值法”,对于图像的放大则可以用“双线性插值法”。
效果如下:
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)(i=1,2, ……M; j=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)