在Android上玩转Opencv 系列:19.基础知识 透视变换和仿射变换

Android 版 OpenCV 透视变换和仿射变换详解

在 Android 版本的 OpenCV 中,透视变换(Perspective Transformation)仿射变换(Affine Transformation) 是两种常见的几何变换,用于图像校正、变形、对齐等任务。本文将详细介绍它们的原理、实现方法及应用场景。

1. 透视变换(Perspective Transformation)

1.1 透视变换概述

透视变换用于将图像从一种视角转换到另一种视角。例如,将倾斜的文本矫正为正视角,或者将拍摄的名片校正成标准矩形。

输入: 四个原始点(图像中的四个角)

输出: 变换后的四个点(目标位置的四个角)

公式:

透视变换使用 3×3 矩阵,计算方式如下:

其中:

• 是原始坐标

• 是变换后的坐标

• 是缩放因子

• 是透视变换矩阵的参数

1.2 透视变换实现

步骤

  1. 选取原始图像中的 四个顶点

  2. 设定变换后的 四个目标点(通常是矩形)。

  3. 计算透视变换矩阵 getPerspectiveTransform()

  4. 进行透视变换 warpPerspective()

示例代码

scss 复制代码
import org.opencv.android.Utils;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import android.graphics.Bitmap;

public class PerspectiveTransform {

    public static Bitmap applyPerspectiveTransform(Bitmap inputBitmap) {
        // 将 Bitmap 转换为 Mat
        Mat srcMat = new Mat();
        Utils.bitmapToMat(inputBitmap, srcMat);

        // 定义源点(选取原图中的四个角点)
        Point srcPoints[] = {
            new Point(50, 50),   // 左上角
            new Point(450, 50),  // 右上角
            new Point(50, 400),  // 左下角
            new Point(450, 400)  // 右下角
        };
        MatOfPoint2f srcMatOfPoint = new MatOfPoint2f(srcPoints);

        // 定义目标点(变换后的矩形区域)
        Point dstPoints[] = {
            new Point(0, 0),
            new Point(500, 0),
            new Point(0, 500),
            new Point(500, 500)
        };
        MatOfPoint2f dstMatOfPoint = new MatOfPoint2f(dstPoints);

        // 计算透视变换矩阵
        Mat perspectiveMatrix = Imgproc.getPerspectiveTransform(srcMatOfPoint, dstMatOfPoint);

        // 进行透视变换
        Mat outputMat = new Mat();
        Imgproc.warpPerspective(srcMat, outputMat, perspectiveMatrix, new Size(500, 500));

        // 转换回 Bitmap
        Bitmap outputBitmap = Bitmap.createBitmap(outputMat.cols(), outputMat.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(outputMat, outputBitmap);

        return outputBitmap;
    }
}

应用场景

文档扫描矫正(拍摄歪斜的文档,并修正为正面视角)

车牌识别(校正角度,提取车牌)

图像投影校正(如投影仪的画面修正)

2. 仿射变换(Affine Transformation)

2.1 仿射变换概述

仿射变换用于对图像进行 缩放、旋转、平移、剪切 ,但不会改变图像的平行性。其特点是:

• 直线仍然是直线

• 平行线仍然平行

输入: 三个原始点

输出: 变换后的三个点

公式:

仿射变换使用 2×3 矩阵,计算方式如下:

2.2 仿射变换实现

步骤

  1. 选择原始图像中的 三个点

  2. 设定变换后的 目标点

  3. 计算仿射变换矩阵 getAffineTransform()

  4. 进行仿射变换 warpAffine()

示例代码

scss 复制代码
import org.opencv.android.Utils;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import android.graphics.Bitmap;

public class AffineTransform {

    public static Bitmap applyAffineTransform(Bitmap inputBitmap) {
        // 转换 Bitmap 为 Mat
        Mat srcMat = new Mat();
        Utils.bitmapToMat(inputBitmap, srcMat);

        // 选择三个原始点
        Point srcPoints[] = {
            new Point(50, 50),
            new Point(200, 50),
            new Point(50, 200)
        };
        MatOfPoint2f srcMatOfPoint = new MatOfPoint2f(srcPoints);

        // 目标点(变换后的新位置)
        Point dstPoints[] = {
            new Point(10, 100),
            new Point(200, 50),
            new Point(100, 250)
        };
        MatOfPoint2f dstMatOfPoint = new MatOfPoint2f(dstPoints);

        // 计算仿射变换矩阵
        Mat affineMatrix = Imgproc.getAffineTransform(srcMatOfPoint, dstMatOfPoint);

        // 进行仿射变换
        Mat outputMat = new Mat();
        Imgproc.warpAffine(srcMat, outputMat, affineMatrix, srcMat.size());

        // 转换回 Bitmap
        Bitmap outputBitmap = Bitmap.createBitmap(outputMat.cols(), outputMat.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(outputMat, outputBitmap);

        return outputBitmap;
    }
}

应用场景

旋转图像(如倾斜文本校正)

面部对齐(将不同角度的人脸归一化)

图像增强(调整物体位置)

3. 透视变换 vs 仿射变换

变换类型 需要点数 适用场景 是否保持平行性 是否允许透视扭曲
透视变换 4 视角矫正、车牌校正
仿射变换 3 旋转、缩放、平移

总结

透视变换 适用于 角度矫正,如文档扫描、车牌识别。

仿射变换 适用于 缩放、旋转、平移,如图像对齐、人脸对齐。

• 在 Android 版 OpenCV 中,可以使用 Imgproc.getPerspectiveTransform() 和 Imgproc.getAffineTransform() 计算变换矩阵,并用 warpPerspective() 或 warpAffine() 进行变换。

相关推荐
彭祥.17 小时前
Jetson边缘计算主板:Ubuntu 环境配置 CUDA 与 cudNN 推理环境 + OpenCV 与 C++ 进行目标分类
c++·opencv·分类
Tony沈哲18 小时前
macOS 上为 Compose Desktop 构建跨架构图像处理 dylib:OpenCV + libraw + libheif 实践指南
opencv·算法
视觉人机器视觉1 天前
Visual Studio2022和C++opencv的配置保姆级教程
c++·opencv·visual studio
PyAIExplorer1 天前
图像旋转:从原理到 OpenCV 实践
人工智能·opencv·计算机视觉
PyAIExplorer1 天前
OpenCV 图像操作:颜色识别、替换与水印添加
人工智能·opencv·计算机视觉
whoarethenext2 天前
使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
开发语言·c++·opencv·mfcc
jndingxin2 天前
OpenCV CUDA模块设备层-----高效地计算两个 uint 类型值的带权重平均值
人工智能·opencv·计算机视觉
晨同学03272 天前
opencv的颜色通道问题 & rgb & bgr
人工智能·opencv·计算机视觉
看到我,请让我去学习2 天前
OpenCV开发-初始概念
人工智能·opencv·计算机视觉
PyAIExplorer2 天前
基于 OpenCV 的图像 ROI 切割实现
人工智能·opencv·计算机视觉