图像处理的透视变换_图像处理基本算法--仿射变换和透视变换 - CSDN
  • 透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变...

    透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。


    透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。通用的变换公式为:


    u,v是原始图片坐标,对应得到变换后的图片坐标x,y,其中
    变换矩阵可以拆成4部分,表示线性变换,比如scaling(缩放),shearing(错切)和ratotion(翻转)。用于平移,产生透视变换。所以可以理解成仿射(线性变换+平移)等是透视变换的特殊形式。经过透视变换之后的图片通常不是平行四边形(除非映射视平面和原来平面平行的情况)。

    重写之前的变换公式可以得到(默认w为1?)


    所以,已知变换对应的几个点就可以求取变换公式,反之,特定的变换公式也能生成新的变换后的图片。简单的看一个正方形到四边形的变换:
    变换的4组对应点可以表示成:

    根据变换公式得到(默认a33为1?)


    定义几个辅助变量:


    都为0时变换平面与原来是平行的,可以得到:


    不为0时,得到:


    求解出的变换矩阵就可以将一个正方形变换到四边形。反之,四边形变换到正方形也是一样的。于是,我们通过两次变换:四边形变换到正方形+正方形变换到四边形就可以将任意一个四边形变换到另一个四边形。


    看一段代码:

    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. PerspectiveTransform::PerspectiveTransform(float inA11, float inA21,   
    2.                                            float inA31, float inA12,   
    3.                                            float inA22, float inA32,   
    4.                                            float inA13, float inA23,   
    5.                                            float inA33) :   
    6.   a11(inA11), a12(inA12), a13(inA13), a21(inA21), a22(inA22), a23(inA23),  
    7.   a31(inA31), a32(inA32), a33(inA33) {}  
    8.   
    9. PerspectiveTransform PerspectiveTransform::quadrilateralToQuadrilateral(float x0, float y0, float x1, float y1,  
    10.     float x2, float y2, float x3, float y3, float x0p, float y0p, float x1p, float y1p, float x2p, float y2p,  
    11.     float x3p, float y3p) {  
    12.   PerspectiveTransform qToS = PerspectiveTransform::quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);  
    13.   PerspectiveTransform sToQ =  
    14.     PerspectiveTransform::squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);  
    15.   return sToQ.times(qToS);  
    16. }  
    17.   
    18. PerspectiveTransform PerspectiveTransform::squareToQuadrilateral(float x0, float y0, float x1, float y1, float x2,  
    19.     float y2, float x3, float y3) {  
    20.   float dx3 = x0 - x1 + x2 - x3;  
    21.   float dy3 = y0 - y1 + y2 - y3;  
    22.   if (dx3 == 0.0f && dy3 == 0.0f) {  
    23.     PerspectiveTransform result(PerspectiveTransform(x1 - x0, x2 - x1, x0, y1 - y0, y2 - y1, y0, 0.0f,  
    24.                                      0.0f, 1.0f));  
    25.     return result;  
    26.   } else {  
    27.     float dx1 = x1 - x2;  
    28.     float dx2 = x3 - x2;  
    29.     float dy1 = y1 - y2;  
    30.     float dy2 = y3 - y2;  
    31.     float denominator = dx1 * dy2 - dx2 * dy1;  
    32.     float a13 = (dx3 * dy2 - dx2 * dy3) / denominator;  
    33.     float a23 = (dx1 * dy3 - dx3 * dy1) / denominator;  
    34.     PerspectiveTransform result(PerspectiveTransform(x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0, y1 - y0  
    35.                                      + a13 * y1, y3 - y0 + a23 * y3, y0, a13, a23, 1.0f));  
    36.     return result;  
    37.   }  
    38. }  
    39.   
    40. PerspectiveTransform PerspectiveTransform::quadrilateralToSquare(float x0, float y0, float x1, float y1, float x2,  
    41.     float y2, float x3, float y3) {  
    42.   // Here, the adjoint serves as the inverse:  
    43.   return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();  
    44. }  
    45.   
    46. PerspectiveTransform PerspectiveTransform::buildAdjoint() {  
    47.   // Adjoint is the transpose of the cofactor matrix:  
    48.   PerspectiveTransform result(PerspectiveTransform(a22 * a33 - a23 * a32, a23 * a31 - a21 * a33, a21 * a32  
    49.                                    - a22 * a31, a13 * a32 - a12 * a33, a11 * a33 - a13 * a31, a12 * a31 - a11 * a32, a12 * a23 - a13 * a22,  
    50.                                    a13 * a21 - a11 * a23, a11 * a22 - a12 * a21));  
    51.   return result;  
    52. }  
    53.   
    54. PerspectiveTransform PerspectiveTransform::times(PerspectiveTransform other) {  
    55.   PerspectiveTransform result(PerspectiveTransform(a11 * other.a11 + a21 * other.a12 + a31 * other.a13,  
    56.                                    a11 * other.a21 + a21 * other.a22 + a31 * other.a23, a11 * other.a31 + a21 * other.a32 + a31  
    57.                                    * other.a33, a12 * other.a11 + a22 * other.a12 + a32 * other.a13, a12 * other.a21 + a22  
    58.                                    * other.a22 + a32 * other.a23, a12 * other.a31 + a22 * other.a32 + a32 * other.a33, a13  
    59.                                    * other.a11 + a23 * other.a12 + a33 * other.a13, a13 * other.a21 + a23 * other.a22 + a33  
    60.                                    * other.a23, a13 * other.a31 + a23 * other.a32 + a33 * other.a33));  
    61.   return result;  
    62. }  
    63.   
    64. void PerspectiveTransform::transformPoints(vector<float> &points) {  
    65.   int max = points.size();  
    66.   for (int i = 0; i < max; i += 2) {  
    67.     float x = points[i];  
    68.     float y = points[i + 1];  
    69.     float denominator = a13 * x + a23 * y + a33;  
    70.     points[i] = (a11 * x + a21 * y + a31) / denominator;  
    71.     points[i + 1] = (a12 * x + a22 * y + a32) / denominator;  
    72.   }  
    73. }  
    对一张透视图片变换回正面图的效果:

    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. int main(){  
    2.     Mat img=imread("boy.png");  
    3.     int img_height = img.rows;  
    4.     int img_width = img.cols;  
    5.     Mat img_trans = Mat::zeros(img_height,img_width,CV_8UC3);  
    6.     PerspectiveTransform tansform = PerspectiveTransform::quadrilateralToQuadrilateral(  
    7.         0,0,  
    8.         img_width-1,0,  
    9.         0,img_height-1,  
    10.         img_width-1,img_height-1,  
    11.         150,250, // top left  
    12.         771,0, // top right  
    13.         0,1023,// bottom left  
    14.         650,1023  
    15.         );  
    16.     vector<float> ponits;  
    17.     for(int i=0;i<img_height;i++){  
    18.         for(int j=0;j<img_width;j++){  
    19.             ponits.push_back(j);  
    20.             ponits.push_back(i);  
    21.         }  
    22.     }  
    23.     tansform.transformPoints(ponits);  
    24.     for(int i=0;i<img_height;i++){  
    25.         uchar*  t= img_trans.ptr<uchar>(i);  
    26.         for (int j=0;j<img_width;j++){  
    27.             int tmp = i*img_width+j;  
    28.             int x = ponits[tmp*2];  
    29.             int y = ponits[tmp*2+1];  
    30.             if(x<0||x>(img_width-1)||y<0||y>(img_height-1))  
    31.                 continue;  
    32.             uchar* p = img.ptr<uchar>(y);  
    33.             t[j*3] = p[x*3];  
    34.             t[j*3+1] = p[x*3+1];  
    35.             t[j*3+2] = p[x*3+2];  
    36.         }  
    37.     }  
    38.     imwrite("trans.png",img_trans);  
    39.     return 0;  
    40. }  




    另外在OpenCV中也实现了基础的透视变换操作,有关函数使用请见下一篇:【OpenCV】透视变换 Perspective Transformation(续)

    转载自:http://blog.csdn.net/xiaowei_cqu/article/details/26471527
    展开全文
  • 1. 最近在做身份证OCR项目中,需要对倾斜扭曲的图像做矫正,透视变换正可以解决这个问题,在这里记录对变换方法的理解。 2. 本文主要介绍一下仿射变换和透视变换的原理,特点以及其在opencv中实现的一些注意点。 3...

    一. 前言

    1. 最近在做身份证OCR项目中,需要对倾斜扭曲的图像做矫正,透视变换正可以解决这个问题,在这里记录对变换方法的理解。

    2. 本文主要介绍一下仿射变换和透视变换的原理,特点以及其在opencv中实现的一些注意点。

    3. 首先看下透视变换后的例图:

                    

    二. 从仿射变换说起

    透视变换和仿射变换在原理上比较相似,而仿射变换更加简单。

    1. 定义:仿射变换(Affine Transformation或 Affine Map),又称为仿射映射,是指在几何中,图像进行从一个向量空间进行一次线性变换和一次平移,变换为到另一个向量空间的过程。

    2. 特性:仿射变换保持了二维图形的平直性和平行性。平直性:变换是直线的,变换后还是直线;平行性:二维图形之间的相对位置关系保持不变。

    3. 公式:如图所示

     

     

        其中,

    • M表示变换矩阵,它包括线性变换矩阵A和平移矩阵B;
    • [x, y]T代表原始图像矩阵,是一个二维数组,x代表像素的横坐标,y代表像素的纵坐标;
    • T代表经过仿射变换后的图像矩阵。

    4. 理解:

    • 在几何中,任何变换都可以以矩阵乘法(线性变换)的形式表示,图像中的平移操作可以以矢量加法(平移)的形式表示;

    • 一个任意的仿射变换都可以表示为乘以一个矩阵再加上一个向量的形式;[x, y]T代表原始图像矩阵,是一个二维数组,x代表像素的横坐标,y代表像素的纵坐标;
    • 如果线性变换矩阵A=[[1, 0], [0,1]],那么A点乘矩阵[x, y]T 就不会改变[x, y]T的信息,此时,仿射变换就变成了平移操作,移动的行列值就是矩阵B中的元素值;
    • 如果线性矩阵A=[[cosθ, -sinθ], [sinθ, cosθ]],那么线性变换就变成了图片的旋转操作,旋转角度θ。矩阵B代表旋转中心的坐标便宜量。两个矩阵的计算方式如下图:

        

    5. 应用:

     

    三. 再说透视变换

        有了仿射变换的理解,下面说透视变换就简单了,因为它是仿射变换的一种非线性扩展。

    1. 定义:透视变换(Perspective Transformation)就是将图片投影到一个新的视平面,也称为投影映射。

    2. 特性:相对仿射变换来说,改变了直线之间的平行关系。

    3. 直接看公式:通用的变换公式如下

                            

        其中,

    • u, v代表原始图片坐标,x, y为经过透视变换的图片坐标;
    • 变换矩阵为3*3,它可以拆分为四个部分
    • [a11, a12, a21, a22]为线性变换的矩阵,[a31, a32]为平移矩阵,这两个矩阵等价于仿射变换的变换矩阵;
    • [a13,a23]为产生透视变换的矩阵;
    • 因此变换公式也可以表示为:

                            

    4. 理解:

    • 在3*3的变换矩阵M中,包含了线性变换矩阵和平移矩阵,因此,仿射变换可以看作透视变换的一种特殊形式;
    • 经过透视变换后的图片通常不是平行四边形(除非映射平面和原平面平行);
    • 求取转换矩阵时,需要四个点的坐标,同时要保证至少三个不在同一直线;
    • 已知4个点的坐标和想要变换成的矩阵坐标,即可求出3*3的变换矩阵。

     

    5. 应用:

    6. 代码:

    # 身份证的模版技术
    import cv2
    import numpy as np
    import os
    from matplotlib import pyplot as plt
    from math import *
    
    img_path = ""
    img = cv2.imread(img_path, 0)
    print("原图")
    plt.imshow(img, cmap='gray', interpolation='bicubic')
    plt.show()
    txt_path = img_path.split('.')[0] + '.txt'
    
    # Roi顺时针坐标
    with open(txt_path, encoding='utf-8') as f:
    rec = list(map(float, f.readline().strip().split(',')))
    # print(rec)
    xDim, yDim = img.shape[1], img.shape[0]
    pt1 = (max(1, rec[0]), max(1, rec[1]))
    pt2 = (rec[2], rec[3])
    pt3 = (rec[4], rec[5])
    pt4 = (min(rec[6], xDim - 2), min(yDim - 2, rec[7]))
    pts = np.array([pt1, pt2, pt3, pt4], np.int32)
    
    H_rows, W_cols= 400, 600
    # print(H_rows, W_cols)
    # 原图中书本的四个角点(左上、右上、左下、右下),与变换后矩阵位置
    pts1 = np.float32([pt1, pt2, pt3, pt4])
    pts2 = np.float32([[0, 0],[W_cols,0],[W_cols, H_rows],[0, H_rows],])
    
    # 生成透视变换矩阵;进行透视变换
    M = cv2.getPerspectiveTransform(pts1, pts2)
    # print(M)
    dst = cv2.warpPerspective(img, M, dsize=(W_cols,H_rows))
    
    print("校正之后的图")
    plt.imshow(dst, cmap='gray', interpolation='bicubic')
    plt.show()

     

    展开全文
  • 该系列文章是讲解Python OpenCV图像处理知识,主要讲解图像入门、OpenCV基础用法。前面的第六篇文章讲解了图像缩放、图像旋转、图像翻转和图像平移的几何变换,本篇文章主要讲解图像仿射变换和图像透视变换,通过...

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。希望文章对您有所帮助,如果有不足之处,还请海涵~

    该系列在github所有源代码:https://github.com/eastmountyxz/ImageProcessing-Python
    PS:请求帮忙点个Star,哈哈,第一次使用Github,以后会分享更多代码,一起加油。

    同时推荐作者的C++图像系列知识:
    [数字图像处理] 一.MFC详解显示BMP格式图片
    [数字图像处理] 二.MFC单文档分割窗口显示图片
    [数字图像处理] 三.MFC实现图像灰度、采样和量化功能详解
    [数字图像处理] 四.MFC对话框绘制灰度直方图
    [数字图像处理] 五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理详解
    [数字图像处理] 六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解
    [数字图像处理] 七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

    前文参考:
    [Python图像处理] 一.图像处理基础知识及OpenCV入门函数
    [Python图像处理] 二.OpenCV+Numpy库读取与修改像素
    [Python图像处理] 三.获取图像属性、兴趣ROI区域及通道处理
    [Python图像处理] 四.图像平滑之均值滤波、方框滤波、高斯滤波及中值滤波
    [Python图像处理] 五.图像融合、加法运算及图像类型转换
    [Python图像处理] 六.图像缩放、图像旋转、图像翻转与图像平移
    [Python图像处理] 七.图像阈值化处理及算法对比
    [Python图像处理] 八.图像腐蚀与图像膨胀
    [Python图像处理] 九.形态学之图像开运算、闭运算、梯度运算
    [Python图像处理] 十.形态学之图像顶帽运算和黑帽运算
    [Python图像处理] 十一.灰度直方图概念及OpenCV绘制直方图

    前面的第六篇文章讲解了图像缩放、图像旋转、图像翻转和图像平移的几何变换,本篇文章主要讲解图像仿射变换和图像透视变换,通过Python调用OpenCV函数实。基础性知识希望对您有所帮助。
    1.图像仿射变换
    2.图像透视变换
    3.基于图像透视变换的图像校正
    4.图像几何变换总结

    PS:文章参考自己以前系列图像处理文章及OpenCV库函数,同时,本篇文章涉及到《计算机图形学》基础知识,请大家下来补充。

    参考文献:
    Python下opencv使用笔记(三)(图像的几何变换)
    数字图像处理——图像的几何变换
    图像校正-透视变换——t6_17


    一.图像仿射变换

    图像仿射变换又称为图像仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间。通常图像的旋转加上拉升就是图像仿射变换,仿射变换需要一个M矩阵实现,但是由于仿射变换比较复杂,很难找到这个M矩阵.

    OpenCV提供了根据变换前后三个点的对应关系来自动求解M的函数——cv2.getAffineTransform(pos1,pos2),其中pos1和pos2表示变换前后的对应位置关系,输出的结果为仿射矩阵M,接着使用函数cv2.warpAffine()实现图像仿射变换。图5-14是仿射变换的前后效果图。

    图像仿射变换的函数原型如下:
    M = cv2.getAffineTransform(pos1,pos2)

    • pos1表示变换前的位置
    • pos2表示变换后的位置

    cv2.warpAffine(src, M, (cols, rows))

    • src表示原始图像
    • M表示仿射变换矩阵
    • (rows,cols)表示变换后的图像大小,rows表示行数,cols表示列数

    实现代码如下所示:

    #encoding:utf-8
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    #读取图片
    src = cv2.imread('test.bmp')
    
    #获取图像大小
    rows, cols = src.shape[:2]
    
    #设置图像仿射变换矩阵
    pos1 = np.float32([[50,50], [200,50], [50,200]])
    pos2 = np.float32([[10,100], [200,50], [100,250]])
    M = cv2.getAffineTransform(pos1, pos2)
    
    #图像仿射变换
    result = cv2.warpAffine(src, M, (cols, rows))
    
    #显示图像
    cv2.imshow("original", src)
    cv2.imshow("result", result)
    
    #等待显示
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    输出效果图如下所示:


    二.图像透视变换

    图像透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,同理OpenCV通过函数cv2.getPerspectiveTransform(pos1,pos2)构造矩阵M,其中pos1和pos2分别表示变换前后的4个点对应位置。得到M后在通过函数cv2.warpPerspective(src,M,(cols,rows))进行透视变换。

    图像透视变换的函数原型如下:

    M = cv2.getPerspectiveTransform(pos1, pos2)

    • pos1表示透视变换前的4个点对应位置
    • pos2表示透视变换后的4个点对应位置

    cv2.warpPerspective(src,M,(cols,rows))

    • src表示原始图像
    • M表示透视变换矩阵
    • (rows,cols)表示变换后的图像大小,rows表示行数,cols表示列数

    代码如下:

    #encoding:utf-8
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    #读取图片
    src = cv2.imread('test01.jpg')
    
    #获取图像大小
    rows, cols = src.shape[:2]
    
    #设置图像透视变换矩阵
    pos1 = np.float32([[114, 82], [287, 156], [8, 322], [216, 333]])
    pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]])
    M = cv2.getPerspectiveTransform(pos1, pos2)
    
    #图像透视变换
    result = cv2.warpPerspective(src, M, (190, 272))
    
    #显示图像
    cv2.imshow("original", src)
    cv2.imshow("result", result)
    
    #等待显示
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    输出结果如下图所示:


    三.基于图像透视变换的图像校正

    下面参考 t6_17大神 的文章,通过图像透视变换实现图像校正功能。

    假设现在存在一张A4纸图像,现在需要通过调用图像透视变换校正图像。

    代码如下所示:

    #encoding:utf-8
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    #读取图片
    src = cv2.imread('test01.jpg')
    
    #获取图像大小
    rows, cols = src.shape[:2]
    
    #将源图像高斯模糊
    img = cv2.GaussianBlur(src, (3,3), 0)
    #进行灰度化处理
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    #边缘检测(检测出图像的边缘信息)
    edges = cv2.Canny(gray,50,250,apertureSize = 3)
    cv2.imwrite("canny.jpg", edges)
    
    #通过霍夫变换得到A4纸边缘
    lines = cv2.HoughLinesP(edges,1,np.pi/180,50,minLineLength=90,maxLineGap=10)
    
    #下面输出的四个点分别为四个顶点
    for x1,y1,x2,y2 in lines[0]:
        print(x1,y1),(x2,y2)
    for x1,y1,x2,y2 in lines[1]:
        print(x1,y1),(x2,y2)
    
    #绘制边缘
    for x1,y1,x2,y2 in lines[0]:
        cv2.line(gray, (x1,y1), (x2,y2), (0,0,255), 1)
    
    #根据四个顶点设置图像透视变换矩阵
    pos1 = np.float32([[114, 82], [287, 156], [8, 322], [216, 333]])
    pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]])
    M = cv2.getPerspectiveTransform(pos1, pos2)
    
    #图像透视变换
    result = cv2.warpPerspective(src, M, (190, 272))
    
    #显示图像
    cv2.imshow("original", src)
    cv2.imshow("result", result)
    
    #等待显示
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    运行结果如下图所示:


    四.图像几何变换总结

    最后补充图像几何代码所有变换,希望读者能体会下相关的代码,并动手实践下。输出结果以女神为例:

    完整代码如下:

    #encoding:utf-8
    import cv2  
    import numpy as np
    import matplotlib.pyplot as plt
     
    #读取图片
    img = cv2.imread('test3.jpg')
    image = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    
    #图像平移矩阵
    M = np.float32([[1, 0, 80], [0, 1, 30]])
    rows, cols = image.shape[:2]
    img1 = cv2.warpAffine(image, M, (cols, rows))
    
    #图像缩小
    img2 = cv2.resize(image, (200,100))
    
    #图像放大
    img3 = cv2.resize(image, None, fx=1.1, fy=1.1)
    
    #绕图像的中心旋转
    #源图像的高、宽 以及通道数
    rows, cols, channel = image.shape
    #函数参数:旋转中心 旋转度数 scale
    M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1) 
    #函数参数:原始图像 旋转参数 元素图像宽高
    img4 = cv2.warpAffine(image, M, (cols, rows))
    
    #图像翻转
    img5 = cv2.flip(image, 0)   #参数=0以X轴为对称轴翻转 
    img6 = cv2.flip(image, 1)   #参数>0以Y轴为对称轴翻转
    
    #图像的仿射
    pts1 = np.float32([[50,50],[200,50],[50,200]])
    pts2 = np.float32([[10,100],[200,50],[100,250]])
    M = cv2.getAffineTransform(pts1,pts2)
    img7 = cv2.warpAffine(image, M, (rows,cols))
    
    #图像的透射
    pts1 = np.float32([[56,65],[238,52],[28,237],[239,240]])
    pts2 = np.float32([[0,0],[200,0],[0,200],[200,200]])
    M = cv2.getPerspectiveTransform(pts1,pts2)
    img8 = cv2.warpPerspective(image,M,(200,200))
    
    
    #循环显示图形
    titles = [ 'source', 'shift', 'reduction', 'enlarge', 'rotation', 'flipX', 'flipY', 'affine', 'transmission']  
    images = [image, img1, img2, img3, img4, img5, img6, img7, img8]  
    for i in xrange(9):  
       plt.subplot(3, 3, i+1), plt.imshow(images[i], 'gray')  
       plt.title(titles[i])  
       plt.xticks([]),plt.yticks([])  
    plt.show()  
    

    希望文章对大家有所帮助,如果有错误或不足之处,还请海涵。最近连续奔波考博,经历的事情太多,有喜有悲,需要改变自己好好对家人,也希望读者与我一起加油。
    (By:Eastmount 2019-03-20 早上12点 https://blog.csdn.net/Eastmount/)

    展开全文
  • 仿射变换和透视变换更直观的叫法可以叫做“平面变换”和“空间变换”或者“二维坐标变换”和“三维坐标变换”。一个是二维坐标(x,y),一个是三维坐标(x,y,z)。也就是:仿射变换: 透视变换: 从另一个角度也能说明三...

    仿射变换和透视变换更直观的叫法可以叫做“平面变换”和“空间变换”或者“二维坐标变换”和“三维坐标变换”。一个是二维坐标(x,y),一个是三维坐标(x,y,z)。也就是:

    仿射变换:
    这里写图片描述

    透视变换:
    这里写图片描述

    从另一个角度也能说明三维变换和二维变换的意思,仿射变换的方程组有6个未知数,所以要求解就需要找到3组映射点,三个点刚好确定一个平面。透视变换的方程组有8个未知数,所以要求解就需要找到4组映射点,四个点就刚好确定了一个三维空间。

    

    图像最常用的是仿射变换一般形式如下:


    (x, y)为变换后的坐标,(v, w)为变换前的坐标。通过变换矩阵T,可以进行图像的缩放,旋转,平移等。

    空间图像几何变换包括两个主要步骤:

    (1) 空间坐标变换

    (2)变换坐标的赋值、插值运算

    有了上面仿射矩阵的坐标的变换,下面一步就是进行像素灰度级的赋值了。从原始图像映射到变换图像,赋值的时候需要进行插值运算。通常情况下有三种插值运算:最邻近插值法、双线性插值法、双三次插值法。【代码最后做了双线性内插的,保证得到的图像更平滑。】

    在仿射变换的一般表达式中,有两种基本的变换方法。第一种是forward mapping, 第二种 是inverse mapping(backward mapping)。在inverse mapping 中,(v, w) = T¬-1(x, y)。一般情况下,inverse mapping 比forward mapping更有效。仿射变换的原始坐标中,首先将原坐标变换为齐次坐标(齐次坐标的理解)。并且经过仿射变换后,你有了图像插值的基础,这样你就可以学习Image Warping了。姑且翻译为图像扭曲吧。Image Warping 同时也分为 Forward Warping 和 Backward Warping。

    【前向映射一个问题是,输入图像的的两个或多个像素会映射到输出图像的同一个位置,另一种可能是某些输出位置完全没有像素,因此反向映射比前向映射更加有效】

    Image Warping:




    和Mapping一样,都是从原始图像向目标图像映射。其中(x’,y’)= T(x,y),x,y为原始图像坐标。同理,作为Backward Warping则为相反的方向。




    其中,(x,y) =inverse(T (x’,y’))。就是从目标图像向原始图像进行映射了。


    总结图像做图像扭曲(warp)步骤是:先根据两幅图像的三对对应点计算出仿射变换矩阵,再将原图像根据这个变换矩阵变换到后图像(插值)(或采取逆向)

    展开全文
  • 图像处理的仿射变换和透视变换其实一直也没理解“仿射”俩字是啥意思,但是大家都这么叫,其实仿射变换和透视变换更直观的叫法可以叫做“平面变换”和“空间变换”或者“二维坐标变换”和“三维坐标变换”。...

    图像处理的仿射变换和透视变换

    其实一直也没理解“仿射”俩字是啥意思,但是大家都这么叫,其实仿射变换和透视变换更直观的叫法可以叫做“平面变换”和“空间变换”或者“二维坐标变换”和“三维坐标变换”。如果这么命名的话,其实很显然,这俩是一回事,只不过一个是二维坐标(x,y),一个是三维坐标(x,y,z)。也就是:

    仿射变换:
    这里写图片描述

    透视变换:
    这里写图片描述

    从另一个角度也能说明三维变换和二维变换的意思,仿射变换的方程组有6个未知数,所以要求解就需要找到3组映射点,三个点刚好确定一个平面。透视变换的方程组有8个未知数,所以要求解就需要找到4组映射点,四个点就刚好确定了一个三维空间。

    写个程序求解线性方程组相信不是什么难事。

    解出方程组之后,就可以按照上面的方程,找到与结果图像上对应的源像素点。然后做插值。

    看一下效果啊:

    原图:
    这里写图片描述

    仿射变换之后:
    这里写图片描述

    透视变换之后:
    这里写图片描述

    从上图也能看出来区别,仿射变换之后还是平行四边形,透视变换之后就只剩下四边形了。图像的旋转缩放理论上都能用仿射变换来实现(90度、180度、270度的旋转用仿射变换实现不划算)。透视变换的用途可能更多一些,比如:
    你扫到的二维码是这样的:
    这里写图片描述
    这样你直接读二维码信息肯定不行,所以需要透视变换一下,成这样:
    这里写图片描述
    就可以读出信息了。

    刚才讲,求解仿射变换需要3组对应的点,求解透视变换需要4组对应的点,如果找到的映射点的数量少于3组或4组就肯定解不出来,但是如果多于3组或4组怎么办?那就要最小二乘法做拟合,找到一个最佳变换方程。这个不细说了。

    展开全文
  • 人的眼睛看近的物体要比远的物体要大。这通常称之为透视。...所以,总的来说,透视变换处理3D世界转换成二维图像。人的视觉工作原理与相机的工作原理一样。 我们首先开始讨论参照系的概念: 参照系:
  • 要构建这个变换矩阵,你需要在输入图像上找 4 个点,以及他们在输出图 像上对应的位置。这四个点中的任意三个都不能共线。这个变换矩阵可以有 函数 cv2.getPerspectiveTransform() 构建。然后把这个矩阵传给函数 ...
  •   这一周主要在研究图像的放射变换与透视变换,目前出现的主要问题是需要正确识别如下图中的编码标志点圆心。 1.当倾斜角较小时: 2.倾斜角较大时:   由上面两幅图可以看出,当倾斜角较大时,中间的圆斑...
  • 透视变换在两幅图像中进行对应非常有用,看下面的两幅图 第一幅图是源图像,图中有五个点,分别是四个顶点和中间的一个点(对应目标图中的中心点)   第二幅图是目标图,包括与源图像中的五个点对应的五...
  • 图像透视变换应用

    2019-11-26 23:27:21
    简介 透视变换是将成像投影到一个新的视平面,也称作投影映射。投影变换是三维空间上的非线性变换,可看做是仿射变换的更一般形式,简单讲即通过一个3...利用透视矩阵对图像进行透视变换。 说明 OpenCV提供了warp...
  • 图像透视变换

    2014-02-23 10:32:24
    前几天写了一篇图像的仿射变换,因为图像的仿射变换是图像透视变换的子集,所以了解掌握图像的仿射变换是很重要的。
  • Matlab中的透视变换

    2019-03-20 10:06:26
    目的:将两幅尺寸不一,形状不同的图像上的像素点一 一对应起来。...例如:已知一幅100x100大小的图像,resize为224x224后,可以通过透视变换,获得原图像上像素坐标在224x224图像上的对应坐标。 100x100 ...
  • function perspectiveTmg=perspectiveTrans(sourceImg,x_para,y_para) %x_para [-1,1] [-1,0]-look from left [0,1]-look form right %y_para [-1,1] [-1,0]-look from top [0,1]-look from bott
  • 先贴上代码和图function perspective_mat = get...% GETPERSPECTIVE 根据点获取透视变换矩阵 % 输入: % moving_points:n*2点集坐标(x,y) % fixed_points:n*2点集坐标(x,y),点顺序要对应moving_points % 输...
  • 参考文章:OpenCV图像变换(仿射变换与透视变换)、图像处理的仿射变换与透视变换 3D视觉工坊 仿射变换(affine transform)和透视变换(perspective transform)在图像还原、图像局部变换处理方面有重要意义。其实仿射...
1 2 3 4 5 ... 20
收藏数 7,673
精华内容 3,069
关键字:

图像处理的透视变换