图像处理之错切变换
来源:互联网 发布:ab plc编程语言 编辑:程序博客网 时间:2024/05/16 01:26
图像处理之错切变换
一:基本数学知识:
图像错切变换在图像几何形变方面非常有用,常见的错切变换分为X方向与Y方向的
错切变换。对应的数学矩阵分别如下:
根据上述矩阵假设P(x1, y1)为错切变换之前的像素点,则错切变换以后对应的像素
P’(x2, y2)当X方向错切变换时:
当Y方向错切变换时:
二:程序实现基本思路
实现图像错切变换时,必须考虑图像将目标像素点坐标变为源相点坐标时小数部分对
像素值的影响,这里通过临近点插值算法实现了目标像素值的计算。根据目标像素计
算源像素的公式可以根据上面的数学公式运算以后分别求的x1,y1的值。由于错切以
后图像会在宽或者高上比原图像大,多出来的这些背景像素默认填充颜色为黑色。
类ShearFilter实现了图像水平或者垂直方向的错切变换,支持角度与背景颜色参数
设置。
三:编程关键点解析
Ø 计算错切以后图像的宽与高
- double angleValue = (angle/180.0d) * Math.PI;
- outh = vertical ? (int)(height + width * Math.tan(angleValue)) : height;
- outw = vertical ? width : (int)(width + height * Math.tan(angleValue));
- System.out.println("after shear, new width : " + outw);
- System.out.println("after shear, new height: " + outh);
- double prow = vertical ? row + Math.tan(angleValue) * (col - width) : row;
- double pcol = vertical ? col : col + Math.tan(angleValue) * (row - height);
- int[] rgb = getPixel(inPixels, width, height, prow, pcol);
Ø 临近点插值计算目标像素点像素值
- private int[] getPixel(int[] input, int width, int height,
- double prow, double pcol) {
- double row = Math.floor(prow);
- double col = Math.floor(pcol);
- if(row < 0 || row >= height) {
- return new int[]{backgroundColor.getRed(),
- backgroundColor.getGreen(),
- backgroundColor.getBlue()};
- }
- if(col < 0 || col >= width) {
- return new int[]{backgroundColor.getRed(),
- backgroundColor.getGreen(),
- backgroundColor.getBlue()};
- }
- double u = vertical ? (prow - row) : pcol - col;
- int nextCol = (int)(col + 1);
- int nextRow = (int)(row + 1);
- if((col + 1) >= width) {
- nextCol = (int)col;
- }
- if((row + 1) >= height) {
- nextRow = (int)row;
- }
- int index1 = (int)(row * width + col);
- int index2 = vertical ? (int)(nextRow * width + col) : (int)(row * width + nextCol);
- int tr1, tr2;
- int tg1, tg2;
- int tb1, tb2;
- tr1 = (input[index1] >> 16) & 0xff;
- tg1 = (input[index1] >> 8) & 0xff;
- tb1 = input[index1] & 0xff;
- tr2 = (input[index2] >> 16) & 0xff;
- tg2 = (input[index2] >> 8) & 0xff;
- tb2 = input[index2] & 0xff;
- int tr = (int)(tr1 * (1-u) + tr2 * u);
- int tg = (int)(tg1 * (1-u) + tg2 * u);
- int tb = (int)(tb1 * (1-u) + tb2 * u);
- return new int[]{tr, tg, tb};
- }
五:类ShearFilter完整代码
- package com.gloomyfish.filter.study;
- import java.awt.Color;
- import java.awt.image.BufferedImage;
- import java.awt.image.ColorModel;
- public class ShearFilter extends AbstractBufferedImageOp {
- private int outw;
- private int outh;
- private double angle;
- private Color backgroundColor;
- private boolean vertical;
- public void setVertical(boolean vertical) {
- this.vertical = vertical;
- }
- public ShearFilter()
- {
- backgroundColor = Color.BLACK;
- vertical = false;
- this.angle = 20;
- }
- public int getOutw() {
- return outw;
- }
- public void setOutw(int outw) {
- this.outw = outw;
- }
- public int getOuth() {
- return outh;
- }
- public void setOuth(int outh) {
- this.outh = outh;
- }
- public double getAngle() {
- return angle;
- }
- public void setAngle(double angle) {
- this.angle = angle;
- }
- public Color getBackgroundColor() {
- return backgroundColor;
- }
- public void setBackgroundColor(Color backgroundColor) {
- this.backgroundColor = backgroundColor;
- }
- @Override
- public BufferedImage filter(BufferedImage src, BufferedImage dest) {
- int width = src.getWidth();
- int height = src.getHeight();
- double angleValue = (angle/180.0d) * Math.PI;
- outh = vertical ? (int)(height + width * Math.tan(angleValue)) : height;
- outw = vertical ? width : (int)(width + height * Math.tan(angleValue));
- System.out.println("after shear, new width : " + outw);
- System.out.println("after shear, new height: " + outh);
- int[] inPixels = new int[width*height];
- int[] outPixels = new int[outh*outw];
- getRGB( src, 0, 0, width, height, inPixels );
- int index = 0;
- for(int row=0; row<outh; row++) {
- int ta = 0;
- for(int col=0; col<outw; col++) {
- double prow = vertical ? row + Math.tan(angleValue) * (col - width) : row;
- double pcol = vertical ? col : col + Math.tan(angleValue) * (row - height);
- int[] rgb = getPixel(inPixels, width, height, prow, pcol);
- index = row * outw + col;
- outPixels[index] = (ta << 24) | (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
- }
- }
- if ( dest == null )
- dest = createCompatibleDestImage( src, null );
- setRGB( dest, 0, 0, outw, outh, outPixels );
- return dest;
- }
- private int[] getPixel(int[] input, int width, int height,
- double prow, double pcol) {
- double row = Math.floor(prow);
- double col = Math.floor(pcol);
- if(row < 0 || row >= height) {
- return new int[]{backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue()};
- }
- if(col < 0 || col >= width) {
- return new int[]{backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue()};
- }
- double u = vertical ? (prow - row) : pcol - col;
- int nextCol = (int)(col + 1);
- int nextRow = (int)(row + 1);
- if((col + 1) >= width) {
- nextCol = (int)col;
- }
- if((row + 1) >= height) {
- nextRow = (int)row;
- }
- int index1 = (int)(row * width + col);
- int index2 = vertical ? (int)(nextRow * width + col) : (int)(row * width + nextCol);
- int tr1, tr2;
- int tg1, tg2;
- int tb1, tb2;
- tr1 = (input[index1] >> 16) & 0xff;
- tg1 = (input[index1] >> 8) & 0xff;
- tb1 = input[index1] & 0xff;
- tr2 = (input[index2] >> 16) & 0xff;
- tg2 = (input[index2] >> 8) & 0xff;
- tb2 = input[index2] & 0xff;
- int tr = (int)(tr1 * (1-u) + tr2 * u);
- int tg = (int)(tg1 * (1-u) + tg2 * u);
- int tb = (int)(tb1 * (1-u) + tb2 * u);
- return new int[]{tr, tg, tb};
- }
- public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
- if ( dstCM == null )
- dstCM = src.getColorModel();
- return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(outw, outh), dstCM.isAlphaPremultiplied(), null);
- }
- }
我会继续努力的!再次声明一下:请不要向我索取源码!谢谢!
代码我在整理中,最终我会开源让大家自己下载,请耐心等待!
0 0
- 图像处理之错切变换
- 图像处理之错切变换
- 基于错切变换的图像旋转
- 错切变换
- Android学习笔记进阶十之Matrix错切变换
- 图像运算平移,旋转,切变换
- python-opencv实现切变换,不裁减图片
- 图像处理 之 图像保存
- 图像处理之图像复原
- 图像处理之旋转图像
- 图像处理之图像平滑
- 图像处理之图像金字塔
- 图像处理之图像直方图
- 图像处理之图像距
- 图像处理之二值化图像
- 图像处理之分割图像
- 【计算机视觉】【图像处理】【VS开发】【Qt开发】opencv之深拷贝及浅拷贝,IplImage装换为Mat
- 【Android图像处理】图像处理之-哈哈镜
- “段错误”定位及调试的一点经验
- 一次线程池有关的性能调优之旅
- iOS - 程序调试模拟器能通真机则不行
- JAVA反射机制
- Android常见知识点
- 图像处理之错切变换
- iOS—UIFont设置字体
- Ⅰ.19 如何实现自动化批量测试
- ios 键盘用多种方式都无法收起的问题
- 关于API接口
- 算法时间复杂度分析表
- Linux服务器 挂载数据盘
- javascript深入理解js闭包
- spring aop execution表达式