精华内容
下载资源
问答
  • 2020-07-13 16:59:28

    图片旋转 1. cv2.getRotationMatrix2D(获得仿射变化矩阵) 2. cv2.warpAffine(进行仿射变化)
    1.rot_mat = cv2.getRotationMatrix2D(center, -5, 1)

    参数说明:center表示中间点的位置,-5表示逆时针旋转5度,1表示进行等比列的缩放

    1. cv2.warpAffine(img, rot_mat, (img.shape[1], img.shape[0]))

    参数说明: img表示输入的图片,rot_mat表示仿射变化矩阵,(image.shape[1], image.shape[0])表示变换后的图片大小

    代码说明:

    第一步:读入图片,进行图片展示

    第二步:获取图片的宽,长,通道数,构造[0, 0, w, h], 即构造[x1, y1, x2, y2] 矩阵,实列化一个矩阵

    第三步:计算其center值,将其代入到cv2.getRotationMatrix2D生成变化矩阵

    第四步:使用cv2.warpAffine(img, rot_mat, (img.shape[1], img.shape[0])) 获得仿射变化以后的图像

    第五步:如果是图片上的一个点,那么经过变化以后的坐标值为

    (rot_mat[0][0] * x + rot_mat[0][1] * y + rot_mat[0][2], rot_mat[1][0] * x + rot_mat[1][1] * y + rot_mat[1][2]

    第六步:进行旋转图片的图片展示,为了保证,这里也可以进行截图操作

    import cv2
    import numpy as np
    
    class BBox(object):
    
        def __init__(self, bbox):
            self.left = bbox[0]
            self.top = bbox[1]
            self.right = bbox[2]
            self.bottom = bbox[3]
    
    img = cv2.imread('0001.jpg')
    cv2.imshow('img', img)
    cv2.waitKey(0)
    h, w, c = img.shape
    box = [0, 0, w, h]
    bbox = BBox(box)
    
    
    
    center = ((bbox.left + bbox.right) / 2, (bbox.top + bbox.bottom) / 2)
    rot_mat = cv2.getRotationMatrix2D(center, -5, 1)
    img_rotated_by_alpha = cv2.warpAffine(img, rot_mat, (img.shape[1], img.shape[0]))
    # 获得图片旋转以后的关键点的位置
    # lanmark_ = np.asarray([(rot_mat[0][0] * x + rot_mat[0][1] * y + rot_mat[0][2],
    #                         rot_mat[1][0] * x + rot_mat[1][1] + rot_mat[1][2]) for (x, y) in landmark])
    
    cv2.imshow('img_rotated', img_rotated_by_alpha)
    cv2.waitKey(0)
    
    # face = img_rotated_by_alpha[bbox.top:bbox.bottom + 1, bbox.left:bbox.right + 1]
    #
    # cv2.imshow('face', face)
    # cv2.waitKey(0)
    
    

    原始图像
    在这里插入图片描述
    旋转以后的图像
    在这里插入图片描述

    更多相关内容
  • 1-halcon仿射变化主要使用两个函数 1、affine_trans_image:图像仿射变化 2、affine_trans_region:区域仿射变化 2-仿射变换矩阵 在halcon中求取仿射变换矩阵的方法包含两种: 一、对单位矩阵进行旋转、偏移和缩放 ...

    1-halcon仿射变化主要使用两个函数

    1、affine_trans_image:图像仿射变化
    2、affine_trans_region:区域仿射变化

    2-仿射变换矩阵

    在halcon中求取仿射变换矩阵的方法包含两种:
    一、对单位矩阵进行旋转、偏移和缩放

    hom_mat2d_identity (HomMat2DIdentity)    生成单位矩阵
    hom_mat2d_rotate (HomMat2DIdentity, -0.3, 256, 256, HomMat2DRotate)  对单位矩阵旋转
    hom_mat2d_scale (HomMat2DRotate, 1.5, 1.5, 256, 256, HomMat2DScale)  对单位矩阵缩放
    affine_trans_region (Region, RegionAffineTrans, HomMat2DScale, 'nearest_neighbor')
    

    旋转、缩放和平移顺序无关、也可以多次使用
    二、已知角度和旋转中心(不能进行缩放)

      orientation_region (zqb, Phi)
         area_center (RegionFillUp1, Area, Row, Column) 
         vector_angle_to_rigid (Row, Column, Phi, Row, Column, 0, HomMat2D)
    

    通过vector_angle_to_rigid生成

    3-旋转角度正负定义

    在这里插入图片描述

    逆时针为﹢,顺时针为-。

    3-几何定位与放射示例

    * Image Acquisition 02: Code generated by Image Acquisition 02
    open_framegrabber ('DirectShow', 1, 1, 0, 0, 0, 0, 'default', 8, 'rgb', -1, 'false', 'default', '[0] FHD Camera', 0, -1, AcqHandle)
    grab_image_start (AcqHandle, -1)
    while (true)
        grab_image_async (Image, AcqHandle, -1)
        rgb1_to_gray (Image, GrayImage)
        
        threshold (GrayImage, Regions, 177, 255)
        opening_rectangle1 (Regions, RegionOpening, 10, 10)
        fill_up (RegionOpening, RegionFillUp1)
        shape_trans (RegionFillUp1, RegionTrans,'ellipse')
        shape_trans (RegionTrans,zqb,'rectangle2')
        orientation_region (zqb, Phi)
         area_center (RegionFillUp1, Area, Row, Column) 
         vector_angle_to_rigid (Row, Column, Phi, Row, Column, 0, HomMat2D)
         affine_trans_image (GrayImage, ImageAffineTrans, HomMat2D, 'constant', 'false')
         affine_trans_region (zqb, RegionAffineTrans, HomMat2D, 'nearest_neighbor')
         reduce_domain (ImageAffineTrans, RegionAffineTrans, ImageReduced)
         
    *     orientation_region (RegionTrans, Phi)
    *     area_center (RegionTrans, Area, Row, Column)
    *     vector_angle_to_rigid (Row, Column, Phi, Row, Column, 0, HomMat2D)
    *     affine_trans_region (RegionTrans, RegionAffineTrans, HomMat2D, 'nearest_neighbor')
    *    affine_trans_image (GrayImage, ImageAffineTrans, HomMat2D, 'constant', 'false')
       
    *     threshold (ImageAffineTrans, Regions1, 196, 254)
    *     opening_rectangle1 (Regions1, RegionOpening1, 10, 10)
    *     fill_up (RegionOpening1, RegionFillUp2)
    *     shape_trans (RegionFillUp2, RegionTrans2,'rectangle1')
    *     reduce_domain (ImageAffineTrans, RegionTrans2, ImageReduced)
        
    *     fill_up (Regions, RegionFillUp)
    *     orientation_region (RegionFillUp, Phi)
    *     area_center (RegionFillUp, Area, Row, Column)
    *     vector_angle_to_rigid (Row, Column, Phi, Row, Column, 0, HomMat2D)
        
        * affine_trans_region (RegionFillUp, RegionAffineTrans, HomMat2D, 'nearest_neighbor')
    *       affine_trans_image (GrayImage, ImageAffineTrans, HomMat2D, 'constant', 'false')
        
    endwhile
    close_framegrabber (AcqHandle)
    
    

    4-结果

    1、初始照片
    在这里插入图片描述
    2、二值化
    在这里插入图片描述
    3、图形变化(求角度)
    在这里插入图片描述
    4、结果
    在这里插入图片描述

    5-总结

    在halcon中,图像、区域和xld变量是有本质区别的,图像带有像素,可以进行图像和区域等所有操作;区域仅仅是图像上符合相关条件的坐标点集合,可以进行几何操作,但是不能进行图像操作。如何需要提取图像上的相关信息,最终还是要进行图像操作,区域操作可以获取相关的几何信息,比如旋转角度、目标图像的位置等。

    展开全文
  • 仿射变化的原理,使用及相关拓展的总结 仿射变换仿射变化的原理,使用及相关拓展的总结前言简单的例子原理提升拓展flags:插值方法borderMode:像素外推方法(边界像素模式)borderValue:边界不变时使用的值结尾 ...

    仿射变化的原理,使用及相关拓展的总结

    前言

    看了下原理计划上榜的文章,没错,我也会写标题了,不过本文内容无愧于题目。给大家详细讲一讲opencv里的仿射变换,也就是cv2.getAffineTransformcv2.warpAffine这两个函数。
    原本我通常会先写原理,然后再举个简单的例子,之后再举一个复杂点的拓展的例子。为了防止大家一看原理或者数学公式这类东西就跑,我先举个例子,大家理解了就能用,想提升的再往下看就好。

    简单的例子

    这个例子看懂了,遇到图像仿射变换的需求直接套就行。
    我们来变下面这张图:
    一张图片A
    其中三个圆圈的中心点大概是,红[316,76],黄[215,369],蓝[413,371]。
    那么我们把红点往左移,黄和蓝不变。移动后,红[215,76],黄[215,369],蓝[413,371]。
    代码如下

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    """
    Created on Mon Mar  9 13:53:38 2020
    
    @author: phoenix
    """
    
    import cv2
    import numpy as np
    
    img=cv2.imread('/Users/phoenix/Documents/A.png')
    rows,cols,ch=img.shape
    
    pts1=np.float32([[316,76],[215,369],[413,371]])
    pts2=np.float32([[215,76],[215,369],[413,371]])
    M=cv2.getAffineTransform(pts1,pts2)
    
    dst=cv2.warpAffine(img,M,(cols,rows))
    
    cv2.imshow("dst",dst)
    cv2.waitKey(0)
    

    结果如下
    红点左移
    再举个例子,如果保持红点不变,黄左移,蓝右移。
    那么只要把代码中的pts2改一下,改成

    pts2=np.float32([[316,76],[115,369],[513,371]])
    

    结果如图
    黄左移,蓝右移

    原理

    简单理解就是:仿射变化的关键在于仿射变化矩阵M
    M可以通过cv2.getAffineTransform这个函数得到。
    M是一个简单的2*3的矩阵。

    假设一个点A坐标为(x1,y1),经过仿射变换矩阵M,在另一个图像上为A1点坐标为(x2,y2)。刚刚有说过M是一个2*3的矩阵,这里设
    M = [ a b c d e f ] M= \begin{gathered} \begin{bmatrix} a & b &c \\ d & e & f \end{bmatrix} \end{gathered} M=[adbecf]
    那么
    [ x 2 y 2 ] = [ a b d e ] [ x 1 y 1 ] + [ c f ] \begin{gathered} \begin{bmatrix} x2 \\ y2 \end{bmatrix}= \begin{bmatrix} a & b\\ d & e\end{bmatrix} \begin{bmatrix} x1 \\ y1 \end{bmatrix}+ \begin{bmatrix} c \\ f \end{bmatrix} \end{gathered} [x2y2]=[adbe][x1y1]+[cf]
    也就是说
    x2=a * x1 + b * y1 + c
    y2=d * x1 + e * y1 + f

    如果想做更深入的了解的话,可以看这个网址。
    仿射变换
    上面👆这个网址介绍的很详细

    提升拓展

    cv2.getAffineTransform这个函数没什么好说的,是单纯用来求仿射变换矩阵M
    下面说说cv2.getAffineTransform这个函数
    先看下它的help。

    Help on built-in function warpAffine:
    
    warpAffine(...)
        warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) -> dst
        .   @brief Applies an affine transformation to an image.
        .   
        .   The function warpAffine transforms the source image using the specified matrix:
        .   
        .   \f[\texttt{dst} (x,y) =  \texttt{src} ( \texttt{M} _{11} x +  \texttt{M} _{12} y +  \texttt{M} _{13}, \texttt{M} _{21} x +  \texttt{M} _{22} y +  \texttt{M} _{23})\f]
        .   
        .   when the flag #WARP_INVERSE_MAP is set. Otherwise, the transformation is first inverted
        .   with #invertAffineTransform and then put in the formula above instead of M. The function cannot
        .   operate in-place.
        .   
        .   @param src input image.
        .   @param dst output image that has the size dsize and the same type as src .
        .   @param M \f$2\times 3\f$ transformation matrix.
        .   @param dsize size of the output image.
        .   @param flags combination of interpolation methods (see #InterpolationFlags) and the optional
        .   flag #WARP_INVERSE_MAP that means that M is the inverse transformation (
        .   \f$\texttt{dst}\rightarrow\texttt{src}\f$ ).
        .   @param borderMode pixel extrapolation method (see #BorderTypes); when
        .   borderMode=#BORDER_TRANSPARENT, it means that the pixels in the destination image corresponding to
        .   the "outliers" in the source image are not modified by the function.
        .   @param borderValue value used in case of a constant border; by default, it is 0.
        .   
        .   @sa  warpPerspective, resize, remap, getRectSubPix, transform
    

    总结下就是
    1.这个方程是用来做图像仿射变化的,且是通过指定的矩阵来进行转换。
    2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) -> dst
    其中
    src:输入图像。
    dst:输出图像,其大小为dsize,并且与src类型相同。
    M: 转换矩阵。
    dsize:输出图像的大小。
    flags:插值方法(请参阅#InterpolationFlags)和可选方法的组合
    borderMode:像素外推方法(不过看别的博客上写的边界像素模式?)(请参阅#BorderTypes);当borderMode =#BORDER_TRANSPARENT,表示目标图像中的像素对应于源图像中的“异常值”不会被该功能修改。(这里我觉得我的翻译没有问题,但我实在不知道他想表达什么
    borderValue:边界不变时使用的值;默认情况下为0。也就是黑色。

    src,dst,M,dsize:输入图像,输出图像,转换矩阵,输出图像的大小。这四个比较基础,没什么好说的。
    后面的**flags,borderMode,borderValue,这个三个变量很容易被大家忽略,其实还是非常非常有用**的。可以区别你对这个函数的理解深度。

    flags:插值方法

    flages表示插值方式,默认为flags=cv2.INTER_LINEAR(双线性插值)。
    做个汇总给大家

    INTER_NEAREST-最近邻插值
    INTER_LINEAR-双线性插值(默认使用)
    INTER_AREA-使用像素面积关系进行重采样。 这可能是首选的图像抽取方法,因为它可以提供无波纹的结果。 但是当图像放大时,它类似于INTER_NEAREST方法。
    INTER_CUBIC-在4x4像素邻域上的双三次插值
    INTER_LANCZOS4-在8x8像素邻域上的Lanczos插值

    这么多插值方法怎么选择,我给大家推荐这篇博客OpenCV图像插值方法的比较

    如果你看不太懂那篇博客。那么我给个不负责任的个人建议
    不在意图片质量:使用默认的就OK。
    在意图片质量不在意代码的运行时间:使用最后一个。
    既在意质量又在意时间:看到前面写的原理了吗,你可以利用矩阵反推回去,因为原图的质量是最高的

    borderMode:像素外推方法(边界像素模式)

    这个推荐大家看这个网站
    BorderTypes
    这是google翻译后的网页截图。
    bordertypes
    简单些解释呢,borderType是指要添加在图像周围的某种类型的边界,就像在图像周围创造一个边框(给你的图像加个相框的感觉)。
    borderMode和borderValue加在一起,默认就是黑的。如果不理解往下看。

    borderValue:边界不变时使用的值

    这里的边界不变指的是borderMode=cv2.BORDER_CONSTANT。
    举个例子这里有一张图片
    abcdefgh
    当我用

    dst=cv2.warpAffine(img,M,(cols,rows))
    

    ,borderMode和borderValue不选择,即为默认时。
    仿射变化的结果是
    abcdefgh仿射变化结果
    记住这张图
    接着我用

    dst=cv2.warpAffine(img,M,(cols,rows),borderMode=cv2.BORDER_CONSTANT ,borderValue=(0,255,255))
    

    或者

    dst=cv2.warpAffine(img,M,(cols,rows) ,borderValue=(0,255,255))
    

    结果是
    被黄色填满
    没错原本黑色的地方被黄色(0,255,255)填满了。
    而我如果更改borderMode,我使用

    dst=cv2.warpAffine(img,M,(cols,rows),borderMode=cv2.BORDER_REFLECT,borderValue=(0,255,255))
    

    结果是如图,右边填充的是h的镜像。
    BORDER_REFLECT
    cv2.BORDER_REFLECT的效果就是fedcba|abcdefgh|hgfedcb
    此时borderValue的值也就没什么用了。

    结尾

    这篇文章花了我好长时间啊,翻了很多资料和博客,力求做到详细正确。如果你看到了这里,麻烦给我点了赞且留言支持一下。如果你还有关于仿射变换的问题没有解决,麻烦发在评论里,我会回复帮你解决的。谢谢各位!

    展开全文
  • 在Convex Optimization的第三章中提到了共轭函数的仿射变化。但是没有具体说明过程,这里推导一下。 参考资料: Convex Optimization: Chapter-3 函数的共轭函数定义为 现给出其仿射变化函数,其共轭函数为,...

    Convex Optimization的第三章中提到了共轭函数的仿射变化。但是没有具体说明过程,这里推导一下。

    参考资料:

    Convex Optimization: Chapter-3


    函数f(x)的共轭函数定义为

    f^*(y)=\sup\limits_{x\in\mathbf{dom}f}(x^Ty-f(x))

    现给出其仿射变化函数g(x)=af(x)+b,其共轭函数为g^*(y)=af^*(y/a)-b,证明如下:

    z=\nabla f(x)时,仿射函数x^Tz与函数f(x)的距离最大,即梯度相同时,距离最远。

    因此对于函数f(x)来说,其共轭函数为

    f^*(z)=x^T\nabla f(x)-f(x)

    其中z=\nabla f(x)

    对于函数g(x)来说,其共轭函数为

    \begin{array} {ll} g^*(y)&=ax^T\nabla f(x)-af(x)-b\\ &=a(x^T\nabla f(x)-f(x))-b\\ &=af^*(z)-b \end{array}

    其中y=a\nabla f(x)=az

    变量替换就可得到g^*(y)=af^*(y/a)-b


    函数g(x)=f(Ax+b),其共轭函数为g^*(y)=f^*(A^{-T}y)-bA^{-T}y,其中,A\in \mathbf{R}^{n\times n},\ b\in \mathbf{R}^{n\times 1}。证明如下:

    这里用到了矩阵求导,参考资料:矩阵求导矩阵求导、几种重要的矩阵及常用的矩阵求导公式

    首先对函数f(x)与上面的证明一致,不再赘述。

    对于函数g(x)=f(Ax+b),当y=A^T\nabla f(Ax+b)时,仿射函数x^Ty与函数f(Ax+b)的距离最大。

    因此其共轭函数为

    g^*(y)&=x^TA^T\nabla f(Ax+b)-f(Ax+b)

    w=Ax+b,则x=A^{-1}(w-b)y=A^T\nabla f(x)。而共轭函数为

    \begin{array}{ll} g^*(y)&=x^TA^T\nabla f(Ax+b)-f(Ax+b)\\ &= (w-b)^TA^{-T}A^T\nabla f(w)-f(w)\\ &=w^T\nabla f(w)-f(w)-b^T\nabla f(w)\\ &=f^*(z)-b^T\nabla f(w) \end{array}

    其中,y=A^T\nabla f(w)=A^Tz,则z=A^{-T}y,而\nabla f(w)=A^{-T}y。将z,\ \nabla f(w)进行替换就可以得到g^*(y)=f^*(A^{-T}y)-bA^{-T}y了。


    这里给个提示:

    • A'A=E
    • A^{T}x=y,\ x=A^{-T}y
    • (A^{T})^{T}=A,注意与矩阵的逆区别。
    • 所有的推导按照矩阵求导的分母布局进行的。

     

     

     

    展开全文
  • 任何仿射变换都可以转换成,乘以一个矩阵(线性变化),再加上一个向量(平移变化)。 实际上仿射是两幅图片的变换关系。 例如我们可以通过仿射变换对图片进行:缩放、旋转、平移等操作。 一个数学问题 在解决仿射...
  • 本文指出提高ASIFT 算法效率的一种新途径:利用“遮罩”屏蔽源自视角模拟的无效像素区域,从而使较为耗时 的区域运算仅作用于有效像素区域,以达到提高运算效率的目的。首先,分析无效像素区域产生根源,并定量...
  • 博客:https://editor.csdn.net/md?not_checkout=1&articleId=121030973 基于形状的模板匹配,仿射变换,模板跟随
  • 关于GDAL 仿射变化参数和图像投影

    千次阅读 2017-03-17 11:57:59
    的六参数(我自己起的名字,是一个仿射变化的参数),第二个是 图像 的投影(也就是空间参考系统)。 下面先说说第一个六参数,六参数其实是 图像 行列号坐标和地理坐标转换的一组转换系数。下面是用GT来表示六...
  • 15、Opencv4.4仿射变化

    2020-06-18 20:36:11
    基本思想:对图像进行仿射处理 #include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace std; ...
  • opencv 仿射变换

    千次阅读 2022-03-14 22:36:56
    文章目录一、仿射变换二、求解仿射变换三、opencv 函数支持1.getAffineTransform()函数2.getRotationMatrix2D()函数3.warpAffine()函数四、测试代码 一、仿射变换 仿射变换可以理解为矩阵乘法(线性变换)和向量加法...
  • 1.rot_mat = cv2.getRotationMatrix2D(center, -5, 1) 参数说明:center表示中间点的位置,-5表示逆时针旋转5度,1表示进行等比列的缩放 ...参数说明: img表示输入的图片,rot_mat表示仿射变化矩阵,(image...
  • 但是为了可视化,你也许想知道某个点通过了这种变化后到了那儿。由原理分析可见,通过解上述方程即可。 3、代码 def reCalculateBBS(self,BBS,M): M = np.transpose(M) for i in range(len(BBS)): k1=BBS[i] # x=((M...
  • matAffine = cv2.getAffineTransform(matSrc,matDst)# mat 1 src 2 dst 仿射变化矩阵 dst = cv2.warpAffine(img,matAffine,(width,height)) #原始 仿射矩阵 长宽 cv2.imshow('dst',dst) cv2.waitKey(0)
  • 我们往往会面临数据集不够的情况,需要进行数据集的扩充,数据集的扩充有多种多样的方式,在这里总结了7种数据扩充的方法对数据进行数据增强,包括:亮度增强,对比度增强,翻转图像,仿射变化扩充图像,错切变化...
  • 若该文为原创文章,未经允许不得转载 原博主博客地址:...本文章博客地址: 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 目录 前言 ...仿射变换 概述...
  • halcon仿射变换

    2022-05-02 22:15:50
    halcon仿射变换
  • Javascript实现二次多项式仿射变化 我之前遇到了这样的问题,用户想要将没有任何坐标信息的图片发布成地图服务,但是又不能对图片进行拉伸等一系列的变换,所以,最终采用的二次多项式做校准,用二次多项式的解做...
  • 由上图新的图形不仅仅是放大缩小,还发生了角度的变化 CALayer 仿射变换最常用的三个方法 1、旋转 函数CATransform3DMakeRotation -(void)rotationAnimation { /** * @ param angle 旋转的度数 *...
  • OpenCV 仿射变换

    千次阅读 2021-04-23 20:25:29
    仿射变换中,原图中所有的平行线在结果图像中同样平行。为了创建这个矩阵需要从原图像中找到三个点以及他们在输出图像中的位置。然后cv2.getAffineTransform 会创建一个 2x3 的矩阵,最后这个矩阵会被传给函数 cv2....
  • 仿射变换

    2019-03-19 21:33:13
    初学图像到图像的映射,在仿射变换前会首先介绍单应性变换。 单应性变换 单应性变换是指将一个平面内的点映射到另一个平面内的二维投影变换。平面是指图像或者是三维空间中的平面表面。单应性变换具有很强的实用性...
  • 仿射变换矩阵

    2022-04-19 10:58:39
    仿射变换Affine3f矩阵 首先总结而言:仿射变换矩阵实际上就是:平移向量+旋转变换组合而成,可以同时实现旋转,缩放,平移等空间变换。 Eigen库中,仿射变换矩阵的大致用法为: 创建Eigen::Affine3f 对象a。 创建...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,538
精华内容 5,015
关键字:

仿射变化