精华内容
下载资源
问答
  • transform-origin 基础语法 transform-origin: x y; 重要知识点 注意后面的参数 x 和 y 用空格隔开 x、 y 默认旋转的中心点是元素的中心 (50P%),等价于 center center 还可以给 x y 设置像素,或者方位名词(top、...
  • 运行后查看效果。非常的不错。 <style type=”text/css”> .pre { font-family:微软雅黑; width:420px;...filter : progid:DXImageTransform.Microsoft.Matrix(SizingMethod=”auto expand”,...-moz-transform-ori
  • 小波方法测量地震行时变化的代码 这个python程序基于Mao和Mordret的工作,您可以在这里找到: : 原始代码在MATLAB中,这是等效的Python ... ori_waveform.npy new_waveform.npy 用于测试代码的两个合成波形ori_wavef
  • 得到关键点 xxx的位置后,以 xxx为中心再取一个小图块 ppp,大小为 64∗6464*6464∗64,将小图块 ppp输入到方向估计模块ORI中预测一个旋转角度,并使用空间变换层(Spatial Transformer layers,STL)对图块进行旋转...

    核心思想

      该文提出一种完整的关键点检测-方向估计-特征描述的方法(LIFT),该流程与经典的SIFT算法非常相似,但使用基于深度学习的方法实现了该过程。流程可以分成三个部分:关键点检测(Detector),方向估计(Orientation Estimator)和特征描述(Descriptor),其实针对这个三个部分现有的基于深度学习的方法已经有很多了,但是该文将三个部分联合起来形成一个完成的pipeline,并且可以进行端到端的训练。下面介绍一下LIFT的处理过程
    在这里插入图片描述
      首先本算法的输入并不是一整幅图像,而是从一幅图片中提取出一个图块 P P P,大小为 128 ∗ 128 128*128 128128,图块的选择方法是利用VisualSFM算法得到的。然后利用关键点检测器DET对图块进行处理,输出得分图 S S S,对 S S S做softargmax操作从中提取出关键点 x x x(可以理解为得分最高的点,softargmax是取代了非极大值抑制的方法,为了保证整个流程的可微性)。得到关键点 x x x的位置后,以 x x x为中心再取一个小图块 p p p,大小为 64 ∗ 64 64*64 6464,将小图块 p p p输入到方向估计模块ORI中预测一个旋转角度,并使用空间变换层(Spatial Transformer layers,STL)对图块进行旋转变换(该过程无需学习且可微)。最后将旋转后的图块 p θ p_{\theta} pθ输入到特征描述器DESC中得到最终的描述向量。
      这里简单的介绍下SFM(Structure from motion)算法的思想,这是一种三维重建的方法,原理是从同一个物体不同视角下的照片来估计物体的位姿信息,其中必须找到同一个点在多个视角图像中对应的匹配点。本文正是利用这一能力从多个视角图像中,找到共同对应的匹配点作为图块 P P P的中心。

    训练过程

      虽然算法的处理过程是关键点检测-方向估计-特征描述,但在训练时是反过来训练的,首先训练特征描述器,然后是方向估计器,最后是关键点检测器,训练过程如下
    在这里插入图片描述
      首先训练集包含一个四元图块组 ( P 1 , P 2 , P 3 , P 4 ) (P^1,P^2,P^3,P^4) (P1,P2,P3,P4),其中 P 1 , P 2 P^1,P^2 P1,P2是同一个三维点在不同视角下的匹配图块, P 3 P^3 P3是不同的三维点对应的图块, P 4 P^4 P4是不包含任何视觉特征的图块。首先特征描述器 h ρ h_{\rho} hρ是根据《Discriminative learning of deep convolutional feature point descriptors》这篇论文设计的一个简单的卷积神经网络,其中 ρ \rho ρ表示网络参数,输入是经过旋转操作的小图块 p θ p_{\theta} pθ,输出为特征向量 d = h ρ ( p θ ) d=h_{\rho}(p_{\theta}) d=hρ(pθ)。损失函数的目的是要增大匹配图像之间的相似度,减少特征向量之间的距离;降低不匹配图像之间的相似度,增加特征向量之间的距离,计算方法如下
    在这里插入图片描述
      方向估计器 g ϕ g_{\phi} gϕ也是一个CNN结构,是要根据输入的图块 p p p来估计其旋转的角度 θ = g ϕ ( p ) \theta=g_{\phi}(p) θ=gϕ(p),该模块没法直接进行训练,需要依靠之前训练好的特征描述器进行训练,将旋转后的图块进行特征描述,再计算特征向量之间的距离,过程如下
    在这里插入图片描述
    其中 G ( P , x ) = R o t ( P , x , g ϕ ( C r o p ( P , x ) ) ) G(P,x)=Rot(P,x,g_{\phi}(Crop(P,x))) G(P,x)=Rot(P,x,gϕ(Crop(P,x))) C r o p Crop Crop表示从大图块中裁剪出小图块 p p p的过程, R o t Rot Rot表示根据预测结果旋转图块的过程。
      最后是关键点检测器 f μ f_{\mu} fμ,该文参考了TILDE算法,使用一个线性激活函数来计算得分图 S S S,过程如下
    在这里插入图片描述
    W W W表示权重, b b b表示偏置, ∗ * 表示卷积操作, M , N M,N M,N都是用来控制线性激活函数复杂度的超参数, δ n \delta_n δn n n n为奇数时为 δ n = 1 \delta_n=1 δn=1,否则为 − 1 -1 1。然后使用softargmax操作从得分图中寻找关键点 x x x,过程如下
    在这里插入图片描述
    在这里插入图片描述
      损失函数包含两个部分:一个是分类损失用来判断处理的图块是否包含关键点,二是配对损失用来判断对于不同视角下的图块,提取到的关键点是否相同。计算过程如下
    在这里插入图片描述
    在这里插入图片描述
    其中当 i = 4 i=4 i=4时, y i = − 1 , α i = 3 / 6 y_i=-1,\alpha_i=3/6 yi=1,αi=3/6,否则 y i = 1 , α i = 1 / 6 y_i=1,\alpha_i=1/6 yi=1,αi=1/6
    在这里插入图片描述

    算法评价

      本文采用基于深度学习的方法实现了从关键点检测,到方向估计,再到特征描述的完整流程,并在其中设计了许多的trick用于解决整个算法可微性的问题以及端到端训练的问题。该篇文章也给相关的研究工作奠定了一个较好的基础,且相对于传统的SIFT特征提取算法其性能也有明显的提升。

    如果大家对于深度学习与计算机视觉领域感兴趣,希望获得更多的知识分享与最新的论文解读,欢迎关注我的个人公众号“深视”。在这里插入图片描述

    展开全文
  • 一、变形transform 1、倾斜skew() skew(水平倾角,垂直倾角) 例如: skew(20deg,30deg)   2、移动变形原点transform-origin transform-origin:left/right/px/% top/bottom/px/%; 例如: ...transform-ori

    一、变形transform

    1、倾斜skew()

    skew(水平倾角,垂直倾角)

    例如:

    skew(20deg,30deg)

     

    2、移动变形原点transform-origin

    transform-origin:left/right/px/%  top/bottom/px/%;

    例如:

    transform-origin:left top;

    相当于

    transform-origin:0 0;

    !注意所有变形transform并不会影响周围其他元素

    二、过度transition

    1、动画变换速率transition-timing-function

    transition-timing-function:linear/ease/ease-in/ease-out/ease-in-out/cubic-bezier()

    说明:

    linear:匀速过度

    ease:慢—快—慢

    ease-in:开始慢

    ease-out:结束慢

    ease-in-out:开始慢,结束慢

    cubic-bezier():贝塞尔曲线,曲线形状代表路径,曲线陡峭平缓代表速度快慢

    可以访问http://cubic-bezier.com/手动调试

     

    2、延迟开始过渡

    transition-delay:xxxs;

    3、简写

    transition:

    transition-property transition-duration transition-timing-function transition-delay;

    说明:

    transition-property:CSS属性/all(所有属性)

    transition-duration:持续时间

    例如:

    transition:all 1s ease-in .5s;

    三、动画animation

    1、定义关键帧

    @keyframes animation-name {

        form{

            css起始属性

    }

    to{

            css最终属性

        }

    }

    2、简写

    animation:

    animation-name animation-duration animation-timing-function animation-iteration-count animation-direction animation-delay animation-fill-mode;

    说明:

    animation-name:动画名

    animation-duration:动画持续时间

    animation-timing-function:同transition-timing-function

    animation-iteration-count:动画运行次数,num/infinite(永久)

    animation-direction:

    动画多次运行时,设置值alternate可奇数次正向播放,偶数次反向播放

    animation-delay:延迟时间

    animation-fill-mode:设置元素在动画完成后的样子,backward/forward/both

        backward:元素退回动画前的样子

        forward:元素显示成动画完成后的样子

        both:元素显示成动画前后的样子

    3、手动暂停/开启动画

    animation-play-state:running/paused;

    四、让动画更流畅

    动画会占用大量CPU,导致设备运行卡

    以下过度不会占用过多CPU:

    (1)透明度。

    (2)transition:translate/scale/rotate。

    (3)transform:translateZ(0)设置3D属性,但元素外观无变化,骗过浏览器,强制设备开启GPU,帮助渲染,但不能使用过多,使GPU占用过大。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • CSS3 3D Transform

    2016-04-29 18:10:03
    很不错的一篇css3d transform的讲解,反正我是懂了 早前2011年5月就在站上写了一篇《CSS3 Transform》介绍CSS3中Transform属性的简单应用。但这篇文章里的知识无法满足大家对Transform... Transform——transform-ori

    很不错的一篇css3d transform的讲解,反正我是懂了

    早前2011年5月就在站上写了一篇《CSS3 Transform》介绍CSS3中Transform属性的简单应用。但这篇文章里的知识无法满足大家对Transform的一个全面认识,最近重新整理了一个Transform系列的文章,希望对初学者有所帮助。前几天介绍了《CSS3 Transform——transform-origin》、《Transform-style和Perspective属性》和《CSS3 2D Transform》。今天是这个系列的最后一篇——CSS3 3D Transform。

    作为一个网页设计师,你可能熟悉在二维空间工作,但是在三维空间上工作并不太熟悉。使用二维变形我们能够改变元素在水平和垂直轴线,然而还有一个轴沿着它,我们可以改变元素。使用三维变形,我们可以改变元素在Z轴位置。

    三维变换使用基于二维变换的相同属性,如果您熟悉二维变换,你们发现3D变形的功能和2D变换的功能相当类似。CSS3中的3D变换主要包括以下几种功能函数:
    •  3D位移:CSS3中的3D位移主要包括translateZ()和translate3d()两个功能函数;
    •  3D旋转:CSS3中的3D旋转主要包括rotateX()、rotateY()、rotateZ()和rotate3d()四个功能函数;
    •  3D缩放:CSS3中的3D缩放主要包括scaleZ()和scale3d()两个功能函数;
    •  3D矩阵:CSS3中3D变形中和2D变形一样也有一个3D矩阵功能函数matrix3d()。

    CSS3 3D位移

    在CSS3中3D位移主要包括两种函数translateZ()和translate3d()。translate3d()函数使一个元素在三维空间移动。这种变形的特点是,使用三维向量的坐标定义元素在每个方向移动多少。其基本语法如下:

    translate3d(tx,ty,tz)
    

    其属性值取值说明如下:

    •  tx:代表横向坐标位移向量的长度;
    •  ty:代表纵向坐标位移向量的长度;
    •  tz:代表Z轴位移向量的长度。此值不能是一个百分比值,如果取值为百分比值,将会认为无效值。

    一起来看一个简单的实例,加深对translate3d()函数的理解:

    HTML

    <div class="stage s1">
        <div class="container">
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="70" height="100" />
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="70" height="100" />
        </div>
    </div>
    <div class="stage s2">
        <div class="container">
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="70" height="100" />
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="70" height="100" />
        </div>
    </div>
    

    CSS

    .stage {
        width: 300px;
        height: 300px;
        float: left;
        margin: 15px;
        position: relative;
        background: url(http://www.w3cplus.com/sites/default/files/blogs/2013/1311/bg.jpg) repeat center center;
    
        -webkit-perspective: 1200px;
        -moz-perspective: 1200px;
        -ms-perspective: 1200px;
        -o-perspective: 1200px;
        perspective: 1200px;
    }
    .container {
        position: absolute;
        top: 50%;
        left: 50%;
    
        -webkit-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
        -ms-transform-style: preserve-3d;
        -o-transform-style: preserve-3d;
        transform-style: preserve-3d;
    }
    .container img {
        position: absolute;
        margin-left: -35px;
        margin-top: -50px; 
    }
    .container img:nth-child(1){
        z-index: 1;
        opacity: .6;
    }
    .s1 img:nth-child(2){
        z-index: 2; 
        -webkit-transform: translate3d(30px,30px,200px);
        -moz-transform: translate3d(30px,30px,200px);
        -ms-transform: translate3d(30px,30px,200px);
        -o-transform: translate3d(30px,30px,200px);
        transform: translate3d(30px,30px,200px);
    }
    .s2 img:nth-child(2){
        z-index: 2; 
        -webkit-transform: translate3d(30px,30px,-200px);
        -moz-transform: translate3d(30px,30px,-200px);
        -ms-transform: translate3d(30px,30px,-200px);
        -o-transform: translate3d(30px,30px,-200px);
        transform: translate3d(30px,30px,-200px);
    }
    

    效果如下所示:

    CSS3 3D Transform

    从上图的效果可以看出,当z轴值越大时,元素也离观看者更近,从视觉上元素就变得更大;反之其值越小时,元素也离观看者更远,从视觉上元素就变得更小。

    在CSS3中3D位移除了translate3d()函数之外还有translateZ()函数。translateZ()函数的功能是让元素在3D空间沿Z轴进行位移,其基本使用语法如下:

    translate(t)
    

    取值说明如下:

    •  t:指的是Z轴的向量位移长度。

    使用translateZ()函数可以让元素在Z轴进行位移,当其值为负值时,元素在Z轴越移越远,导致元素变得较小。反之,当其值为正值时,元素在Z轴越移越近,导致元素变得较大。在上例的基础上,我们稍加变化一下,将translate3d()函数换成translateZ()函数:

    .s1 img:nth-child(2){
        z-index: 2; 
        opacity: .6;
        -webkit-transform: translateZ(200px);
        -moz-transform: translateZ(200px);
        -ms-transform: translateZ(200px);
        -o-transform: translateZ(200px);
        transform: translateZ(200px);
    }
    .s2 img:nth-child(2){
        z-index: 2; 
        -webkit-transform: translateZ(-200px);
        -moz-transform: translateZ(-200px);
        -ms-transform: translateZ(-200px);
        -o-transform: translateZ(-200px);
        transform: translateZ(-200px);
    }
    

    效果如下:

    CSS3 3D Transform

    效果再次证明了translateZ()函数仅让元素在Z轴进行位移,当其值越大时,元素离观看者越近,视觉上元素放大,反之元素缩小。

    translateZ()函数在实际使用中等同于translate3d(0,0,tz)。仅从视觉效果上看,translateZ()和translate3d(0,0,tz)函数功能非常类似于二维空间的scale()缩放函数,但实际上完全不同。translateZ()和translate3d(0,0,tz)变形是发生在Z轴上,而不是X轴和Y轴。当使用3D变形,能够在一Z轴上移动一个元素确实有很大的好处,比如说在创建一个3D立方体的盒子之时。

    CSS3 3D缩放

    CSS3 3D变形中的缩放主要有scaleZ()和scale3d()两种函数,当scale3d()中X轴和Y轴同时为1,即scale3d(1,1,sz),其效果等同于scaleZ(sz)。通过使用3D缩放函数,可以让元素在Z轴上按比例缩放。默认值为1,当值大于1时,元素放大,反之小于1大于0.01时,元素缩小。其使用语法如下:

    scale3d(sx,sy,sz)
    

    其取值说明如下:

    •  sx:横向缩放比例;
    •  sy:纵向缩放比例;
    •  sz:Z轴缩放比例;
    scaleZ(s)
    

    其取值说明如下:

    •  s:指定元素每个点在Z轴的比例。

    scaleZ(-1)定义了一个原点在Z轴的对称点(按照元素的变换原点)。

    scaleZ()和scale3d()函数单独使用时没有任何效果,需要配合其他的变形函数一起使用才会有效果。下面我们来看一个实例,为了能看到scaleZ()函数的效果,我们添加了一个rotateX(45deg)功能:

    .s1 img:nth-child(2){
        z-index: 2; 
        -webkit-transform: scaleZ(5) rotateX(45deg);
        -moz-transform: scaleZ(5) rotateX(45deg);
        -ms-transform: scaleZ(5) rotateX(45deg);
        -o-transform: scaleZ(5) rotateX(45deg);
        transform: scaleZ(5) rotateX(45deg);
    }
    .s2 img:nth-child(2){
        z-index: 2; 
        -webkit-transform: scaleZ(.25) rotateX(45deg);
        -moz-transform: scaleZ(.25) rotateX(45deg);
        -ms-transform: scaleZ(.25) rotateX(45deg);
        -o-transform: scaleZ(.25) rotateX(45deg);
        transform: scaleZ(.25) rotateX(45deg);
    }
    

    其效果如下所示:

    CSS3 3D Transform

     

    CSS3 3D旋转

    到目前为止,我们已经讨论了如何让一个元素在平面上进行顺时针或逆时针旋转。在三维变形中,我们可以让元素在任何轴旋转。为此,CSS3新增三个旋转函数:rotateX()、rotateY()和rotateZ()。

    使用rotateX()函数允许一个元素围绕X轴旋转;rotateY()函数允许一个元素围绕Y轴旋转;最后rotateZ()函数允许一个元素围绕Z轴旋转。接下来我们简单的了解一下这三个旋转函数。

    rotateX()函数指定一个元素围绕X轴旋转,旋转的量被定义为指定的角度;如果值为正值,元素围绕X轴顺时针旋转;反之,如果值为负值,元素围绕X轴逆时针旋转。其基本语法如下:

    rotateX(a)
    

    其中a指的是一个旋转角度值,其值可以是正值也可以是负值。

    rotateY()函数指定一个元素围绕Y轴旋转,旋转的量被定义为指定的角度;如果值为正值,元素围绕Y轴顺时针旋转;反之,如果值为负值,元素围绕Y轴逆时针旋转。其基本语法如下:

    rotateY(a)
    

    其中a指的是一个旋转角度值,其值可以是正值也可以是负值。

    rotateZ()函数和其他两个函数功能一样的,区别在于rotateZ()函数指定一个元素围绕Z轴旋转。其基本语法如下:

    rotateZ(a)
    

    rotateZ()函数指定元素围绕Z轴旋转,如果仅从视觉角度上看,rotateZ()函数让元素顺时针或逆时针旋转,并且效果和rotate()效果等同,但他不是在2D平面的旋转。

    在三维空间里,除了rotateX()、rotateY()和rotateZ()函数可以让一个元素在三维空间中旋转之外,还有一个属性rotate3d()函数。在3D空间,旋转有三个程度的自由来描述一个转动轴。轴的旋转是由一个[x,y,z]向量并经过元素原点。其基本语法如下:

    rotate3d(x,y,z,a)
    

    rotate3d()中取值说明:

    •  x:是一个0到1之间的数值,主要用来描述元素围绕X轴旋转的矢量值;
    •  y:是一个0到1之间的数值,主要用来描述元素围绕Y轴旋转的矢量值;
    •  z:是一个0到1之间的数值,主要用来描述元素围绕Z轴旋转的矢量值;
    •  a:是一个角度值,主要用来指定元素在3D空间旋转的角度,如果其值为正值,元素顺时针旋转,反之元素逆时针旋转。

    面介绍的三个旋转函数功能等同:

    •  rotateX(a)函数功能等同于rotate3d(1,0,0,a)
    •  rotateY(a)函数功能等同于rotate3d(0,1,0,a)
    •  rotateZ(a)函数功能等同于rotate3d(0,0,1,a)

    接下来通过一个简单的实例,来实战一下3D旋转的运用:

    HTML

    <div class="stage s1">
        <div class="container">
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="140" height="200" />
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="140" height="200" />
        </div>
    </div>
    <div class="stage s2">
        <div class="container">
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="140" height="200" />
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="140" height="200" />
        </div>
    </div>
    <div class="stage s3">
        <div class="container">
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="140" height="200" />
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="140" height="200" />
        </div>
    </div>
    <div class="stage s4">
        <div class="container">
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="140" height="200" />
            <img src="http://www.w3cplus.com/sites/default/files/blogs/2013/1311/cardKingClub.png" alt="" width="140" height="200" />
        </div>
    </div>
    

    CSS

    .stage {
        width: 300px;
        height: 300px;
        float: left;
        margin: 15px;
        position: relative;
        background: url(http://www.w3cplus.com/sites/default/files/blogs/2013/1311/bg.jpg) repeat center center;
    
        -webkit-perspective: 1200px;
        -moz-perspective: 1200px;
        -ms-perspective: 1200px;
        -o-perspective: 1200px;
        perspective: 1200px;
    }
    .container {
        position: absolute;
        top: 50%;
        left: 50%;
    
        -webkit-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
        -ms-transform-style: preserve-3d;
        -o-transform-style: preserve-3d;
        transform-style: preserve-3d;
    }
    .container img {
        position: absolute;
        margin-left: -70px;
        margin-top: -100px; 
    }
    .container img:nth-child(1){
        z-index: 1;
        opacity: .6;
    }
    .s1 img:nth-child(2){
        z-index: 2; 
        -webkit-transform:rotateX(45deg);
        -moz-transform:rotateX(45deg);
        -ms-transform:rotateX(45deg);
        -o-transform:rotateX(45deg);
        transform:rotateX(45deg);
    }
    .s2 img:nth-child(2){
        z-index: 2; 
        -webkit-transform:rotateY(45deg);
        -moz-transform:rotateY(45deg);
        -ms-transform:rotateY(45deg);
        -o-transform:rotateY(45deg);
        transform:rotateY(45deg);
    }
    .s3 img:nth-child(2){
        z-index: 2; 
        -webkit-transform:rotateZ(45deg);
        -moz-transform:rotateZ(45deg);
        -ms-transform:rotateZ(45deg);
        -o-transform:rotateZ(45deg);
        transform:rotateZ(45deg);
    }
    .s4 img:nth-child(2){
        z-index: 2; 
        -webkit-transform:rotate3d(.6,1,.6,45deg);
        -moz-transform:rotate3d(.6,1,.6,45deg);
        -ms-transform:rotate3d(.6,1,.6,45deg);
        -o-transform:rotate3d(.6,1,.6,45deg);
        transform:rotate3d(.6,1,.6,45deg);
    }
    

    效果如下所示:

    CSS3 3D Transform

     

    CSS3 3D矩阵

    CSS3中的3D矩阵要比2D中的矩阵复杂的多了,从二维到三维,是从4到9;而在矩阵里头是3*3变成4*4,9到16了。话说又说回来,对于3D矩阵而言,本质上很多东西都与2D一致的,只是复杂程度不一样而已。

    3D矩阵即为透视投影,推算方法与2D矩阵类似:

    CSS3 3D Transform

    代码表示就是:

    matrix3d(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1)
    

    CSS3 3D倾斜

    倾斜是二维变形,不能在三维空间变形。元素可能会在X轴和Y轴倾斜,然后转化为三维,但它们不能在Z轴倾斜。

    CSS3 3D变形兼容性

    3D变形在实际使用这时同样需要添加各浏览器的私有属性,并且有个别属性在某些主流浏览器中并未得到很好的支持:

    •  IE10+中3D变形部分属性未得到很好的支持;
    •  Firefox10.0至Firefox15.0版本的浏览器,在使用3D变形时需要添加私有属性-moz-,但从Firefox16.0+版本开始无需添加浏览器私有属性;
    •  Chrome12.0+版本中使用3D变形时需要添加私有属性-webkit-;
    •  Safari4.0+版本中使用3D变形时需要添加私有属性-webkit-;
    •  Opera15.0+版本才开始支持3D变形,使用之里需要添加私有属性-webkit-;
    •  移动设备中iOS Safari3.2+、Android Browser3.0+、Blackberry Browser7.0+、Opera Mobile14.0+、Chrome for Android25.0+都支持3D变形,但在使用时需要添加私有属性-webkit-;Firefox for Android19.0+支持3D变形,但无需添加浏览器私有属性。

    多重变形

    在CSS3中,不管是2D变形还是3D变形,我们都可以使用多重变形,他们之间使用空格分隔,具体的语法如下:

    transform: <transform-function>  <transform-function> *
    

    其中transfrom-function是指CSS3中的任何变形函数。我们来看一个使用多重变形制作的立方体。先来看一个使用2D变形制作的立方体:

    HTML

    <div class="stage s1">
        <div class="container">
            <div class="side top">1</div>
            <div class="side left">2</div>
            <div class="side right">3</div>
        </div>
    </div>
    

    CSS

    @-webkit-keyframes spin{
        0%{-webkit-transform:rotateY(0deg);transform:rotateY(0deg)}
        100%{-webkit-transform:rotateY(360deg);transform:rotateY(360deg)}
    }
    @-moz-keyframes spin{
        0%{-moz-transform:rotateY(0deg);transform:rotateY(0deg)}
        100%{-moz-transform:rotateY(360deg);transform:rotateY(360deg)}
    }
    @-ms-keyframes spin{        
    
        0%{-ms-transform:rotateY(0deg);transform:rotateY(0deg)}     100%{-ms-transform:rotateY(360deg);transform:rotateY(360deg)}
    }
    @-o-keyframes spin{     
    
        0%{-o-transform:rotateY(0deg);transform:rotateY(0deg)}
        100%{-o-transform:rotateY(360deg);transform:rotateY(360deg)}
    }
    @keyframes spin{
        0%{transform:rotateY(0deg)}
        100%{transform:rotateY(360deg)}
    }
    .stage {
        width: 300px;
        height: 300px;
        float: left;
        margin: 15px;
        position: relative;
        background: url(http://www.w3cplus.com/sites/default/files/blogs/2013/1311/bg.jpg) repeat center center;
    
        -webkit-perspective: 1200px;
        -moz-perspective: 1200px;
        -ms-perspective: 1200px;
        -o-perspective: 1200px;
        perspective: 1200px;
    }
    .container {
        position: relative;
        height: 230px;
        width: 100px;
        top: 50%;
        left: 50%;
        margin: -100px 0 0 -50px;
        -webkit-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
        -ms-transform-style: preserve-3d;
        -o-transform-style: preserve-3d;
        transform-style: preserve-3d;
    }
    .container:hover{
        -moz-animation:spin 5s linear infinite;
        -o-animation:spin 5s linear infinite;
        -webkit-animation:spin 5s linear infinite;
        animation:spin 5s linear infinite;
    }
    .side {
        font-size: 20px;
        font-weight: bold;
        height: 100px;
        line-height: 100px;
        color: #fff;
        position: absolute;
        text-align: center;
        text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
        text-transform: uppercase;
        width: 100px;
    }
    .top {
        background: #9acc53;
        -webkit-transform: rotate(-45deg) skew(15deg, 15deg);
        -moz-transform: rotate(-45deg) skew(15deg, 15deg);
        -ms-transform: rotate(-45deg) skew(15deg, 15deg);
        -o-transform: rotate(-45deg) skew(15deg, 15deg);
        transform: rotate(-45deg) skew(15deg, 15deg);
    }
    .left {
        background: #8ec63f;
        -webkit-transform: rotate(15deg) skew(15deg, 15deg) translate(-50%, 100%);
        -moz-transform: rotate(15deg) skew(15deg, 15deg) translate(-50%, 100%);
        -ms-transform: rotate(15deg) skew(15deg, 15deg) translate(-50%, 100%);
        -o-transform: rotate(15deg) skew(15deg, 15deg) translate(-50%, 100%);
        transform: rotate(15deg) skew(15deg, 15deg) translate(-50%, 100%);
    }
    .right {
        background: #80b239;
        -webkit-transform: rotate(-15deg) skew(-15deg, -15deg) translate(50%, 100%);
        -moz-transform: rotate(-15deg) skew(-15deg, -15deg) translate(50%, 100%);
        -ms-transform: rotate(-15deg) skew(-15deg, -15deg) translate(50%, 100%);
        -o-transform: rotate(-15deg) skew(-15deg, -15deg) translate(50%, 100%);
        transform: rotate(-15deg) skew(-15deg, -15deg) translate(50%, 100%);
    }
    

    效果如下:

    CSS3 3D Transform

     

    上例通过三个面,使用多个2D变形,制作的一个3D立方体,接着我们在来使用3D多重变形制作一个3D立方体。

    HTML

    <div class="stage">
        <div class="container">
            <div class="side front">1</div>
            <div class="side back">2</div>
            <div class="side left">3</div>
            <div class="side right">4</div>
            <div class="side top">5</div>
            <div class="side bottom">6</div>
        </div>
    </div>
    

    CSS

    @-webkit-keyframes spin{
         0%{
             -webkit-transform:rotateY(0deg);
             transform:rotateY(0deg) }
          100%{
            -webkit-transform:rotateY(360deg);
            transform:rotateY(360deg) }
        }
        @-moz-keyframes spin{
            0%{
                -moz-transform:rotateY(0deg);
                transform:rotateY(0deg) }
            100%{
                -moz-transform:rotateY(360deg);
                transform:rotateY(360deg) }
        }
        @-ms-keyframes spin{
            0%{
                -ms-transform:rotateY(0deg);
                transform:rotateY(0deg) }
            100%{
                -ms-transform:rotateY(360deg);
                transform:rotateY(360deg) }
        }
        @-o-keyframes spin{
            0%{
                -o-transform:rotateY(0deg);
                transform:rotateY(0deg) }
            100%{
                -o-transform:rotateY(360deg);
                transform:rotateY(360deg) }
        }
        @keyframes spin{
            0%{transform:rotateY(0deg)}
            100%{transform:rotateY(360deg)}
        }
        .stage {
            width: 300px;
            height: 300px;
            margin: 15px auto;
            position: relative;
            background: url(http://www.w3cplus.com/sites/default/files/blogs/2013/1311/bg.jpg) repeat center center;
    
            -webkit-perspective: 300px;
            -moz-perspective: 300px;
            -ms-perspective: 300px;
            -o-perspective: 300px;
            perspective: 300px;
        }
        .container {
            top: 50%;
            left: 50%;
            margin: -100px 0 0 -100px;
            position: absolute;
            -webkit-transform: translateZ(-100px);
            -moz-transform: translateZ(-100px);
            -ms-transform: translateZ(-100px);
            -o-transform: translateZ(-100px);
            transform: translateZ(-100px);
            -webkit-transform-style: preserve-3d;
            -moz-transform-style: preserve-3d;
            -ms-transform-style: preserve-3d;
            -o-transform-style: preserve-3d;
            transform-style: preserve-3d;
        }
        .container:hover{
            -moz-animation:spin 5s linear infinite;
            -o-animation:spin 5s linear infinite;
            -webkit-animation:spin 5s linear infinite;
            animation:spin 5s linear infinite;
        }
        .side {
            background: rgba(142,198,63,0.3);
            border: 2px solid #8ec63f;
            font-size: 60px;
            font-weight: bold;
            color: #fff;
            height: 196px;
            line-height: 196px;
            position: absolute;
            text-align: center;
            text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
            text-transform: uppercase;
            width: 196px;
        }
    
        .front {
            -webkit-transform: translateZ(100px);
            -moz-transform: translateZ(100px);
            -ms-transform: translateZ(100px);
            -o-transform: translateZ(100px);
            transform: translateZ(100px);
        }
        .back {
            -webkit-transform: rotateX(180deg) translateZ(100px);
            -moz-transform: rotateX(180deg) translateZ(100px);
            -ms-transform: rotateX(180deg) translateZ(100px);
            -o-transform: rotateX(180deg) translateZ(100px);
            transform: rotateX(180deg) translateZ(100px);
        }
        .left {
            -webkit-transform: rotateY(-90deg) translateZ(100px);
            -moz-transform: rotateY(-90deg) translateZ(100px);
            -ms-transform: rotateY(-90deg) translateZ(100px);
            -o-transform: rotateY(-90deg) translateZ(100px);
            transform: rotateY(-90deg) translateZ(100px);
        }
        .right {
            -webkit-transform: rotateY(90deg) translateZ(100px);
            -moz-transform: rotateY(90deg) translateZ(100px);
            -ms-transform: rotateY(90deg) translateZ(100px);
            -o-transform: rotateY(90deg) translateZ(100px);
            transform: rotateY(90deg) translateZ(100px);
        }
        .top {
            -webkit-transform: rotateX(90deg) translateZ(100px);
            -moz-transform: rotateX(90deg) translateZ(100px);
            -ms-transform: rotateX(90deg) translateZ(100px);
            -o-transform: rotateX(90deg) translateZ(100px);
            transform: rotateX(90deg) translateZ(100px);
        }
        .bottom {
            -webkit-transform: rotateX(-90deg) translateZ(100px);
            -moz-transform: rotateX(-90deg) translateZ(100px);
            -ms-transform: rotateX(-90deg) translateZ(100px);
            -o-transform: rotateX(-90deg) translateZ(100px);
            transform: rotateX(-90deg) translateZ(100px);
        }
    

    效果如下所示:

    CSS3 3D Transform

     

    案例实战:使用3D变形制作产品信息展示

    在Web设计中有很多方法用来制作产品信息展示,例如当鼠标移动到产品图片上时,产品信息滑动出来甚至使用弹出框。在这里,我们将使用CSS3 3D变形来制作一个3D立方体翻转展示信息的效果。

    在谈论技术之前,我们先来看要实现的效果(如下图)。默认情况之下只显示产品图片,而产品信息隐藏不可见。当用户鼠标悬浮在产品图像上时,产品图像慢慢往上旋转使产品信息展示出来,而产品图像慢慢隐藏起来,看起来就像是一个旋转的立方体。
    CSS3 3D Transform
    该技术用于创建一个多维的数据,在这个实例中使用了两个元素用于正面和反面。前面用来放置产品图片,底部用来放置产品信息。默认情况下产品信息隐藏起来,同时鼠标悬停在产品图片上时,隐藏在底部的产品信息在X轴放置-90度和Z轴旋转,使底部的信息旋转置于顶部,从而达到我们需要的效果,产品图片隐藏,产品信息显示。如图所示:

    CSS3 3D Transform

    使用两个标签包裹产品图片和产品信息,第一个主要用来设置3D视点perspective,旨在设置用户有画布的视距;第二个包裹容器主要用来包裹图片和产品信息。当鼠标悬浮在这个容器上时,会沿X轴旋转,将产品信息显示出来。在三维旋转中,我们常的一种结构:

    舞台=>div.wrapper
        容器=>div.item
            产品图片=>img
            产品信息=>span.information
    

    在我们的实例中使用的结构是:

    <div class="wrapper">
          <div class="item">
            <img src="images/contact.png" />
            <span class="information">
              <strong>Contact Form</strong> The easiest way to add a contact form to your shop.
            </span>
          </div>
        </div>
    

    接下来完成这个实例的样式。首先给每个wrapper容器设置display:inline-block和perspective:4000px,同时给item设置transform-style:preserve-3d让他的子元素具有一个3D位置。并且为了效果能更加完美,在例中添加了CSS3的transition属性:

    .wrapper {
        display: inline-block;
        width: 310px;
        height: 100px;
        vertical-align: top;
        margin: 1em 1.5em 2em 0;
        cursor: pointer;
        position: relative;
        font-family: Tahoma, Arial;
        -webkit-perspective: 4000px;
           -moz-perspective: 4000px;
            -ms-perspective: 4000px;
             -o-perspective: 4000px;
                perspective: 4000px;
      }
    
      .item {
        height: 100px;
          -webkit-transform-style: preserve-3d;
             -moz-transform-style: preserve-3d;
              -ms-transform-style: preserve-3d;
               -o-transform-style: preserve-3d;
                  transform-style: preserve-3d;
          -webkit-transition: -webkit-transform .6s;
             -moz-transition: -moz-transform .6s;
              -ms-transition: -ms-transform .6s;
               -o-transition: -o-transform .6s;
                  transition: transform .6s;
      }
    

    接下来给产品图片设置一个Z轴位移,给产品信息设置一个X轴旋转和Z轴位移,为了效果更加完美,还添加了一些其他的装饰样式:

    .item img {
      display: block;
      position: absolute;
      top: 0;
      border-radius: 3px;
      box-shadow: 0px 3px 8px rgba(0,0,0,0.3);
      -webkit-transform: translateZ(50px);
         -moz-transform: translateZ(50px);
          -ms-transform: translateZ(50px);
           -o-transform: translateZ(50px);
              transform: translateZ(50px);
      -webkit-transition: all .6s;
         -moz-transition: all .6s;
          -ms-transition: all .6s;
           -o-transition: all .6s;
              transition: all .6s;
    }
    .item .information {
      display: block;
      position: absolute;
      top: 0;
      height: 80px;
      width: 290px;
      text-align: left;
      border-radius: 15px;
      padding: 10px;
      font-size: 12px;
      text-shadow: 1px 1px 1px rgba(255,255,255,0.5);
      box-shadow: none;
      background: rgb(236,241,244);
      background: -webkit-linear-gradient(to bottom, rgba(236,241,244,1) 0%,rgba(190,202,217,1) 100%);
      background: -ms-linear-gradient(to bottom, rgba(236,241,244,1) 0%,rgba(190,202,217,1) 100%);
      background: linear-gradient(to bottom, rgba(236,241,244,1) 0%,rgba(190,202,217,1) 100%);
      -webkit-transform: rotateX(-90deg) translateZ(50px);
         -moz-transform: rotateX(-90deg) translateZ(50px);
          -ms-transform: rotateX(-90deg) translateZ(50px);
           -o-transform: rotateX(-90deg) translateZ(50px);
              transform: rotateX(-90deg) translateZ(50px);
      -webkit-transition: all .6s;
         -moz-transition: all .6s;
          -ms-transition: all .6s;
           -o-transition: all .6s;
              transition: all .6s;
    }
    

    最后来完成用户鼠标悬浮在产品图片上时,旋转隐藏产品图片,同时产品信息旋转显示出来:

    .item:hover {
      -webkit-transform: translateZ(-50px) rotateX(95deg);
         -moz-transform: translateZ(-50px) rotateX(95deg);
          -ms-transform: translateZ(-50px) rotateX(95deg);
           -o-transform: translateZ(-50px) rotateX(95deg);
              transform: translateZ(-50px) rotateX(95deg);
    }
    
      .item:hover img {
        box-shadow: none;
        border-radius: 15px;
      }
    
      .item:hover .information {
        box-shadow: 0px 3px 8px rgba(0,0,0,0.3);
        border-radius: 3px;
      }
    

    到此整个实例的效果就全部完成了,由于篇幅问题,这里不展示所有代码,如果您对这个实例感兴趣,可以点击DEMO或下载源码自己分析。


    展开全文
  • 这里我们还需要name、oriimg(resize后的原始图像,以帮助我们可视化) def test(self): self.model.eval() self.evaluator.reset() # tbar = tqdm(self.test_loader, desc='\r') num = len(self.test_...

    以项目pytorch-deeplab-xception为例:

    测试代码:

    https://github.com/jfzhang95/pytorch-deeplab-xception/issues/122

        def test(self):
            self.model.eval()
            self.evaluator.reset()
            # tbar = tqdm(self.test_loader, desc='\r')
            for i, sample in enumerate(self.test_loader):
                image, target = sample['image'], sample['label']
                with torch.no_grad():
                    output = self.model(image)
                pred = output.data.cpu().numpy()
                target = target.cpu().numpy()

    这里通过枚举函数,生成的只有image和target,

    但是image是已经数据增强过的,有可能已经改变,而且经过Totensor()函数和均值方差,

    已经不能适应后续我们可视化任务的需要,

    这里我们还需要name、oriimg(resize后的原始图像,以帮助我们可视化)

        def test(self):
            self.model.eval()
            self.evaluator.reset()
            # tbar = tqdm(self.test_loader, desc='\r')
            num = len(self.test_loader)
            for i, sample in enumerate(self.test_loader):
                image, target = sample['image'], sample['label']
                print(i,"/",num)
                torch.cuda.synchronize()
                start = time.time()
                with torch.no_grad():
                    output = self.model(image)
                end = time.time()
                times = (end - start) * 1000
                print(times, "ms")
                torch.cuda.synchronize()
                pred = output.data.cpu().numpy()
                pred = np.argmax(pred, axis=1)
                target = target.cpu().numpy()

    原始的dateset代码:

    train_set = coco.COCOSegmentation(args, split='train')
    val_set = coco.COCOSegmentation(args, split='val'

    train_loader = DataLoader(train_set, batch_size=args.batch_size, shuffle=True, **kwargs)
    val_loader = DataLoader(val_set, batch_size=args.batch_size, shuffle=False, **kwargs)

    from dataloaders.datasets import cityscapes, coco, combine_dbs, pascal, sbd
    from torch.utils.data import DataLoader
    
    def make_data_loader(args, **kwargs):
    
        elif args.dataset == 'coco':
            train_set = coco.COCOSegmentation(args, split='train')
            val_set = coco.COCOSegmentation(args, split='val')
            num_class = train_set.NUM_CLASSES
            train_loader = DataLoader(train_set, batch_size=args.batch_size, shuffle=True, **kwargs)
            val_loader = DataLoader(val_set, batch_size=args.batch_size, shuffle=False, **kwargs)
            test_loader = None
            return train_loader, val_loader, test_loader, num_class
    
        else:
            raise NotImplementedError

    通过COCO处理函数得到COCO的dataset:

    import numpy as np
    import torch
    from torch.utils.data import Dataset
    from mypath import Path
    from tqdm import trange
    import os
    from pycocotools.coco import COCO
    from pycocotools import mask
    from torchvision import transforms
    from dataloaders import custom_transforms as tr
    from PIL import Image, ImageFile
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    
    
    class COCOSegmentation(Dataset):
        NUM_CLASSES = 21
        CAT_LIST = [0, 5, 2, 16, 9, 44, 6, 3, 17, 62, 21, 67, 18, 19, 4,
            1, 64, 20, 63, 7, 72]
    
        def __init__(self,
                     args,
                     base_dir=Path.db_root_dir('coco'),
                     split='train',
                     year='2017'):
            super().__init__()
            ann_file = os.path.join(base_dir, 'annotations/instances_{}{}.json'.format(split, year))
            ids_file = os.path.join(base_dir, 'annotations/{}_ids_{}.pth'.format(split, year))
            self.img_dir = os.path.join(base_dir, 'images/{}{}'.format(split, year))
            self.split = split
            self.coco = COCO(ann_file)
            self.coco_mask = mask
            if os.path.exists(ids_file):
                self.ids = torch.load(ids_file)
            else:
                ids = list(self.coco.imgs.keys())
                self.ids = self._preprocess(ids, ids_file)
            self.args = args
    
        def __getitem__(self, index):
            _img, _target = self._make_img_gt_point_pair(index)
            sample = {'image': _img, 'label': _target}
    
            if self.split == "train":
                return self.transform_tr(sample)
            elif self.split == 'val':
                return self.transform_val(sample)
    
        def _make_img_gt_point_pair(self, index):
            coco = self.coco
            img_id = self.ids[index]
            img_metadata = coco.loadImgs(img_id)[0]
            path = img_metadata['file_name']
            _img = Image.open(os.path.join(self.img_dir, path)).convert('RGB')
            cocotarget = coco.loadAnns(coco.getAnnIds(imgIds=img_id))
            _target = Image.fromarray(self._gen_seg_mask(
                cocotarget, img_metadata['height'], img_metadata['width']))
    
            return _img, _target
    
        def _preprocess(self, ids, ids_file):
            print("Preprocessing mask, this will take a while. " + \
                  "But don't worry, it only run once for each split.")
            tbar = trange(len(ids))
            new_ids = []
            for i in tbar:
                img_id = ids[i]
                cocotarget = self.coco.loadAnns(self.coco.getAnnIds(imgIds=img_id))
                img_metadata = self.coco.loadImgs(img_id)[0]
                mask = self._gen_seg_mask(cocotarget, img_metadata['height'],
                                          img_metadata['width'])
                # more than 1k pixels
                if (mask > 0).sum() > 1000:
                    new_ids.append(img_id)
                tbar.set_description('Doing: {}/{}, got {} qualified images'. \
                                     format(i, len(ids), len(new_ids)))
            print('Found number of qualified images: ', len(new_ids))
            torch.save(new_ids, ids_file)
            return new_ids
    
        def _gen_seg_mask(self, target, h, w):
            mask = np.zeros((h, w), dtype=np.uint8)
            coco_mask = self.coco_mask
            for instance in target:
                rle = coco_mask.frPyObjects(instance['segmentation'], h, w)
                m = coco_mask.decode(rle)
                cat = instance['category_id']
                if cat in self.CAT_LIST:
                    c = self.CAT_LIST.index(cat)
                else:
                    continue
                if len(m.shape) < 3:
                    mask[:, :] += (mask == 0) * (m * c)
                else:
                    mask[:, :] += (mask == 0) * (((np.sum(m, axis=2)) > 0) * c).astype(np.uint8)
            return mask
    
        def transform_tr(self, sample):
            composed_transforms = transforms.Compose([
                tr.RandomHorizontalFlip(),
                tr.RandomScaleCrop(base_size=self.args.base_size, crop_size=self.args.crop_size),
                tr.RandomGaussianBlur(),
                tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
                tr.ToTensor()])
    
            return composed_transforms(sample)
    
        def transform_val(self, sample):
    
            composed_transforms = transforms.Compose([
                tr.FixScaleCrop(crop_size=self.args.crop_size),
                tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
                tr.ToTensor()])
    
            return composed_transforms(sample)
    
    
        def __len__(self):
            return len(self.ids)
    

    这里使用的数据增强为自己写的函数,不是pytorch中的transforms

    但是使用了transforms的容器函数:transforms.Compose()

    数据增强函数都有:

    class Normalize(object):

    class ToTensor(object):

    class RandomHorizontalFlip(object):

    class RandomRotate(object):

    class RandomGaussianBlur(object):

    class RandomScaleCrop(object):

    class FixScaleCrop(object):

    class FixedResize(object):

    这里有一个流程,

    pytorch-deeplab-xception/train.py

    self.train_loader, self.val_loader, self.test_loader, self.nclass = make_data_loader(args, **kwargs) 

    pytorch-deeplab-xception/dataloaders/__init__.py

    train_set = cityscapes.CityscapesSegmentation(args, split='train') 

    pytorch-deeplab-xception/dataloaders/datasets/coco.py

    def __getitem__(self, index):

        def __getitem__(self, index):
            _img, _target = self._make_img_gt_point_pair(index)
            sample = {'image': _img, 'label': _target}
    
            if self.split == "train":
                return self.transform_tr(sample)
            elif self.split == 'val':
                return self.transform_val(sample)

     def _make_img_gt_point_pair(self, index):

        def _make_img_gt_point_pair(self, index):
            coco = self.coco
            img_id = self.ids[index]
            img_metadata = coco.loadImgs(img_id)[0]
            path = img_metadata['file_name']
            _img = Image.open(os.path.join(self.img_dir, path)).convert('RGB')
            cocotarget = coco.loadAnns(coco.getAnnIds(imgIds=img_id))
            _target = Image.fromarray(self._gen_seg_mask(
                cocotarget, img_metadata['height'], img_metadata['width']))
    
            return _img, _target

    def transform_tr(self, sample): 

        def transform_tr(self, sample):
            composed_transforms = transforms.Compose([
                tr.RandomHorizontalFlip(),
                tr.RandomScaleCrop(base_size=self.args.base_size, crop_size=self.args.crop_size),
                tr.RandomGaussianBlur(),
                tr.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
                tr.ToTensor()])
    
            return composed_transforms(sample)

     

    pytorch-deeplab-xception/dataloaders/custom_transforms.py

    class Normalize(object):

    class ToTensor(object):

    class FixScaleCrop(object):

    class FixScaleCrop(object):
        def __init__(self, crop_size):
            self.crop_size = crop_size
    
        def __call__(self, sample):
            img = sample['image']
            mask = sample['label']
            w, h = img.size
            if w > h:
                oh = self.crop_size
                ow = int(1.0 * w * oh / h)
            else:
                ow = self.crop_size
                oh = int(1.0 * h * ow / w)
            img = img.resize((ow, oh), Image.BILINEAR)
            mask = mask.resize((ow, oh), Image.NEAREST)
            # center crop
            w, h = img.size
            x1 = int(round((w - self.crop_size) / 2.))
            y1 = int(round((h - self.crop_size) / 2.))
            img = img.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))
            mask = mask.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))
    
            return {'image': img,
                    'label': mask}
    class Normalize(object):
        """Normalize a tensor image with mean and standard deviation.
        Args:
            mean (tuple): means for each channel.
            std (tuple): standard deviations for each channel.
        """
        def __init__(self, mean=(0., 0., 0.), std=(1., 1., 1.)):
            self.mean = mean
            self.std = std
    
        def __call__(self, sample):
            img = sample['image']
            mask = sample['label']
            img = np.array(img).astype(np.float32)
            mask = np.array(mask).astype(np.float32)
            img /= 255.0
            img -= self.mean
            img /= self.std
    
            return {'image': img,
                    'label': mask}
    class ToTensor(object):
        """Convert ndarrays in sample to Tensors."""
    
        def __call__(self, sample):
            # swap color axis because
            # numpy image: H x W x C
            # torch image: C X H X W
            img = sample['image']
            mask = sample['label']
            img = np.array(img).astype(np.float32).transpose((2, 0, 1))
            mask = np.array(mask).astype(np.float32)
    
            img = torch.from_numpy(img).float()
            mask = torch.from_numpy(mask).float()
    
            return {'image': img,
                    'label': mask}

    改进一下,可以返回原图和路径:

    import torch
    import random
    import numpy as np
    
    from PIL import Image, ImageOps, ImageFilter
    
    class Normalize(object):
        """Normalize a tensor image with mean and standard deviation.
        Args:
            mean (tuple): means for each channel.
            std (tuple): standard deviations for each channel.
        """
        def __init__(self, mean=(0., 0., 0.), std=(1., 1., 1.)):
            self.mean = mean
            self.std = std
    
        def __call__(self, sample):
            img = sample['image']
            mask = sample['label']
            img = np.array(img).astype(np.float32)
            mask = np.array(mask).astype(np.float32)
            img /= 255.0
            img -= self.mean
            img /= self.std
    
            # return {'image': img,
            #         'label': mask}
    
            #return {'image': img, 'label': mask, 'ori_image': sample['ori_image'], 'path': sample['path']}
    
            return {'image': img, 'label': mask, 'ori_image': sample['ori_image'], 'path': sample['path']}
    
    
    class ToTensor(object):
        """Convert ndarrays in sample to Tensors."""
    
        def __call__(self, sample):
            # swap color axis because
            # numpy image: H x W x C
            # torch image: C X H X W
            img = sample['image']
            mask = sample['label']
    
            # import cv2
            # image1 = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
            # target1 = cv2.cvtColor(np.asarray(mask), cv2.COLOR_GRAY2BGR)
            # cv2.imwrite("./image5.jpg", image1)
            # cv2.imwrite("./target5.jpg", target1)
            #
            # xxx = np.array(img).astype(np.float32)
            # import copy
            # xxx1 = copy.deepcopy(xxx)
            # xxx2 = copy.deepcopy(xxx)
            # img1 = np.array(xxx1).astype(np.float32).transpose((2, 1, 0))
            # img2 = np.array(xxx2).astype(np.float32).transpose((2, 0, 1))
    
            img = np.array(img).astype(np.float32).transpose((2, 0, 1))
            mask = np.array(mask).astype(np.float32)
    
            img = torch.from_numpy(img).float()
            mask = torch.from_numpy(mask).float()
    
            # import cv2
            # image1=img.cpu().numpy()
            # target1=mask.cpu().numpy()
            # image1 = image1.transpose(2, 1, 0)
            # image1 = cv2.cvtColor(image1, cv2.COLOR_RGB2BGR)
            # target1 = cv2.cvtColor(target1, cv2.COLOR_GRAY2BGR)
            # cv2.imwrite("./image4.jpg", image1)
            # cv2.imwrite("./target4.jpg", target1)
    
            # return {'image': img,
            #         'label': mask}
            ori_image = np.array(sample['ori_image']).astype(np.float32).transpose((2, 0, 1))
            ori_image = torch.from_numpy(ori_image).float()
    
            #return {'image': img, 'label': mask, 'ori_image': sample['ori_image'], 'path': sample['path']}
            return {'image': img, 'label': mask, 'ori_image': ori_image, 'path': sample['path']}
    
    
    class RandomHorizontalFlip(object):
        def __call__(self, sample):
            img = sample['image']
            mask = sample['label']
            if random.random() < 0.5:
                img = img.transpose(Image.FLIP_LEFT_RIGHT)
                mask = mask.transpose(Image.FLIP_LEFT_RIGHT)
    
            # return {'image': img,
            #         'label': mask}
            return {'image': img, 'label': mask, 'ori_image': sample['ori_image'], 'path': sample['path']}
    
    
    class RandomRotate(object):
        def __init__(self, degree):
            self.degree = degree
    
        def __call__(self, sample):
            img = sample['image']
            mask = sample['label']
            rotate_degree = random.uniform(-1*self.degree, self.degree)
            img = img.rotate(rotate_degree, Image.BILINEAR)
            mask = mask.rotate(rotate_degree, Image.NEAREST)
    
            return {'image': img,
                    'label': mask}
    
    
    class RandomGaussianBlur(object):
        def __call__(self, sample):
            img = sample['image']
            mask = sample['label']
            if random.random() < 0.5:
                img = img.filter(ImageFilter.GaussianBlur(
                    radius=random.random()))
    
            # return {'image': img,
            #         'label': mask}
            return {'image': img, 'label': mask, 'ori_image': sample['ori_image'], 'path': sample['path']}
    
    class RandomScaleCrop(object):
        def __init__(self, base_size, crop_size, fill=0):
            self.base_size = base_size
            self.crop_size = crop_size
            self.fill = fill
    
        def __call__(self, sample):
            img = sample['image']
            mask = sample['label']
            # random scale (short edge)
            short_size = random.randint(int(self.base_size * 0.5), int(self.base_size * 2.0))
            w, h = img.size
            if h > w:
                ow = short_size
                oh = int(1.0 * h * ow / w)
            else:
                oh = short_size
                ow = int(1.0 * w * oh / h)
            img = img.resize((ow, oh), Image.BILINEAR)
            mask = mask.resize((ow, oh), Image.NEAREST)
            # pad crop
            if short_size < self.crop_size:
                padh = self.crop_size - oh if oh < self.crop_size else 0
                padw = self.crop_size - ow if ow < self.crop_size else 0
                img = ImageOps.expand(img, border=(0, 0, padw, padh), fill=0)
                mask = ImageOps.expand(mask, border=(0, 0, padw, padh), fill=self.fill)
            # random crop crop_size
            w, h = img.size
            x1 = random.randint(0, w - self.crop_size)
            y1 = random.randint(0, h - self.crop_size)
            img = img.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))
            mask = mask.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))
            #x = mask[mask>1]
            return {'image': img, 'label': mask, 'ori_image': img, 'path': sample['path']}
            #return {'image': img, 'label': mask, 'ori_image': sample['ori_image'], 'path': sample['path']}
            # return {'image': img,
            #         'label': mask}
    
    
    class FixScaleCrop(object):
        def __init__(self, crop_size):
            self.crop_size = crop_size
    
        def __call__(self, sample):
            img = sample['image']
            mask = sample['label']
            w, h = img.size
            if w > h:
                oh = self.crop_size
                ow = int(1.0 * w * oh / h)
            else:
                ow = self.crop_size
                oh = int(1.0 * h * ow / w)
            img = img.resize((ow, oh), Image.BILINEAR)
            mask = mask.resize((ow, oh), Image.NEAREST)
            # center crop
            w, h = img.size
            x1 = int(round((w - self.crop_size) / 2.))
            y1 = int(round((h - self.crop_size) / 2.))
            img = img.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))
            mask = mask.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))
    
            # import cv2
            # image1 = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
            # target1 = cv2.cvtColor(np.asarray(mask), cv2.COLOR_GRAY2BGR)
            # cv2.imwrite("./image3.jpg", image1)
            # cv2.imwrite("./target3.jpg", target1)
    
    
            # return {'image': img,
            #         'label': mask,
            #         }
            #return {'image': img, 'label': mask, 'ori_image': img, 'path': sample['path']}
    
            return {'image': img, 'label': mask, 'ori_image': img, 'path': sample['path']}
    
    class FixedResize(object):
        def __init__(self, size):
            self.size = (size, size)  # size: (h, w)
    
        def __call__(self, sample):
            img = sample['image']
            mask = sample['label']
    
            assert img.size == mask.size
    
            img = img.resize(self.size, Image.BILINEAR)
            mask = mask.resize(self.size, Image.NEAREST)
    
            return {'image': img,
                    'label': mask}
        def __getitem__(self, index):
            _img, _target, _path = self._make_img_gt_point_pair(index)
            sample = {'image': _img, 'label': _target, 'ori_image': _img, 'path': _path}
    
            if self.split == "train":
                return self.transform_tr(sample)
            elif self.split == 'val':
                return self.transform_val(sample)
            elif self.split == 'test':
                X = self.transform_val(sample)
                # aa = X['image']
                # bb = X['label']
                #
                # aa = aa.cpu().numpy()
                # bb = bb.cpu().numpy()
                # aa = aa.transpose(2, 1, 0)
                # image1 = cv2.cvtColor(aa, cv2.COLOR_RGB2BGR)
                # target1 = cv2.cvtColor(bb, cv2.COLOR_GRAY2BGR)
                # cv2.imwrite("./image2.jpg", image1)
                # cv2.imwrite("./target2.jpg", target1)
    
                return X
    
        def _make_img_gt_point_pair(self, index):
            coco = self.coco
            img_id = self.ids[index]
            img_metadata = coco.loadImgs(img_id)[0]
            path = img_metadata['file_name']
            _path = path.split('.jpg')[0]
            _img = Image.open(os.path.join(self.img_dir, path)).convert('RGB')
            cocotarget = coco.loadAnns(coco.getAnnIds(imgIds=img_id))
            _target = Image.fromarray(self._gen_seg_mask(
                cocotarget, img_metadata['height'], img_metadata['width']))
    
            #_targetx = np.asarray(_target)
            #x = _targetx[_targetx > 1]
            # image1 = cv2.cvtColor(np.asarray(_img), cv2.COLOR_RGB2BGR)
            # target1 = cv2.cvtColor(np.asarray(_target), cv2.COLOR_GRAY2BGR)
            # cv2.imwrite("./image1.jpg", image1)
            # cv2.imwrite("./target1.jpg", target1)
    
            return _img, _target, _path

     

    展开全文
  • OpenGL Transform feed back 粒子系统

    千次阅读 2016-05-11 09:11:17
    在原来的OpenGL渲染的pipeline并没有提供较多的交互接口,当调用Draw函数之后很难再绘制过程对已经装配的图元进行修改。然而,在绘制过程中存在这样的需求,尤其是需要根据之前装配好的图元来更新随后...Transform feed
  • preprocessing这个模块还提供了一个实用类Normalizer,实用transform方法同样也可以对新的数据进行同样的转换 根据训练数据创建一个正则器 normalizer = preprocessing.Normalizer().fit(x) normalizer 1 2 3...
  • 小目标的目标检测

    2021-06-18 14:25:55
    crop crop的尺寸尽可能的是原... bbox = bboxes[i] bbox[:2] = affine_transform(bbox[:2], trans_affine) bbox[2:] = affine_transform(bbox[2:], trans_affine) ori_h, ori_w = bbox[3] - bbox[1], bbox[2] - bbox[0]...
  • ori.SetTRS(transform.position, transform.rotation, Vector3.one); matrix = Matrix4x4.identity; if (axle == SelfAxle.X) { matrix.m11 = Mathf.Cos(angle * Mathf.Deg2Rad); matrix.m12 = -Mathf.Sin(angle * ...
  • 基于kaggle气胸X光比赛原始数据,对RLE气胸标注标签转储mask图和json标注可读文件,JPEG胸片图像。公开代码基于python,可用于后续的分类、检测、分割等等任务数据输入
  • s = T r e l = O r i − O r i s t a r t O r i e n d − O r i s t a r t s = T_{rel}=\frac{Ori-Ori_{start}}{Ori_{end}-Ori_{start}} s=Trel​=Oriend​−Oristart​Ori−Oristart​​ 这里需要重新了解旋转矩阵...
  • using System.Collections.Generic; using UnityEngine; public class MatHideDisplayCtrl : MonoBehaviour { public static MatHideDisplayCtrl instance; [SerializeField] private Material ...Transform, List.
  • [机器学习] 模型融合GBDT(xgb/lgbm/rf)+LR 的原理及实践

    千次阅读 多人点赞 2019-01-23 16:21:37
    X_train_leaves = onehot.fit_transform(lgbm.predict(X_train, pred_leaf=True)) lgbm_lr = LogisticRegression() lgbm_lr.fit(X_train_leaves, y_train) X_test_leaves = onehot.transform(lgbm.predict(X_...
  • PyTorch faster_rcnn之一源码解读一

    千次阅读 2019-03-10 11:14:14
    class Transform voc_dataset.VOCBboxDataset class Transform read_label read_image progress util.resize_bbox util.random_flip util.flip_bbox caffe_pretrain pytorch_pretrain caffe_normalize pytorch_...
  • JS实现骰子3D旋转效果

    2021-01-19 21:07:41
    本文实例为大家分享了JS实现骰子3D旋转效果展示的具体代码,供大家参考,具体内容如下 css部分代码: .dice_box { width: 400px; height: 400px; position:relative;... -webkit-perspective-ori
  • CountVectorizer参数学习

    2021-01-21 16:39:09
    指定vocabulary,此时tokenizer/token_...  其中CountVectorizer中的fit_transform的源代码如下所示,需要重点关注的是 self._validate_vocabulary()和self.count_vocab(raw_documents,self.fixed_vocabulary) def fi
  • 猫狗大战学习笔记:

    2021-09-09 13:39:51
    # ori_path移到当前目录并命名为des_path for i,file in enumerate(cat_file): ori_path = os.path.join(root,'train',file) if i *len(cat_file): des_path = os.path.join(root,'train','cat') else: des_path = ...
  • 数字图像处理与Python实现笔记之频域滤波

    千次阅读 多人点赞 2020-07-28 16:15:54
    ch() def show(ori_func, sampling_period=5): n = len(ori_func) interval = sampling_period / n # 绘制原始函数 plt.subplot(2, 1, 1) plt.plot(np.arange(0, sampling_period, interval), ori_func, 'black') ...
  • 背景说明 可以说在分析机器学习的数据源中最常见的知识发现主题是把数据对象或事件转换为... ori_content=read_file(os.path.join(ori_subdir_path,ori_file)) #对换行符进行替换 ori_content.replace( '\r\n'...
  • public Transform lightTransform; private Material godRayVolumeMateril; void Awake() { var renderer = GetComponentInChildren(); foreach(var mat in renderer.sharedMaterials) ...
  • 数据集成:完成数据的抽取、清洗、转换和加载任务,数据源中的数据采用ETL(Extract-Transform-Load)工具以固定的周期加载到数据仓库中。 数据存储和管理:此层次主要涉及对数据的存储和管理,含数据仓库、数据...
  • final_score = 0 best_score_threshold = 0 EPO = 15 WEIGHTS = '../input/yolo52/last_yolov5x_fold0.pt' CONFIG = '../input/ttt112/yolo5_ori.yaml' DATA = '../input/configyolo5/wheat0.yaml' is_TEST = len(os...
  • //bool x = tfBuffer.canTransform( base_frame_id,laser_frame_id,timeout, nullptr); //rate.sleep(); base2laserTrans = tfBuffer.lookupTransform( base_frame_id,laser_frame_id,ros::Time(0)); }catch (tf2::...
  • data_x =pd.DataFrame(KNN(k=6).fit_transform(train_data_x), columns=features) 2. 噪声数据 剔除噪声在数据预处理当中也非常重要,在kaggle最近在比的ieee中,剔除噪声数据非常重要。 对于模型预测非常重要 主要...
  • 图像旋转后的还原图像坐标

    千次阅读 2016-04-02 14:12:44
    float x_ori, y_ori; float x_tmp, y_tmp; float x1 = *x0; float y1 = *y0; Rtheta = Rtheta*CV_PI/180; if ( Rtheta ) { x_ori = 0; y_ori = w1 * sin(Rtheta) / t1; } else { x_ori = -w1 * cos...
  • ++i) { uchar average = (ori.at(j, i)[0] + ori.at(j, i)[1] + ori.at(j, i)[2]) / 3; if (average > threshold) average = 255; else average = 0; srcMat.at(j, i)[0] = average; src...
  • Unity Shader-描边效果

    万次阅读 多人点赞 2017-01-15 16:00:58
    //通过TRANSFORM_TEX宏转化纹理坐标,主要处理了Offset和Tiling的改变,默认时等同于o.uv = v.texcoord.xy; o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); o.worldNormal = mul(v.normal, (float3x3)_...
  • - Transform the image using \f$H'\f$ as a look-up table: \f$\texttt{dst}(x,y) = H'(\texttt{src}(x,y))\f$ The algorithm normalizes the brightness and increases the contrast of the image. @param src ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 895
精华内容 358
关键字:

oritransform