精华内容
下载资源
问答
  • 写文章不易,如果您觉得此文对您有所帮助,请帮忙点赞、评论、收藏,感谢您! 一. 仿射变换介绍:  请参考:图解图像仿射变换... python实现仿射变换——图像平移 import cv2 import numpy as np # 图像仿射变换->图
  • 主要介绍了Python 在OpenCV里实现仿射变换—坐标变换效果,本文通过一个例子给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • 5.我们利用这个角度得到一个旋转的矩形(仿射变换所需要的) 6.使用仿射变换得到矫正后的图像 1.得到灰度图像 //读取图像 src= cv.imread('imageTextR.png') //cv.imshow('src',src) //cvtColor函数用于转换色彩...

    主要流程:

    1.首先得到灰度图像
    2.对灰度图像进行二值化
    3.然后找一个最小矩形框住对象轮廓(opencv中有相应的函数)
    4.这个最小矩形的函数会返回一个角度
    5.我们利用这个角度得到一个旋转的矩形(仿射变换所需要的)
    6.使用仿射变换得到矫正后的图像

    1.得到灰度图像

    //读取图像
    src= cv.imread('imageTextR.png')
    (h,w)=src.shape[:2]
    //记录图像宽高,后面会用
    //cv.imshow('src',src)  
    //cvtColor函数用于转换色彩空间,将图像转换为GRAY灰度图像
    gray=cv.cvtColor(src,cv.COLOR_BGR2GRAY)
    
    

    我们需要矫正的图像
    这是我们需要矫正的图像

    2.对灰度图像进行二值化

    ret,binary = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
    #由于文本是黑底白字的,我们需要让背景是黑色的,所以我们在传入参数的时候需要使用cv.THRESH_BINARY_INV 加上_INV使二值图反转
    

    二值图
    这是二值图

    3.找一个最小矩形框住对象轮廓

    coords=np.column_stack(np.where(binary>0))
    

    np.where(binary>0):可以理解为找出二值图中所有的白色
    np.column_stack(np.where(binary>0)):将所有白色的像素统计起来

    这里可以看到返回的coords的大小是(24527,2)即二值图中共有24527个白色像素点。

    4.得到矩形角度

    接下使用cv的minAreaRect函数求出最小外接矩形,传入的参数要求为点集数组或向量。返回的参数有三个:1.矩形的中心点 2.矩形的长和宽 3.矩形的旋转角度

    angle =cv.minAreaRect(coords)[-1] 
    //[-1]表示返回参数中的最后一个,即角度
    

    角度是根据这个规则来的:
    在这里插入图片描述
    这里我们默认倾斜角度不是特别大,所以如果我们的倾斜角度大于-45度我们就将其矫正为水平的,如果小于-45度我们将其矫正为垂直的:

    if angle<-45:
        angle = -(90+angle)
    else:
        angle=-angle
    center = (w//2,h//2)
    //求出矩形中点
    

    5.我们利用这个角度得到一个旋转变换的矩形(仿射变换所需要的)

    使用cv.getRotationMatrix2D()来得到选择最小外接旋转矩形,3个参数分别为旋转中心,旋转角度,旋转后图像的缩放比例

    M= cv.getRotationMatrix2D(center,angle,1.0) 
    

    6.使用仿射变换得到矫正后的图像

    使用cv.warpAffine来进行仿射变换,传入参数为:需要处理的图像,旋转变换矩阵,宽高,flags:插值方法,borderMode:边界填充

    rotated = cv.warpAffine(src,M,(w,h),flags=cv.INTER_CUBIC,borderMode=cv.BORDER_REPLICATE)
    

    在这里插入图片描述
    得到的矫正后的图片

    如果觉得有用 点个赞哦 谢谢啦
    最后附上完整代码:

    import numpy as np
    import cv2 as cv
    
    
    def binary(img):
        gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
        ret,binary = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
        return binary
    
    def  Transformation(img,src):
        coords=np.column_stack(np.where(img>0))
        print(coords)
        print(coords.shape)
        angle =cv.minAreaRect(coords)[-1]    #最小外接矩形
    
        print(angle)
        if angle<-45:
            angle = -(90+angle)
        else:
            angle=-angle
        center = (w//2,h//2)
        M= cv.getRotationMatrix2D(center,angle,1.0) #传入中心和角度 得到旋转矩形
        rotated = cv.warpAffine(src,M,(w,h),flags=cv.INTER_CUBIC,borderMode=cv.BORDER_REPLICATE)
        cv.putText(rotated,'Angle:{:.2f} degrees'.format(angle),(10,30),cv.FONT_HERSHEY_SIMPLEX,0.7,(0,0,255),2)#绘制文字
        cv.imshow('Rotated',rotated)
    
    
    src= cv.imread('imageTextR.png')
    (h,w)=src.shape[:2]
    gray=cv.cvtColor(src,cv.COLOR_BGR2GRAY)
    binary=binary(src)
    Transformation(binary,src)
    cv.imshow('src',src)
    cv.imshow('binary',binary)
    cv.waitKey(0)
    
    
    
    
    展开全文
  • python3 图片仿射变换

    2016-05-17 09:24:00
    图片仿射变换示例。
  • 图像img的像素为534*300,img.shape = (300, 534, 3)。 需要引入: import cv2 as cv import numpy as np ...img.shape得到的(300, 534, 3),前者300是高度,y轴的值...cv2.warpAffine() 仿射变换(从二维坐标到二维

    图像img的像素为534*300,img.shape = (300, 534, 3)。

    需要引入:

    import cv2 as cv
    import numpy as np

    img.shape得到的(300, 534, 3),前者300是高度,y轴的值,后者534是宽度,x轴的值,这一点有些不同。

    图像的xy轴,是以图像左上角顶点为(0, 0)原点,类似于css。从顶点沿宽度向右是x正轴,沿高度向下是y正轴。

    一、平移变换

    cv2.warpAffine()   仿射变换(从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。仿射变换可以通过一系列的原子变换的复合来实现,包括平移,缩放,翻转,旋转和剪切)
        参数:
            img: 图像对象
            M:2*3 transformation matrix (转变矩阵)
            dsize:输出矩阵的大小,注意格式为(cols,rows)  即width对应cols,height对应rows
            flags:可选,插值算法标识符,有默认值INTER_LINEAR,
                   如果插值算法为WARP_INVERSE_MAP, warpAffine函数使用如下矩阵进行图像转dst(x,y)=src(M11*x+M12*y+M13,M21*x+M22*y+M23)
            borderMode:可选, 边界像素模式,有默认值BORDER_CONSTANT 
            borderValue:可选,边界取值,有默认值Scalar()即0

    下面的M矩阵表示向x轴正方向(向右)移动200像素,向y轴负方向(向上)移动100像素。

    # 创建转变矩阵
    M = np.float32([[1, 0, 200], [0, 1, -100]])
    # 使用warpAffine()方法执行变换
    img = cv.warpAffine(img, M, (500, 300))
    # 展示图片
    cv.imshow("img", img)
    cv.waitKey(0)

    二、缩放变换

    缩放变换的转变矩阵与平移变换的转变矩阵是一样的。

    M是一个2*3矩阵,[[1, 0, 100], [0, 1, 200]]。

    从左到右看,第一个“1”代表x轴(长度)是原来的几倍,“100”表示将原图沿x轴如何移动。

    第二个“1”表示y轴(宽度)是原来的几倍,“100”表示将原图沿y轴如何移动。

    下面的操作表示将原图放大1.5倍。

    # 创建转变矩阵
    M = np.float32([[1.5, 0, 0], [0, 1.5, 0]])
    # 执行变换,输出图片大小为500*400
    img = cv.warpAffine(img, M, (500, 400))
    # 展示图片
    cv.imshow("img", img)
    cv.waitKey(0)

    三、旋转变换

    通过getRotationMatrix2D()能得到转变矩阵M。

     cv2.getRotationMatrix2D()  返回2*3的转变矩阵(浮点型)
        参数:
            center:旋转的中心点坐标
            angle:旋转角度,单位为度数,证书表示逆时针旋转
            scale:同方向的放大倍数

    我们以图片的左上角(0,0)原点为旋转中心,旋转30°。

    # 创建旋转转变矩阵
    M = cv.getRotationMatrix2D((0, 0), 30, 1)
    # 执行转变
    img = cv.warpAffine(img, M, (500, 300))
    
    cv.imshow("img", img)
    cv.waitKey(0)

    四、三点定位,仿射变换矩阵的计算,cv2.getAffineTransform()

    通过图片变换前后的三组坐标定位,和cv2.getAffineTransform()方法,可以计算出我们需要的仿射变换矩阵M。

    该方法可以一定程度上代替上面三个方法,同时实现旋转、平移和缩放。

    getAffineTransform()等同于将平移,旋转和缩放的变换矩阵相乘,最后都会获得仿射变换矩阵。

    cv2.getAffineTransform()  返回2*3的转变矩阵
          参数:
              src:原图像中的三组坐标,如np.float32([[50,50],[200,50],[50,200]])
              dst: 转换后的对应三组坐标,如np.float32([[10,100],[200,50],[100,250]])
    

    img原图的四个角的坐标为[0, 0] , [534, 0], [0,300], [534, 300]。(此处为[x, y] 坐标形式,不同于shape)

    # 原图像中的三组坐标
    pts1 = np.float32([[0, 0] , [534, 0], [534, 300]])
    # 转换后的三组对应坐标
    pts2 = np.float32([[300, 0], [300, 534], [0, 534]])
    # 计算仿射变换矩阵
    M = cv.getAffineTransform(pts1, pts2)
    # 执行变换
    img = cv.warpAffine(img, M ,(300, 534))
    

    二维仿射变换总结:我们可以发现,上面的所有仿射变换矩阵M都是一个2*3的矩阵,而用来进行变换的方法都是同一个cv2.warpAffine()

    下面是三维仿射变换

    五、透视变换(三维)

    四、三点定位,仿射变换矩阵的计算类似,三维的仿射变换矩阵需要四组坐标来进行定位。

    与之前不同的是,我们需要使用另外两个方法getPerspectiveTransform()和warpPerspective(),仿射变换矩阵M变成了3*3矩阵。

    cv2.getPerspectiveTransform()   返回3*3的转变矩阵
            参数:    
                src:原图像中的四组坐标,如 np.float32([[56,65],[368,52],[28,387],[389,390]])
                dst: 转换后的对应四组坐标,如np.float32([[0,0],[300,0],[0,300],[300,300]])
    
                
            cv2.warpPerspective()
            参数:    
                src: 图像对象
                M:3*3 transformation matrix (转变矩阵)
                dsize:输出矩阵的大小,注意格式为(cols,rows)  即width对应cols,height对应rows
                flags:可选,插值算法标识符,有默认值INTER_LINEAR,
                       如果插值算法为WARP_INVERSE_MAP, warpAffine函数使用如下矩阵进行图像转dst(x,y)=src(M11*x+M12*y+M13,M21*x+M22*y+M23)
                borderMode:可选, 边界像素模式,有默认值BORDER_CONSTANT 
                borderValue:可选,边界取值,有默认值Scalar()即0

    我们将img图片的左上角和右上角往“里”缩一缩,同时左下角和右下角位置不变。

    # 原图的四组顶点坐标
    pts3D1 = np.float32([[0, 0], [534, 0], [0, 300], [534, 300]])
    # 转换后的四组坐标
    pts3D2 = np.float32([[100, 100], [434, 100], [0, 300], [534, 300]])
    # 计算透视放射矩阵
    M = cv.getPerspectiveTransform(pts3D1, pts3D2)
    # 执行变换
    img = cv.warpPerspective(img, M, (550, 400))

    展开全文
  • 图像的仿射变换原理及python实现

    万次阅读 多人点赞 2018-09-21 13:16:17
    1. 原理 ...仿射变换保持了二维图形的“平直性”(直线经仿射变换后依然为直线)和“平行性”(直线之间的相对位置关系保持不变,平行线经仿射变换后依然为平行线,且直线上点的位置顺序不会发生变化)...

    1. 原理

    1.1 原理

    仿射变换(Affine Transformation 或Affine Map)是一种二维坐标(x, y)到二维坐标(u, v)的线性变换,其数学表达式形式如下:
    在这里插入图片描述
    对应的齐次坐标矩阵表示形式为:
    在这里插入图片描述
    仿射变换保持了二维图形的“平直性”(直线经仿射变换后依然为直线)和“平行性”(直线之间的相对位置关系保持不变,平行线经仿射变换后依然为平行线,且直线上点的位置顺序不会发生变化)。非共线的三对对应点确定一个唯一的仿射变换。

    1.2 二维图像仿射变换

    图像处理中,可应用仿射变换对二维图像进行平移、缩放、旋转等操作。实例如下:
    在这里插入图片描述
    经仿射变换后,图像关键点依然构成三角形,但三角形形状已经发生变化。

    1.3 原子变换

    仿射变换通过一系列原子变换复合实现,具体包括:平移(Translation)、缩放(Scale)、旋转(Rotation)、翻转(Flip)和错切(Shear)。
    a. 平移
    在这里插入图片描述
    在这里插入图片描述
    b. 缩放
    在这里插入图片描述
    在这里插入图片描述
    c. 旋转
    在这里插入图片描述
    在这里插入图片描述
    d. 翻转
    在这里插入图片描述
    在这里插入图片描述
    e. 错切
    错切亦称为剪切或错位变换,包含水平错切和垂直错切,常用于产生弹性物体的变形处理。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    1.4 程序

    clc;
    clear all;close all;
    clc;
    
    image = imread('jyy.png');
    
    % u = 4 * x and v = 2 * y
    T = [4 0 0; 0 2 0; 0 0 1];
    
    % create spatial transformation structure.
    transformation = maketform('affine', T);
    
    % apply 2D spatial transformation to image.
    transformationResult = imtransform(image, transformation);
    

    结果示例:
    在这里插入图片描述
    在这里插入图片描述

    2. Python-opencv实现图像的几何变换

    2.1 写在前面

    二维与三维图像的几何变换在计算机图形学上有重要的应用,包括现在的许多图像界面的切换、二维与三维游戏画面控制等等都涉及到图像几何变换,就比如说在三维游戏中,控制角色三维移动的时候,画面是要跟着移动的,那么怎么移动,怎么让上一时刻的画面移动到这一时刻,这都是根据了你的移动量,然后找到三维坐标之间的对应关系,用这一时刻的坐标替换到上一时刻的坐标像素值实现图像的切换。
    图像的几何变换主要包括:平移、扩大与缩小、旋转、仿射、透视等等。图像变换是建立在矩阵运算基础上的,通过矩阵运算可以很快的找到对应关系。理解变换的原理需要理解变换的构造方法以及矩阵的运算方法,曾经写过matlab下的简单图像变换原理,里面有最基础的构造原理可以看看: matlab之原始处理图像几何变换

    2.2 图像的平移

    下面介绍的图像操作假设你已经知道了为什么需要用矩阵构造才能实现了(上面那个博客有介绍为什么)。那么关于偏移很简单,图像的平移,沿着x方向tx距离,y方向ty距离,那么需要构造移动矩阵:

    通过numpy来产生这个矩阵,并将其赋值给仿射函数cv2.warpAffine().
    仿射函数cv2.warpAffine()接受三个参数,需要变换的原始图像,移动矩阵M 以及变换的图像大小(这个大小如果不和原始图像大小相同,那么函数会自 动通过插值来调整像素间的关系)。
    一个例子如下:

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    img = cv2.imread('flower.jpg')
    H = np.float32([[1,0,100],[0,1,50]])
    rows,cols = img.shape[:2]
    res = cv2.warpAffine(img,H,(rows,cols)) #需要图像、变换矩阵、变换后的大小
    plt.subplot(121)
    plt.imshow(img)
    plt.subplot(122)
    plt.imshow(res)
    

    在这里插入图片描述

    2.3 图像的扩大与缩小

    图像的扩大与缩小有专门的一个函数,cv2.resize(),那么关于伸缩需要确定的就是缩放比例,可以是x与y方向相同倍数,也可以单独设置x与y的缩放比例。另外一个就是在缩放以后图像必然就会变化,这就又涉及到一个插值问题。那么这个函数中,缩放有几种不同的插值(interpolation)方法,在缩小时推荐cv2.INTER_ARER,扩大是推荐cv2.INTER_CUBIC和cv2.INTER_LINEAR。默认都是cv2.INTER_LINEAR,比如:

    import cv2
    import matplotlib.pyplot as plt
    
    img = cv2.imread('flower.jpg')
    # 插值:interpolation
    # None本应该是放图像大小的位置的,后面设置了缩放比例,
    #所有就不要了
    res1 = cv2.resize(img,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC)
    #直接规定缩放大小,这个时候就不需要缩放因子
    height,width = img.shape[:2]
    res2 = cv2.resize(img,(2*width,2*height),interpolation=cv2.INTER_CUBIC)
    plt.subplot(131)
    plt.imshow(img)
    plt.subplot(132)
    plt.imshow(res1)
    plt.subplot(133)
    plt.imshow(res2)
    

    在这里插入图片描述
    通过坐标轴可以看到图像扩大了一倍,并且两种方法相同。

    2.4 图像的旋转

    图像的旋转矩阵一般为:
    在这里插入图片描述
    但是单纯的这个矩阵是在原点处进行变换的,为了能够在任意位置进行旋转变换,opencv采用了另一种方式:

    为了构造这个矩阵,opencv提供了一个函数:
    cv2.getRotationMatrix2D(),这个函数需要三个参数,旋转中心,旋转角度,旋转后图像的缩放比例,比如下例:

    import cv2
    import matplotlib.pyplot as plt
    
    img = cv2.imread('flower.jpg')
    rows,cols = img.shape[:2]
    #第一个参数旋转中心,第二个参数旋转角度,第三个参数:缩放比例
    M = cv2.getRotationMatrix2D((cols/2,rows/2),45,1)
    #第三个参数:变换后的图像大小
    res = cv2.warpAffine(img,M,(rows,cols))
    
    plt.subplot(121)
    plt.imshow(img)
    plt.subplot(122)
    plt.imshow(res)
    

    在这里插入图片描述

    2.5 图像的仿射

    图像的旋转加上拉升就是图像仿射变换,仿射变化也是需要一个M矩阵就可以,但是由于仿射变换比较复杂,一般直接找很难找到这个矩阵,opencv提供了根据变换前后三个点的对应关系来自动求解M。这个函数是
    M=cv2.getAffineTransform(pos1,pos2),其中两个位置就是变换前后的对应位置关系。输 出的就是仿射矩阵M。然后在使用函数cv2.warpAffine()。形象化的图如下(引用参考的)
    在这里插入图片描述
    一个例子比如:

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    img = cv2.imread('flower.jpg')
    rows,cols = img.shape[:2]
    pts1 = np.float32([[50,50],[200,50],[50,200]])
    pts2 = np.float32([[10,100],[200,50],[100,250]])
    M = cv2.getAffineTransform(pts1,pts2)
    #第三个参数:变换后的图像大小
    res = cv2.warpAffine(img,M,(rows,cols))
    plt.subplot(121)
    plt.imshow(img)
    plt.subplot(122)
    plt.imshow(res)
    

    在这里插入图片描述

    2.6 图像的透射

    透视需要的是一个3*3的矩阵,同理opencv在构造这个矩阵的时候还是采用一种点对应的关系来通过函数自己寻找的,因为我们自己很难计算出来。这个函数是M = cv2.getPerspectiveTransform(pts1,pts2),其中pts需要变换前后的4个点对应位置。得到M后在通过函数cv2.warpPerspective(img,M,(200,200))进行。形象化的图如下(引用参考的)
    在这里插入图片描述
    一个例子如下:

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    img = cv2.imread('flower.jpg')
    rows,cols = img.shape[:2]
    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)
    res = cv2.warpPerspective(img,M,(200,200))
    plt.subplot(121)
    plt.imshow(img)
    plt.subplot(122)
    plt.imshow(res)
    

    在这里插入图片描述

    原文链接:
    图像几何变换之仿射变换
    Python下opencv使用笔记(三)(图像的几何变换)

    展开全文
  • python 仿射变换

    千次阅读 2019-05-29 15:15:57
    记录学习Python Computer Vision的过程 第三次 Homography(单应性变换) 图像变换的方法很多,单应性变换是其中一种方法,单应性变换会涉及到单应性矩阵。单应性变换的目标是通过给定的几个点(通常是4对点)来得到...

    PCV-chapter03

    记录学习Python Computer Vision的过程

    第三次

    Homography(单应性变换)

    图像变换的方法很多,单应性变换是其中一种方法,单应性变换会涉及到单应性矩阵。单应性变换的目标是通过给定的几个点(通常是4对点)来得到单应性矩阵。单应性变换是将一个平面内的点映射到另一个平面内的二维投影变换。平面指的是图像或者三维中平面表面,单应性变换的具有很强的实用性,比如图像标配,图像纠正和纹理扭曲,以及创建全景图像。

    基础变换

    • 刚体变换(rigid transformation): 旋转和平移变换/rotation,translation, 3个自由度,点与点之间的距离不变
    • 相似变换(similarity transformation): 增加了缩放尺度, 四个自由度,点与点之间的距离比不变。
    • 仿射变换(affine transformation): 仿射变换和相似变换近似,不同之处在于相似变换具有单一旋转因子和单一缩放因子,仿射变换具有两个旋转因子和两个缩放因子,因此具有6个自由度. 不具有保角性和保持距离比的性质,但是原图平行线变换后仍然是平行线.
    • 投影变换(projective transformation): 也叫作单应性变换。投影变换是齐次坐标下非奇异的线性变换。然而在非齐次坐标系下却是非线性的,这说明齐次坐标的发明是很有价值的。投影变换比仿射变换多2个自由度,具有8个自由度。上面提到的仿射变换具有的“不变”性质,在投影变换中已不复存在了。尽管如此,它还是有一项不变性,那就是在原图中保持共线的3个点,变换后仍旧共线。
    • 透视变换: 将3D空间点投影成2D点的变换

    Affine Transformation(仿射变换)

    仿射变换就是说一种二维坐标到二维坐标之间的线性变换,然后在变换后还能保持图形的平直性和平行性,通俗的说就是变换后的图形中,直线还是直线,圆弧还是圆弧,而且图形间的相对位置,平行线还有直线的交角都不会改变,一条直线上的几段线段之间的比例关系保持不变。但是这里要提一下,仿射变换不会保持原来的线段长度,和夹角角度不变。

    仿射变换可以通过一系列的原子变换的复合来实现,包括:平移(Translation)、缩放(Scale)、翻转(Flip)、旋转(Rotation)和剪切(Shear)。

    仿射变换可以用下面公式表示:

    image

    在上面这个公式中你可以实现平移、缩放、翻转、旋转等变换后的坐标

    所以说仿射变换可以理解为经过对坐标轴的放缩,旋转,平移后原坐标在在新坐标域中的值
    更简洁的说:仿射变换=线性变换+平移

    我们有许多种方法来求这个仿射变换矩阵。下面我们使用对应点来计算仿射变换矩阵,下面是具体函数

    def Haffine_from_points(fp,tp):
        """ Find H, affine transformation, such that 
            tp is affine transf of fp. """
        
        if fp.shape != tp.shape:
            raise RuntimeError('number of points do not match')
            
        # condition points
        # --from points--
        m = mean(fp[:2], axis=1)
        maxstd = max(std(fp[:2], axis=1)) + 1e-9
        C1 = diag([1/maxstd, 1/maxstd, 1]) 
        C1[0][2] = -m[0]/maxstd
        C1[1][2] = -m[1]/maxstd
        fp_cond = dot(C1,fp)
        
        # --to points--
        m = mean(tp[:2], axis=1)
        C2 = C1.copy() #must use same scaling for both point sets
        C2[0][2] = -m[0]/maxstd
        C2[1][2] = -m[1]/maxstd
        tp_cond = dot(C2,tp)
        
        # conditioned points have mean zero, so translation is zero
        A = concatenate((fp_cond[:2],tp_cond[:2]), axis=0)
        U,S,V = linalg.svd(A.T)
        
        # create B and C matrices as Hartley-Zisserman (2:nd ed) p 130.
        tmp = V[:2].T
        B = tmp[:2]
        C = tmp[2:4]
        
        tmp2 = concatenate((dot(C,linalg.pinv(B)),zeros((2,1))), axis=1) 
        H = vstack((tmp2,[0,0,1]))
        
        # decondition
        H = dot(linalg.inv(C2),dot(H,C1))
        
        return H / H[2,2]
    

    该函数有有以下参数:

    • fp:图像固定点坐标
    • tp :图像变换目标坐标

    我们能够使用函数Haffine_from_points()来求出仿射变换,函数Haffine_from_points()会返回给定对应点对的最优仿射变换。

    图像扭曲

    对图像块应用仿射变换,我们将其称为图像扭曲。该操作不仅经常应用在计算机图形学,而且经常出现在计算机视觉算法中。扭曲操作可以使用SciPy工具包中的nadimage包来完成。使用这个包进行线性变换A和一个平移量b来对图像块应用仿射变换。演示代码如下:

    from scipy import ndimage
    from PIL import Image
    from pylab import *
    
    im = array(Image.open(r'C:\Users\ZQQ\Desktop\advanced\study\computervision\images\ch02\j03.jpg').convert('L'))
    H = array([[1.4,0.05,-100],[0.05,1.5,-100],[0,0,1]])
    im2 = ndimage.affine_transform(im,H[:2,:2],(H[0,2],H[1,2]))
    
    figure()
    gray()
    subplot(121)
    axis('off')
    imshow(im)
    subplot(122)
    axis('off')
    imshow(im2)
    show()
    

    原图:
    在这里插入图片描述

    结果:
    在这里插入图片描述

    Alpha通道

    在仿射扭曲的例子中有一个简单的应用是将图像或者图像的一部分放置在另一幅图像中,使得它们能够和指定的区域或者标记物对齐。将扭曲的图像和第二幅图像融合,我们就创建了alpha图像。该图像定义了每个像素从各个图像中获取的像素值成分多少。我们基于以下事实,扭曲的图像是在扭曲区域边界之外以0来填充的图像,来创建一个二值的alpha图像。

    在计算机图形学中,一个RGB颜色模型的真彩图形,用由红、绿、蓝三个色彩信息通道合成的,每个通道用了8位色彩深度,共计24位,包含了所有彩色信息。为实现图形的透明效果,采取在图形文件的处理与存储中附加上另一个8位信息的方法,这个附加的代表图形中各个素点透明度的通道信息就被叫做Alpha通道。

    Alpha通道使用8位二进制数,就可以表示256级灰度,即256级的透明度。白色(值为255)的Alpha像素用以定义不透明的彩色像素,而黑色(值为0)的Alpha通道像素用以定义透明像素,介于黑白之间的灰度(值为30-255)的Alpha像素用以定义不同程度的半透明像素。因而通过一个32位总线的图形卡来显示带Alpha通道的图形,就可能呈现出透明或半透明的视觉效果。

    事实上,我们把需要组合的颜色计算出不含Alpha分量的原始RGB分量然后相加便可。如:两幅图像分别为A和B,由这两幅图像组合而成的图像称为C,则可用如下四元组表示图A和B,三元组表示图像C:

    • A:(Ra,Ga,Ba,Alphaa)
    • B:(Rb,Gb,Bb,Alphab)
    • C:(Rc,Gc,Bc)

    根据上述算法,则:

    • Rc=RaAlphaa+RbAlphab
    • Gc=GaAlphaa+GbAlphab
    • Bc=BaAlphaa+BbAlphab

    这就是两图像混合后的三原色分量。如果有多幅图像需要混合,则按照以上方法两幅两幅地进行混合。

    图像中的图像

    使用仿射变换将一幅图像放置到另一幅图像中

    代码如下:

     # -*- coding: utf-8 -*-
    from PCV.geometry import warp, homography
    from PIL import  Image
    from pylab import *
    from scipy import ndimage
    
    # example of affine warp of im1 onto im2
    
    im1 = array(Image.open(r'C:\Users\ZQQ\Desktop\advanced\study\computervision\images\ch03\03.jpg').convert('L'))
    im2 = array(Image.open(r'C:\Users\ZQQ\Desktop\advanced\study\computervision\images\ch03\01.jpg').convert('L'))
    # set to points
    tp = array([[280,574,574,280],[340,340,735,735],[1,1,1,1]])
    #tp = array([[675,826,826,677],[55,52,281,277],[1,1,1,1]])
    im3 = warp.image_in_image(im1,im2,tp)
    figure()
    gray()
    subplot(141)
    axis('off')
    imshow(im1)
    subplot(142)
    axis('off')
    imshow(im2)
    subplot(143)
    axis('off')
    imshow(im3)
    
    # set from points to corners of im1
    m,n = im1.shape[:2]
    fp = array([[0,m,m,0],[0,0,n,n],[1,1,1,1]])
    # first triangle
    tp2 = tp[:,:3]
    fp2 = fp[:,:3]
    # compute H
    H = homography.Haffine_from_points(tp2,fp2)
    im1_t = ndimage.affine_transform(im1,H[:2,:2],
    (H[0,2],H[1,2]),im2.shape[:2])
    # alpha for triangle
    alpha = warp.alpha_for_triangle(tp2,im2.shape[0],im2.shape[1])
    im3 = (1-alpha)*im2 + alpha*im1_t
    # second triangle
    tp2 = tp[:,[0,2,3]]
    fp2 = fp[:,[0,2,3]]
    # compute H
    H = homography.Haffine_from_points(tp2,fp2)
    im1_t = ndimage.affine_transform(im1,H[:2,:2],
    (H[0,2],H[1,2]),im2.shape[:2])
    # alpha for triangle
    alpha = warp.alpha_for_triangle(tp2,im2.shape[0],im2.shape[1])
    im4 = (1-alpha)*im3 + alpha*im1_t
    subplot(144)
    imshow(im4)
    axis('off')
    show()
    

    在其中定义的tp变量是图像变换目标坐标,它按照从左上角逆时针的顺序,定义第一幅图像的四个角的点在第二幅中的位置。

    原图:
    在这里插入图片描述
    在这里插入图片描述

    实验结果如下:
    在这里插入图片描述

    在上面的例子中,对应点对为图像和教室幕布的角点。仿射变换可以将一幅图像进行扭曲,是这对应点对可以完美匹配上。这是因为,仿射变换具有六个自由度。

    小结

    本次实验主要学习了仿射变换,和应用仿射变换

    展开全文
  • 对像素点直接操作来实现仿射变换 第一部分:图片倒置 1.图片倒置就是将图片的像素点就行倒置,左上角的像素点 与对应右下角的像素点就行交换,经过这样的操作后,就实现了图片的倒置,下面给出操作的代码。 import...
  • 一般对图像的变化操作有放大、缩小、旋转等,统称为几何变换,对一个图像的图像变换主要有两大步骤,一是实现空间坐标... ##仿射变换## 二维空间坐标的仿射变换公式:$$ \left( \begin{matrix} \overline{x} \ \ove...
  • OpenCV-Python仿射变换开发中遇到的坑

    千次阅读 2021-02-19 16:11:00
    本文介绍了老猿在使用OpenCV-Python进行仿射变换开发中遇到的坑,这些问题可能大家或多或少会碰到,这些问题涉及基本知识的理解、官方资料的坑等方面,希望能帮助到大家。
  • 图像仿射变换python实现

    千次阅读 2020-03-18 21:54:21
    写文章不易,如果您觉得此... 仿射变换介绍: 请参考:图解图像仿射变换:https://www.cnblogs.com/wojianxin/p/12518393.html 图像仿射变换之图像平移:https://www.cnblogs.com/wojianxin/p/12519498.html 二...
  • Python / PIL仿射变换

    2021-02-28 12:35:37
    首先,PIL使用反仿射变换是绝对正确的,如carlosdc's answer中所述 . 但是,没有必要使用线性代数来计算原始变换的逆变换 - 相反,它可以很容易地直接表达 . 我将使用缩放和围绕其中心旋转图像作为示例,如Ruediger ...
  • OpenCV-图片仿射变换 把原图片映射到目标图片三个新的位置 src->dst 3 (左上角,左下角,右上角) ''' import cv2 import numpy as np img = cv2.imread('D:\image1.jpg',1) cv2.imshow('src',img) #原图片的高...
  • 1.4 Python图像的坐标变换-仿射变换 文章目录1.4 Python图像的坐标变换-仿射变换1 算法原理2 代码3 效果 1 算法原理 图像的几何变换,也就是矩阵乘法。 通过仿射变换图片中的每个像素点按照一定的规律映射到新的...
  • 本节介绍了仿射变换的概念、类型、基本仿射变换矩阵、OpenCV-Python仿射变换相关的主要函数及语法说明,并提供了两种不同方式实现的图像旋转和任选三个点将圈定子图放大的示例。通过阅读相关内容可以有助于大家...
  • 对图像块应用仿射变换,我们将其称为图像扭曲(或者仿射扭曲)。该操作不仅经常应用在计算机图形学中,而且经常出现在计算机视觉算法中。 一、仿射变换原理 仿射变换能够保持图像的“平直性”,包括旋转,缩放,平移...
  • python+opencv三点仿射变换

    千次阅读 2019-02-26 15:56:27
    一张图来表明要实现的功能: 说明:将一张正正方方的矩形图转换成平行四边形(甚至不规则四边形)的操作。...三个点的坐标就是6个数字,我们把6个数字设置成自己想要的位置,就可以实现三点仿射变换。我...
  • 本文是老猿关于仿射变换的原理、概念以及OpenCV-Python实现额的导览式文章,通过本文作为入口,读者可以非常快速的理解仿射变换的相关知识以及开发应用。
  • 仿射变换opencv提供了函数cv2.getAffineTransform()来创建一个2*3的矩阵,该矩阵传递给cv2.warpAffine()。该函数语法格式为:retval = cv.getAffineTransform(src, dst)'''src:输入图像的三个点坐标dst:输出图像的...
  • 什么是仿射变换仿射变换就是图像的线性变换加上平移 用一幅图表示,就是  由 image1 到 image2 的转换经过了三个操作 旋转 (线性变换)缩放操作(线性变换)平移 (向量加) 如果没有了第3个平移的操作,那它就是...
  • import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('pic3.PNG') cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows() rows, cols = img.shape[:2] ...
  • 一、图像仿射变换 1.原理 仿射变换(Affine Transformation 或Affine Map)是一种二维坐标(x, y)到二维坐标(u, v)的线性变换,转换过程坐标点的相对位置和属性不发生变换,是一个线性变换,该过程只发生旋转和...
  • 利用Python语言,定义一个类,完成对长方形进行仿射变换。类属性包括有长方形的高度Height、宽度Width,左上角坐标Left,Top。类操作包括有:x方向平移,y方向平移,xy同时平移,x方向拉伸,y方向拉伸,xy方向同比例...
  • 图片拉伸成类似平行四边形这样 直接上效果图 先不着急上代码, 如果你遇到opencv报以下错误的话, cv2.error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-z4706ql7\opencv\modules...
  • 在前面实现了平移和缩放,还有一种常用的坐标变换,那就是旋转。...由于旋转变换,都是绕着点进行运动的,首先要找到轴的位置,默认是原点(0,0),如果要指定点进行,那么要采用前面的平移操作,即是把图片移到这...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,639
精华内容 2,255
关键字:

python图片仿射变换

python 订阅