图像处理之图像快速插值放缩算法
来源:互联网 发布:李兴华讲的java怎么样 编辑:程序博客网 时间:2024/05/14 01:40
算法思想:
基于双线性算法的分解,分别进行水平与垂直两个方向的放缩,完成对整张图像的放大或
者缩小。基于的数学思想为矩阵的乘法,对一个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;}@Overridepublic 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++;}}}}}后注:其效果近似与双线性内插值算法,但是运行速度却是它的几十倍之多,感兴趣者
可以自己测试。证明我没有信口开河。
- 图像处理之图像快速插值放缩算法
- 图像处理之图像快速旋转算法
- 图像处理之浮雕算法
- 图像处理之滤波算法
- 图像处理算法之滤镜
- 图像处理算法之美颜
- 由图像处理快速算法想到的
- 图像快速处理算法II 距离变换
- 图像处理之基于一维高斯快速模糊
- 图像处理之基于一维高斯快速模糊
- 图像处理之图像分割之Snake算法简单梳理
- 图像处理算法之图像暗角特效
- 快速图像细化算法
- 图像处理之特殊灰度算法技巧
- 图像处理-基本算法之线性变换
- 图像处理-基本算法之对数变换
- 图像处理-基本算法之指数变换
- 图像处理-基本算法之阈值变换
- 奢望
- 经典面试题目
- FPGA_Embedded_9_13
- Rzpanel1的一个属性
- javascript和jquery分别实现树
- 图像处理之图像快速插值放缩算法
- 猜数字游戏
- nefu473最大流
- cocos2d
- CognosBI技术建议书
- AS3.0 效率优化
- Paxos算法学习笔记
- TCP/IP:认识TCP
- 3、关于手机型号的前缀翻译表