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

相关推荐
清醒的兰10 小时前
OpenCV 图像像素的算术操作
人工智能·opencv·计算机视觉
s1533513 小时前
3.RV1126-OPENCV 图像叠加
人工智能·opencv·计算机视觉
机器学习算法1 天前
基于 OpenCV 和 DLib 实现面部特征调整(眼间距、鼻子、嘴巴)
人工智能·深度学习·神经网络·opencv·目标检测·机器学习·计算机视觉
YxVoyager1 天前
OpenCV C++ 学习笔记(三):矩阵基本操作、遍历图像矩阵的方法及性能分析
c++·opencv
youshang520i1 天前
Mac M1编译OpenCV获取libopencv_java490.dylib文件
opencv·macos
AndrewHZ2 天前
【图像处理入门】2. Python中OpenCV与Matplotlib的图像操作指南
图像处理·python·opencv·计算机视觉·matplotlib·图像操作
whoarethenext2 天前
磨皮功能 C++/C的OpenCV 实现
c语言·c++·opencv·磨皮功能
yes or ok3 天前
二、OpenCV图像处理-图像处理
图像处理·人工智能·opencv
jndingxin3 天前
OpenCV CUDA模块直方图计算------用于在 GPU 上执行对比度受限的自适应直方图均衡类cv::cuda::CLAHE
人工智能·opencv·计算机视觉
layneyao3 天前
计算机视觉入门:OpenCV与YOLO目标检测
opencv·yolo·计算机视觉