ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java 图像处理(二)

2022-07-03 12:04:54  阅读:161  来源: 互联网

标签:Java resourceImage BufferedImage bufferedImage 图像处理 fileOutputStream new affineT


接着上一节关于图像基本要素的介绍之后,今天主要来介绍二维图像的仿射变换处理。

一、放射变换

 

放射变换是空间直角坐标系的变换,从一个二维坐标变换到另一个二维坐标,仿射变换是一个线性变换,它保持了图像的“平行性”和“平直性”,即图像中原来的直线和平行线,变换后仍然保持原来的直线和平行线,仿射变换比较常用的有平移(Translation)、缩放(Scale)、旋转(Rotation)和剪切(Shear)。

 

Java中处理放射变换的类主要是:  AffineTransform 类,其实通过这个类,我们可以理解,放射变换最主要就是下面的这个3*3的矩阵

   [ m00   m01    m02]

   [m10    m11    m12]

   [ 0          0           1]

 那么如何通过放射变换从一个向量X 如何变换到另一个X'向量,主要也是通过上面的这个矩阵来完成

[ x']   [  m00  m01  m02  ] [ x ]   [ m00x + m01y + m02 ]
[ y'] = [ m10 m11 m12 ] [ y ] = [ m10x + m11y + m12 ]
[ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]

在这个矩阵中,其中m00和m11是控制x和y方向的缩放变换的,m01和m10是控制裁剪变换的,m02和m12是控制平移变换,

其中旋转矩阵是要做相应的变换,也就是这个3*3的矩阵变换为如下:
[ cos(theta) -sin(theta) 0 ]

[ sin(theta) cos(theta) 0 ]
[       0              0         1   ]
其中theta表示旋转的角度值。

二、放射变换Java示例

现在我们将下面的这张图进行一个缩放的处理(图片来源于网络)

   下面我们看下代码:

public void affineTest() throws IOException {
        String SCALE_IMAGE = "D:\\test\\affine.jpeg";
        BufferedImage resourceImage = ImageIO.read(new File("D:\\test\\1.jpg"));
        BufferedImage bufferedImage = new BufferedImage(resourceImage.getWidth() ,resourceImage.getHeight(),BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics();
        AffineTransform affineTransform = new AffineTransform();
        affineTransform.setToScale(0.5,0.5);    //缩放比例
        graphics2D.drawImage(resourceImage,affineTransform,null);
        FileOutputStream fileOutputStream = new FileOutputStream(new File(SCALE_IMAGE));
        ImageIO.write(bufferedImage,"png",fileOutputStream);
        fileOutputStream.flush();
        fileOutputStream.close();
    }

其中我们可以看到affineTransform.setToScale(0.5,0.5) 图片的宽和高分别按照原来的1/2,进行等比例缩放,我们看下效果

当然如果参数给的都是1,则和原图没有区别。

下面我们再看看平移参数的使用以及效果

public void streamMapTest() throws IOException {
        String SCALE_IMAGE = "D:\\test\\affine.jpeg";
        BufferedImage resourceImage = ImageIO.read(new File("D:\\test\\1.jpg"));
        BufferedImage bufferedImage = new BufferedImage(resourceImage.getWidth() ,resourceImage.getHeight(),BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics();
        AffineTransform affineTransform = new AffineTransform();
        affineTransform.setToTranslation(100,100); //平移参数
        graphics2D.drawImage(resourceImage,affineTransform,null);
        FileOutputStream fileOutputStream = new FileOutputStream(new File(SCALE_IMAGE));
        ImageIO.write(bufferedImage,"png",fileOutputStream);
        fileOutputStream.flush();
        fileOutputStream.close();
    }

我们看看效果

可以看出,这个平移是以图片左上角为原点,如果参数为正,则是向右和向下平移,如果参数为负,则是向左和向上平移。

下面来看下旋转的粗合理方式,我们将上面的原图旋转30°看下效果,首先看代码

 public void streamMapTest() throws IOException {
        String SCALE_IMAGE = "D:\\test\\affine.jpeg";
        BufferedImage resourceImage = ImageIO.read(new File("D:\\test\\1.jpg"));
        BufferedImage bufferedImage = new BufferedImage(resourceImage.getWidth() ,resourceImage.getHeight(),BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics();
        AffineTransform affineTransform = new AffineTransform();
        affineTransform.setToRotation(Math.PI / 6,0,0);
        graphics2D.drawImage(resourceImage,affineTransform,null);
        FileOutputStream fileOutputStream = new FileOutputStream(new File(SCALE_IMAGE));
        ImageIO.write(bufferedImage,"png",fileOutputStream);
        fileOutputStream.flush();
        fileOutputStream.close();
    }

其中 affineTransform.setToRotation(Math.PI / 6,0,0);这句代码就是设置图像的旋转处理

其中第一个参数,单位是弧度,因此我们按照角度,来处理的时候,一定要进行转化弧度,第二个和第三个参数,指的是

旋转的坐标远点,默认是左上角,也可以自己制定,我们来看看按照0,0点旋转30°后的效果

可以看到原始图片被按照0,0点,顺时针旋转30°。

好了,今天关于Java处理二维图像的仿射变换处理,就介绍到这里,内容如果有不妥之处,欢迎各位大佬指正。

 

 

 

 












 

标签:Java,resourceImage,BufferedImage,bufferedImage,图像处理,fileOutputStream,new,affineT
来源: https://www.cnblogs.com/share-gis/p/16367840.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有