在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 颜色识别实战:从 HSV 原理到摄像头实时检测
人工智能·opencv·计算机视觉
ahccqw14 小时前
OpenCV 缩放 与 位移
人工智能·opencv·计算机视觉
AI的探索之旅1 天前
OpenCV Day40 —— K-means 聚类与 EM 高斯混合
opencv·kmeans·聚类
AI的探索之旅1 天前
OpenCV Day39 —— 无缝克隆 seamless cloning(cloning_demo / cloning_gui)
人工智能·opencv
小豆庄1 天前
会议录屏忘打码后的技术复盘:本地自动化隐私脱敏方案
运维·opencv·目标检测·自动化·视频·纹理贴图
小豆庄1 天前
监控视频脱敏:夜视/低光线条件下人脸检测的工程处理思路
opencv·计算机视觉·阿里云·视觉检测·音视频·视频
小豆庄2 天前
视频遮罩追踪退场后ID撞号的排查—多目标场景下的失效
opencv·算法·bug·视频·python3.11
zwc32104320552 天前
Day 2:图像内存、数据类型与stride
c++·人工智能·opencv·算法·计算机视觉
誰能久伴不乏2 天前
OpenCV 入门(二):像素访问、ROI 与深浅拷贝
人工智能·opencv·计算机视觉
zwc32104320552 天前
第四周第五天——重构成类
c++·人工智能·opencv·算法·计算机视觉