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

相关推荐
骄傲的心别枯萎13 小时前
RV1126 NO.57:ROCKX+RV1126人脸识别推流项目之读取人脸图片并把特征值保存到sqlite3数据库
数据库·opencv·计算机视觉·sqlite·音视频·rv1126
中年程序员一枚16 小时前
cv2.sqrBoxFilter 是 OpenCV 中用于计算像素邻域平方和的盒式滤波函数
人工智能·opencv·计算机视觉
棒棒的皮皮16 小时前
【OpenCV】Python图像处理之平滑处理
图像处理·python·opencv·计算机视觉
棒棒的皮皮17 小时前
【OpenCV】Python图像处理之重映射
图像处理·python·opencv·计算机视觉
中年程序员一枚17 小时前
cv2.blur 是 OpenCV 中实现均值滤波(归一化盒式滤波) 的核心函数
人工智能·opencv·均值算法
技术净胜1 天前
MATLAB进行图像分割从基础阈值到高级分割
opencv·计算机视觉·matlab
骄傲的心别枯萎1 天前
RV1126 NO.56:ROCKX+RV1126人脸识别推流项目之VI模块和VENC模块讲解
人工智能·opencv·计算机视觉·音视频·rv1126
骄傲的心别枯萎1 天前
RV1126 NO.55:ROCKX+RV1126人脸识别推流项目讲解
opencv·计算机视觉·音视频·rv1126
码界奇点1 天前
Python与OpenCV集成海康威视工业相机从基础配置到高级应用的全方位指南
python·数码相机·opencv·相机·python3.11
棒棒的皮皮1 天前
【OpenCV】Python图像处理几何变换之透视
图像处理·python·opencv·计算机视觉