栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

32 二维图片变换

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

32 二维图片变换

数学原理

  二维图片上每一个点,右乘以一个转换矩阵,就可以实现图片绕原点的旋转和拉伸。而这个转换矩阵,就是(1,0)和(0,1)转换后的点组成的。
  说了这么多,那不得来个例子啊,假设我们要绕原点顺时针旋转90°。首先(1,0)绕原点顺时针旋转90°后变成什么了呢?变成了(0,-1),而(0,1)呢,变成了(1,0)。所以这个变换矩阵为:
[ 0 1 − 1 0 ] left[ begin{matrix} 0 & 1\ -1 & 0 end{matrix} right] [0−1​10​]
  假设将图形上的一个点,坐标为(1,1),转换后的点,用线性代数计算一下:
[ 0 1 − 1 0 ] × [ 1 1 ] = [ 1 − 1 ] left[ begin{matrix} 0 & 1\ -1 & 0 end{matrix} right]times left[ begin{matrix} 1\ 1 end{matrix} right]=left[ begin{matrix} 1\ -1 end{matrix} right] [0−1​10​]×[11​]=[1−1​]
  这两个点用图像表示就是下面这个样子:

  但是这个旋转拉伸操作,是绕着原点进行的。而实际应用图片的旋转,是两个运算,第一个运算是绕着原点的旋转,第二个是图形的平移。可以这样理解,矩阵乘法顺时针旋转90°,其实是绕着原点,把图像旋转到了第三象限,然后只有往上平移才能把图片拉回到第一象限。图形的旋转可以用矩阵与向量的乘法进行计算,图像的平移就使用向量的加法进行计算。

java实现

  Java转换代码如下:

public class ImageConvertor {

    private Matrix matrix;
    private Integer[] moveVector;

    public ImageConvertor(Matrix matrix, Integer[] moveVector) {
        this.matrix = matrix;
        this.moveVector = moveVector;
    }

    public BufferedImage convert(BufferedImage source) {
        final int width = source.getWidth();
        final int height = source.getHeight();
        final BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        final Graphics2D graphics = (Graphics2D) target.getGraphics();
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                final int rgb = source.getRGB(i, j);
                // 运用矩阵乘法,算出这个点在哪里
                final int sx = i;
                final int sy = j;
                final Integer[][] integers = matrix.multiply(new IntegerMatrix(new Integer[][]{{sx}, {sy}}));
                graphics.setColor(new Color(rgb));
                final int x = integers[0][0] + moveVector[0];
                final int y = integers[1][0] + moveVector[1];
                graphics.drawLine(x, y, x, y);
                System.out.println("source:(" + sx + "," + sy + "),target:(" + x + "," + y + ")," + rgb);
            }
        }
        return target;
    }
}

  测试类如下:

@Test
public void test() throws IOException {
    // 顺时针旋转90°,100x100图片
    final Integer[][] array = {{0, -1}, {1, 0}};
    final IntegerMatrix matrix = new IntegerMatrix(array);
    final ImageConvertor imageConvertor = new ImageConvertor(matrix, new Integer[]{99, 0});
    final BufferedImage image = ImageIO.read(new File("e.png"));
    final BufferedImage target = imageConvertor.convert(image);
    ImageIO.write(target, "png", new File("out.png"));
}

  效果如下:

Python实现

  Python的图形库是opencv-python

pip install opencv-python

  代码和Java类似

import numpy as np

from com.youngthing.mathalgorithm.matrix import Matrix


class ImageConvertor:

    def __init__(self, matrix: Matrix, move_vector: list):
        self.__matrix = matrix
        self.__move_vector = move_vector

    def convert(self, image):
        width = len(image[0])
        height = len(image)
        target = np.zeros((width, height, 3), np.uint8)
        for (y, line) in enumerate(image):
            for (x, color) in enumerate(line):
                m = Matrix([[x, y]]) * self.__matrix
                d = m + self.__move_vector
                print(d.lines[0][1], d.lines[0][0], np.uint8(color), color)
                target[d.lines[0][1]][d.lines[0][0]] = np.uint8(color)
        return target
测试类代码
from com.youngthing.mathalgorithm.matrix import Matrix

import cv2
from com.youngthing.mathalgorithm.image.image_process import ImageConvertor

if __name__ == '__main__':
    img = cv2.imread('F:learnmath-algorithme.png')
    rotate_matrix = Matrix([[0, 1], [-1, 0]])
    move_matrix = Matrix([[99, 0]])
    ic = ImageConvertor(rotate_matrix, move_matrix)
    new_img = ic.convert(img)
    cv2.imshow('img', new_img)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

执行效果

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/777992.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号