图像处理之错切变换

来源:互联网 发布:ab plc编程语言 编辑:程序博客网 时间:2024/05/16 01:26


图像处理之错切变换

一:基本数学知识:

图像错切变换在图像几何形变方面非常有用,常见的错切变换分为X方向与Y方向的

错切变换。对应的数学矩阵分别如下:

  

根据上述矩阵假设P(x1, y1)为错切变换之前的像素点,则错切变换以后对应的像素

P’(x2, y2)当X方向错切变换时:


当Y方向错切变换时:


二:程序实现基本思路

实现图像错切变换时,必须考虑图像将目标像素点坐标变为源相点坐标时小数部分对

像素值的影响,这里通过临近点插值算法实现了目标像素值的计算。根据目标像素计

算源像素的公式可以根据上面的数学公式运算以后分别求的x1,y1的值。由于错切以

后图像会在宽或者高上比原图像大,多出来的这些背景像素默认填充颜色为黑色。

类ShearFilter实现了图像水平或者垂直方向的错切变换,支持角度与背景颜色参数

设置。

 三:编程关键点解析

Ø  计算错切以后图像的宽与高

[java] view plaincopyprint?
  1. double angleValue = (angle/180.0d) * Math.PI;  
  2. outh = vertical ? (int)(height + width * Math.tan(angleValue)) : height;  
  3. outw = vertical ? width : (int)(width + height * Math.tan(angleValue));  
  4. System.out.println("after shear, new width : " + outw);  
  5. System.out.println("after shear, new height: " + outh);  
Ø  根据目标像素点坐标计算源像素点坐标

[java] view plaincopyprint?
  1. double prow = vertical ? row + Math.tan(angleValue) * (col - width) : row;  
  2. double pcol = vertical ? col : col + Math.tan(angleValue) * (row - height);  
  3.        int[] rgb = getPixel(inPixels, width, height, prow, pcol);  

Ø  临近点插值计算目标像素点像素值

[java] view plaincopyprint?
  1. private int[] getPixel(int[] input, int width, int height,   
  2.         double prow, double pcol) {  
  3.     double row = Math.floor(prow);  
  4.     double col = Math.floor(pcol);  
  5.     if(row < 0 || row >= height) {  
  6.         return new int[]{backgroundColor.getRed(),   
  7.                 backgroundColor.getGreen(),   
  8.                 backgroundColor.getBlue()};  
  9.     }  
  10.     if(col < 0 || col >= width) {  
  11.         return new int[]{backgroundColor.getRed(),   
  12.                 backgroundColor.getGreen(),   
  13.                 backgroundColor.getBlue()};  
  14.     }  
  15.     double u = vertical ? (prow - row) : pcol - col;  
  16.     int nextCol = (int)(col + 1);  
  17.     int nextRow = (int)(row + 1);  
  18.     if((col + 1) >= width) {  
  19.         nextCol = (int)col;  
  20.     }  
  21.     if((row + 1) >= height) {  
  22.         nextRow = (int)row;  
  23.     }  
  24.     int index1 = (int)(row * width + col);  
  25.     int index2 = vertical ? (int)(nextRow * width + col) : (int)(row * width + nextCol);  
  26.       
  27.     int tr1, tr2;  
  28.     int tg1, tg2;  
  29.     int tb1, tb2;  
  30.       
  31.     tr1 = (input[index1] >> 16) & 0xff;  
  32.     tg1 = (input[index1] >> 8) & 0xff;  
  33.     tb1 = input[index1] & 0xff;  
  34.       
  35.     tr2 = (input[index2] >> 16) & 0xff;  
  36.     tg2 = (input[index2] >> 8) & 0xff;  
  37.     tb2 = input[index2] & 0xff;  
  38.       
  39.     int tr = (int)(tr1 * (1-u) + tr2 * u);  
  40.     int tg = (int)(tg1 * (1-u) + tg2 * u);  
  41.     int tb = (int)(tb1 * (1-u) + tb2 * u);  
  42.       
  43.     return new int[]{tr, tg, tb};  
  44. }  
四:运行效果


五:类ShearFilter完整代码

[java] view plaincopyprint?
  1. package com.gloomyfish.filter.study;  
  2.   
  3. import java.awt.Color;  
  4. import java.awt.image.BufferedImage;  
  5. import java.awt.image.ColorModel;  
  6.   
  7. public class ShearFilter extends AbstractBufferedImageOp {  
  8.     private int outw;  
  9.     private int outh;  
  10.     private double angle;  
  11.     private Color backgroundColor;  
  12.     private boolean vertical;  
  13.       
  14.     public void setVertical(boolean vertical) {  
  15.         this.vertical = vertical;  
  16.     }  
  17.   
  18.     public ShearFilter()  
  19.     {  
  20.         backgroundColor = Color.BLACK;  
  21.         vertical = false;  
  22.         this.angle = 20;  
  23.     }  
  24.       
  25.     public int getOutw() {  
  26.         return outw;  
  27.     }  
  28.     public void setOutw(int outw) {  
  29.         this.outw = outw;  
  30.     }  
  31.     public int getOuth() {  
  32.         return outh;  
  33.     }  
  34.     public void setOuth(int outh) {  
  35.         this.outh = outh;  
  36.     }  
  37.     public double getAngle() {  
  38.         return angle;  
  39.     }  
  40.     public void setAngle(double angle) {  
  41.         this.angle = angle;  
  42.     }  
  43.     public Color getBackgroundColor() {  
  44.         return backgroundColor;  
  45.     }  
  46.     public void setBackgroundColor(Color backgroundColor) {  
  47.         this.backgroundColor = backgroundColor;  
  48.     }  
  49.     @Override  
  50.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  51.         int width = src.getWidth();  
  52.         int height = src.getHeight();  
  53.   
  54.         double angleValue = (angle/180.0d) * Math.PI;  
  55.         outh = vertical ? (int)(height + width * Math.tan(angleValue)) : height;  
  56.         outw = vertical ? width : (int)(width + height * Math.tan(angleValue));  
  57.         System.out.println("after shear, new width : " + outw);  
  58.         System.out.println("after shear, new height: " + outh);  
  59.           
  60.         int[] inPixels = new int[width*height];  
  61.         int[] outPixels = new int[outh*outw];  
  62.         getRGB( src, 00, width, height, inPixels );  
  63.         int index = 0;  
  64.         for(int row=0; row<outh; row++) {  
  65.             int ta = 0;  
  66.             for(int col=0; col<outw; col++) {  
  67.                 double prow = vertical ? row + Math.tan(angleValue) * (col - width) : row;  
  68.                 double pcol = vertical ? col : col + Math.tan(angleValue) * (row - height);  
  69.                 int[] rgb = getPixel(inPixels, width, height, prow, pcol);  
  70.                 index = row * outw + col;  
  71.                 outPixels[index] = (ta << 24) | (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];    
  72.             }  
  73.         }  
  74.   
  75.         if ( dest == null )  
  76.             dest = createCompatibleDestImage( src, null );  
  77.         setRGB( dest, 00, outw, outh, outPixels );  
  78.         return dest;  
  79.     }  
  80.   
  81.     private int[] getPixel(int[] input, int width, int height,   
  82.             double prow, double pcol) {  
  83.         double row = Math.floor(prow);  
  84.         double col = Math.floor(pcol);  
  85.         if(row < 0 || row >= height) {  
  86.             return new int[]{backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue()};  
  87.         }  
  88.         if(col < 0 || col >= width) {  
  89.             return new int[]{backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue()};  
  90.         }  
  91.         double u = vertical ? (prow - row) : pcol - col;  
  92.         int nextCol = (int)(col + 1);  
  93.         int nextRow = (int)(row + 1);  
  94.         if((col + 1) >= width) {  
  95.             nextCol = (int)col;  
  96.         }  
  97.         if((row + 1) >= height) {  
  98.             nextRow = (int)row;  
  99.         }  
  100.         int index1 = (int)(row * width + col);  
  101.         int index2 = vertical ? (int)(nextRow * width + col) : (int)(row * width + nextCol);  
  102.           
  103.         int tr1, tr2;  
  104.         int tg1, tg2;  
  105.         int tb1, tb2;  
  106.           
  107.         tr1 = (input[index1] >> 16) & 0xff;  
  108.         tg1 = (input[index1] >> 8) & 0xff;  
  109.         tb1 = input[index1] & 0xff;  
  110.           
  111.         tr2 = (input[index2] >> 16) & 0xff;  
  112.         tg2 = (input[index2] >> 8) & 0xff;  
  113.         tb2 = input[index2] & 0xff;  
  114.           
  115.         int tr = (int)(tr1 * (1-u) + tr2 * u);  
  116.         int tg = (int)(tg1 * (1-u) + tg2 * u);  
  117.         int tb = (int)(tb1 * (1-u) + tb2 * u);  
  118.           
  119.         return new int[]{tr, tg, tb};  
  120.     }  
  121.       
  122.     public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {  
  123.         if ( dstCM == null )  
  124.             dstCM = src.getColorModel();  
  125.         return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(outw, outh), dstCM.isAlphaPremultiplied(), null);  
  126.     }  
  127.   
  128. }  
下半年事情比较多,博客一直没有更新,感谢众多网友的关注与留言

我会继续努力的!再次声明一下:请不要向我索取源码!谢谢!

代码我在整理中,最终我会开源让大家自己下载,请耐心等待!

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 浏览器未正常加载相关控件怎么办 猫的眼睛发炎了怎么办 橡胶手机壳松了怎么办 橡胶手机壳小了怎么办 苹果手机下载不了软件了怎么办 苹果手机浏览器下载不了软件怎么办 小狗吃了硬的棉花怎么办 小狗吃了隔尿垫里的棉花怎么办 眼睫毛掉进眼睛里怎么办 爱掉头发怎么办吃什么 头皮屑多头发干燥脱发怎么办 剪了头发后悔了怎么办 2岁宝宝发际线高怎么办 脱发怎么办吃什么能长发 后面头发睡平了怎么办 鸟羽毛长得不好怎么办 吃激素药头发掉怎么办 吃了药头发掉怎么办 头皮痒头发掉的厉害怎么办 西昌学院被记过了怎么办? 初三了数学太差怎么办 板绘线条不流畅怎么办 嘴被风吹歪了怎么办 被风吹的嘴歪了怎么办 怀孕一个多月见红了怎么办 b本扣了6分怎么办 b牌驾驶证扣6分怎么办 忘记了谁考证的密码怎么办 专升本学校有课怎么办 跨境额度超了怎么办 微商代购被骗了怎么办 减肥到了瓶颈期该怎么办 大润发超市把一件商品打两件怎么办 小红书上买到假货怎么办 主动退市股票钱怎么办 老板卷款逃跑财务怎么办 房开延迟交房怎么办 房开逾期交房怎么办 买了保险想退保怎么办 辐射避难所探索废土死了怎么办 大门上边的齿轮滑丝怎么办