图像处理之图像快速插值放缩算法

简介: 算法思想: 基于双线性算法的分解,分别进行水平与垂直两个方向的放缩,完成对整张图像的放大或 者缩小。基于的数学思想为矩阵的乘法,对一个scale矩阵可以拆分为水平与垂直方向的两 个关联矩阵,具体如下: 关于什么是双线性插值参加这里:http://blog.csdn.net/jia20003/article/details/6915185 程序解释: 类ScaleFilter完成对图像的快速放大与缩小,接受输入参数为XY方向的放缩比例值。

算法思想:

基于双线性算法的分解,分别进行水平与垂直两个方向的放缩,完成对整张图像的放大或

者缩小。基于的数学思想为矩阵的乘法,对一个scale矩阵可以拆分为水平与垂直方向的两

个关联矩阵,具体如下:


关于什么是双线性插值参加这里:http://blog.csdn.net/jia20003/article/details/6915185

程序解释:

类ScaleFilter完成对图像的快速放大与缩小,接受输入参数为XY方向的放缩比例值。

hscal, vscale的默认值为1.5f即将输入图像在XY放大1.5倍。XY方向的Scale方法参考与运用

了移动窗口的算法。感兴趣可以自己研究,我也是改写一段c语言代码得到。感觉非常的精妙。

程序效果如下:


Scale Filter的源代码如下:

package com.gloomyfish.filter.study;
/**
 * @author gloomyfish
 * @date 2012-09-23
 * @BLOGPAGE:http://blog.csdn.net/jia20003
 */
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;

public class ScaleFilter extends AbstractBufferedImageOp {
	
	/**
	 * default will zoom in 2.0 * input size of original image.
	 */
	private float hscale = 1.5f;
	private float vscale = 1.5f;
	public ScaleFilter() {
		
	}
	
	public void setHscale(float hscale) {
		this.hscale = hscale;
	}

	public void setVscale(float vscale) {
		this.vscale = vscale;
	}

	@Override
	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
		int width = src.getWidth();
        int height = src.getHeight();

        if ( dest == null )
        	dest = createCompatibleDestImage( src, null );

        // initialization pixel data
        int[] inPixels = new int[width*height];
        int outwidth = (int)(hscale * (float)width);
        int outheight = (int)(vscale * (float)height);
        int[] outhPixels = new int[outwidth*height];
        int[] outPixels = new int[outwidth*outheight];

        // start to zoom in/out here
        getRGB( src, 0, 0, width, height, inPixels );
        hscale(inPixels, outhPixels, width, height);
        vscale(outhPixels, outPixels, outwidth, height);

        // create buffered image and return it with result image data 
        setRGB( dest, 0, 0, outwidth, outheight, outPixels);
        return dest;
	}
	
    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
        if ( dstCM == null )
            dstCM = src.getColorModel();
        int outwidth = (int)(hscale * (float)src.getWidth());
        int outheight = (int)(vscale * (float)src.getHeight());
        return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(outwidth, outheight), dstCM.isAlphaPremultiplied(), null);
    }
	
	private void hscale(int[] input, int[] output, int width, int height) {
		int ta1 = 0, tr1 = 0, tg1 = 0, tb1 = 0;
		int ta2 = 0, tr2 = 0, tg2 = 0, tb2 = 0;
		int sumred = 0, sumgreen = 0, sumblue = 0;
		double accred = 0, accgreen = 0, accblue = 0;
		int p, q;
		int outwidth = (int)(this.hscale * width);
		double area = (outwidth * width);
		int inCol = 0, outCol = 0;
		int inIndex1 = 0, inIndex2 = 0, outIndex = 0;
		for (int row = 0; row < height; row++) {
			q = width;
			p = outwidth;
			accred = accgreen = accblue = 0;
			inCol = outCol = 0;
			while (outCol < outwidth) {
				if(outCol == 299) {
					System.out.println("what are you doing...");
				}
				if ((inCol + 1) < 2) {
					inIndex1 = row * width + inCol;
					inIndex2 = row * width + (inCol + 1);
	        		ta1 = (input[inIndex1] >> 24) & 0xff;
	                tr1 = (input[inIndex1] >> 16) & 0xff;
	                tg1 = (input[inIndex1] >> 8) & 0xff;
	                tb1 = input[inIndex1] & 0xff;
	                
	        		ta2 = (input[inIndex2] >> 24) & 0xff;
	                tr2 = (input[inIndex2] >> 16) & 0xff;
	                tg2 = (input[inIndex2] >> 8) & 0xff;
	                tb2 = input[inIndex2] & 0xff;
	                sumred = p * tr1 + (outwidth - p) * tr2;
	                sumgreen = p * tg1 + (outwidth - p) * tg2;
	                sumblue = p * tb1 + (outwidth - p) * tb2;
				}
				else 
				{
					inIndex1 = row * width + inCol;
	        		ta1 = (input[inIndex1] >> 24) & 0xff;
	                tr1 = (input[inIndex1] >> 16) & 0xff;
	                tg1 = (input[inIndex1] >> 8) & 0xff;
	                tb1 = input[inIndex1] & 0xff;
	                sumred = outwidth * tr1;
	                sumgreen = outwidth * tg1;
	                sumblue = outwidth * tb1;
				}
				if (p < q) {
					accred += sumred * p;
					accgreen += sumgreen * p;
					accblue += sumblue * p;
					q -= p;
					p = outwidth;
					inCol++;
				} else {
					accred += sumred * q;
					accgreen += sumgreen * q;
					accblue += sumblue * q;
					outIndex = row * outwidth + outCol;
					output[outIndex] = ta1 << 24 | ((int)(accred / area) << 16) | ((int)(accgreen / area) << 8) | (int)(accblue / area);
					accred = accgreen = accblue = 0;
					p -= q;
					q = width;
					outCol++;
				}
			}
		}
	}

	private void vscale(int[] input, int[] output, int width, int height) {
		int ta1 = 0, tr1 = 0, tg1 = 0, tb1 = 0;
		int ta2 = 0, tr2 = 0, tg2 = 0, tb2 = 0;
		int sumred = 0, sumgreen = 0, sumblue = 0;
		double accred = 0, accgreen = 0, accblue = 0;
		int inRow = 0, outRow = 0;
		int inIndex1 = 0, inIndex2 = 0, outIndex = 0;
		int p, q;
		int ih = height;
		int oh = (int)(height * vscale);
		int area = (ih * oh);
		for (int col = 0; col < width; col++) {
			q = ih;
			p = oh;
			accred = accgreen = accblue = 0;
			inRow = outRow = 0;
			while (outRow < oh) {
				if (inRow+1 < ih) {
					inIndex1 = inRow * width + col;
					inIndex2 = (inRow+1) * width + col;
	        		ta1 = (input[inIndex1] >> 24) & 0xff;
	                tr1 = (input[inIndex1] >> 16) & 0xff;
	                tg1 = (input[inIndex1] >> 8) & 0xff;
	                tb1 = input[inIndex1] & 0xff;
	                
	        		ta2 = (input[inIndex2] >> 24) & 0xff;
	                tr2 = (input[inIndex2] >> 16) & 0xff;
	                tg2 = (input[inIndex2] >> 8) & 0xff;
	                tb2 = input[inIndex2] & 0xff;
	                sumred = p * tr1 + (oh - p) * tr2;
	                sumgreen = p * tg1 + (oh - p) * tg2;
	                sumblue = p * tb1 + (oh - p) * tb2;
				}
				else
				{
					inIndex1 = inRow * width + col;
	        		ta1 = (input[inIndex1] >> 24) & 0xff;
	                tr1 = (input[inIndex1] >> 16) & 0xff;
	                tg1 = (input[inIndex1] >> 8) & 0xff;
	                tb1 = input[inIndex1] & 0xff;
	                sumred = oh * tr1;
	                sumgreen = oh * tg1;
	                sumblue = oh * tb1;
				}
				if (p < q) {
					accred += sumred * p;
					accgreen += sumgreen * p;
					accblue += sumblue * p;
					q -= p;
					p = oh;
					inRow++;
				} else {
					accred += sumred * q;
					accgreen += sumgreen * q;
					accblue += sumblue * q;
					outIndex = outRow * width + col;
					
					output[outIndex] = ta1 << 24 | ((int)(accred / area) << 16) | ((int)(accgreen / area) << 8) | (int)(accblue / area);
					accred = accgreen = accblue = 0;
					p -= q;
					q = ih;
					outRow++;
				}
			}
		}		
	}
}
后注:其效果近似与双线性内插值算法,但是运行速度却是它的几十倍之多,感兴趣者

可以自己测试。证明我没有信口开河。

目录
相关文章
|
3月前
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
514 0
|
3月前
|
监控 算法 图计算
图像处理之积分图应用三(基于NCC快速相似度匹配算法)
图像处理之积分图应用三(基于NCC快速相似度匹配算法)
59 0
|
18天前
|
算法 数据可视化 数据安全/隐私保护
基于LK光流提取算法的图像序列晃动程度计算matlab仿真
该算法基于Lucas-Kanade光流方法,用于计算图像序列的晃动程度。通过计算相邻帧间的光流场并定义晃动程度指标(如RMS),可量化图像晃动。此版本适用于Matlab 2022a,提供详细中文注释与操作视频。完整代码无水印。
|
2月前
|
机器学习/深度学习 编解码 监控
算法金 | 深度学习图像增强方法总结
**图像增强技术概括** 图像增强聚焦于提升视觉效果和细节,广泛应用于医学、遥感等领域。空间域增强包括直方图均衡化(增强对比度)、对比度拉伸、灰度变换、平滑滤波(均值、中值)和锐化滤波(拉普拉斯、高通)。频率域增强利用傅里叶变换、小波变换,通过高频和低频滤波增强图像特征。现代方法涉及超分辨率重建、深度学习去噪(如CNN、Autoencoder)、图像修复(如GAN)和GANs驱动的多种图像处理任务。
71 14
算法金 | 深度学习图像增强方法总结
|
1月前
|
算法 前端开发 计算机视觉
基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
26 0
|
1月前
|
自然语言处理 并行计算 算法
基于均值坐标(Mean-Value Coordinates)的图像融合算法的具体实现
基于均值坐标(Mean-Value Coordinates)的图像融合算法的具体实现
27 0
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
|
2月前
|
算法
基于粒子群优化的图像融合算法matlab仿真
这是一个基于粒子群优化(PSO)的图像融合算法,旨在将彩色模糊图像与清晰灰度图像融合成彩色清晰图像。在MATLAB2022a中测试,算法通过PSO求解最优融合权值参数,经过多次迭代更新粒子速度和位置,以优化融合效果。核心代码展示了PSO的迭代过程及融合策略。最终,使用加权平均法融合图像,其中权重由PSO计算得出。该算法体现了PSO在图像融合领域的高效性和融合质量。
|
3月前
|
机器学习/深度学习 人工智能 算法
【CVPR2024】面向StableDiffusion的编辑算法FreePromptEditing,提升图像编辑效果
近日,阿里云人工智能平台PAI与华南理工大学贾奎教授团队合作在深度学习顶级会议 CVPR2024 上发表 FPE(Free-Prompt-Editing) 算法,这是一种面向StableDiffusion的图像编辑算法。在这篇论文中,StableDiffusion可用于实现图像编辑的本质被挖掘,解释证明了基于StableDiffusion编辑的算法本质,并基于此设计了新的图像编辑算法,大幅度提升了图像编辑的效率。
|
3月前
|
算法 计算机视觉
基于Chan-Vese算法的图像边缘提取matlab仿真
**算法预览展示了4幅图像,从边缘检测到最终分割,体现了在matlab2022a中应用的Chan-Vese水平集迭代过程。核心代码段用于更新水平集并显示迭代效果,最后生成分割结果及误差曲线。Chan-Vese模型(2001)是图像分割的经典方法,通过最小化能量函数自动检测平滑区域和清晰边界的图像分割,适用于复杂环境,广泛应用于医学影像和机器视觉。**