在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() 进行变换。

相关推荐
王尼莫啊4 小时前
【立体标定】圆形标定板标定python实现
开发语言·python·opencv
蓝桉8024 小时前
opencv学习(视频读取)
人工智能·opencv·学习
dlraba8028 小时前
基于 OpenCV 与 sklearn 的数字识别:KNN 算法实践
opencv·算法·sklearn
德育处主任Pro9 小时前
『React』 组件通信全攻略
python·opencv·matplotlib
一方热衷.15 小时前
YOLOv8/YOLOv11 C++ OpenCV DNN推理
c++·opencv·yolo
momomo_mocs1 天前
opencv 模块裁剪 按需安装指定模块
opencv
m0_642330471 天前
【人工智能-15】OpenCV直方图均衡化,模板匹配,霍夫变换,图像亮度变换,形态学变换
人工智能·opencv·计算机视觉
Wendy14412 天前
【边缘填充】——图像预处理(OpenCV)
人工智能·opencv·计算机视觉
luofeiju2 天前
OpenCV图像缩放:resize
opencv
沐沐沐沐沐沐2 天前
图像认知与OpenCV | Day5:图像预处理(4)
人工智能·opencv·计算机视觉