首页 > 编程知识 正文

lanczos算法原理,lanczos

时间:2023-05-05 21:05:34 阅读:277194 作者:1702

图像处理之Lanczos采样放缩算法

一:什么是Lanczos采样

参见这里:http://en.wikipedia.org/wiki/Lanczos_resampling

二:大致算法流程


三:算法运行结果

1.向下采样, 生成缩略图, 左边为原图,右边为缩略图


向上采样,生成放大图像时效果:


算法源代码:

package com.gloomyfish.壮观的导师.study; import java.awt.p_w_picpath.BufferedImage; import java.awt.p_w_picpath.ColorModel; import com.gloomyfish.filter.study.AbstractBufferedImageOp; public class LanczosScaleFilter extends AbstractBufferedImageOp { // lanczos_size private float lanczosSize; private float destWidth; public LanczosScaleFilter() { lanczosSize = 3; destWidth = 100; } public LanczosScaleFilter(float lobes, int width) { this.lanczosSize = lobes; this.destWidth = width; } public void setLanczosSize(float size) { this.lanczosSize = size; } public void setDestWidth(float destWidth) { this.destWidth = destWidth; } @Override public BufferedImage filter(BufferedImage src, BufferedImage dest) { int width = src.getWidth(); int height = src.getHeight(); float ratio = width / this.destWidth; float rcp_ratio = 2.0f / ratio; float range2 = (float) Math.ceil(ratio * lanczosSize / 2); // destination p_w_picpath int dh = (int)(height * (this.destWidth/width)); int dw = (int)this.destWidth; if (dest == null) { ColorModel cMD = src.getColorModel(); dest = new BufferedImage(src.getColorModel(), cMD.createCompatibleWritableRaster(dw, dh), cMD.isAlphaPremultiplied(), null); } int[] inPixels = new int[width * height]; int[] outPixels = new int[dw * dh]; getRGB(src, 0, 0, width, height, inPixels); int index = 0; float fcy = 0, icy = 0, fcx = 0, icx = 0; for (int row = 0; row < dh; row++) { int ta = 0, tr = 0, tg = 0, tb = 0; fcy = (row + 0.5f) * ratio; icy = (float) Math.floor(fcy); for (int col = 0; col < dw; col++) { fcx = (col + 0.5f) * ratio; icx = (float) Math.floor(fcx); float sumred = 0, sumgreen = 0, sumblue = 0; float totalWeight = 0; for (int subcol = (int) (icx - range2); subcol <= icx + range2; subcol++) { if (subcol < 0 || subcol >= width) continue; int ncol = (int) Math.floor(1000 * Math.abs(subcol - fcx)); for (int subrow = (int) (icy - range2); subrow <= icy + range2; subrow++) { if (subrow < 0 || subrow >= height) continue; int nrow = (int) Math.floor(1000 * Math.abs(subrow - fcy)); float weight = (float) getLanczosFactor(Math.sqrt(Math.pow(ncol * rcp_ratio, 2) + Math.pow(nrow * rcp_ratio, 2)) / 1000); if (weight > 0) { index = (subrow * width + subcol); tr = (inPixels[index] >> 16) & 0xff; tg = (inPixels[index] >> 8) & 0xff; tb = inPixels[index] & 0xff; totalWeight += weight; sumred += weight * tr; sumgreen += weight * tg; sumblue += weight * tb; } } } index = row * dw + col; tr = (int) (sumred / totalWeight); tg = (int) (sumgreen / totalWeight); tb = (int) (sumblue / totalWeight); outPixels[index] = (255 << 24) | (clamp(tr) << 16) | (clamp(tg) << 8) | clamp(tb); // clear for next pixel sumred = 0; sumgreen = 0; sumblue = 0; totalWeight = 0; } } setRGB(dest, 0, 0, dw, dh, outPixels); return dest; } public static int clamp(int v) { return v > 255 ? 255 : (v < 0 ? 0 : v); } private double getLanczosFactor(double distance) { if (distance > lanczosSize) return 0; distance *= Math.PI; if (Math.abs(distance) < 1e-16) return 1; double xx = distance / lanczosSize; return Math.sin(distance) * Math.sin(xx) / distance / xx; } }

五:窗口大小对结果的影响

如果是向下采样生成缩略图的话, 窗口大小设置为3就已经非常清楚了

如果向上采样要放大图像的话, 窗口大小设置要大于6才能获得较好结果,推荐使用窗口

大小为8.

转载于:https://blog.51cto.com/gloomyfish/1400257

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。