精华内容
下载资源
问答
  • 要说明这个问题主要从感受野的角度去看,one stage的方法,对于SSD,其采取多个特征图进行分类,但由于依赖网络中比较深的层(特征层),感受野很大,因而小物体检测不准确。同样,对于YOLO,由于在方法设计中就把原...
  • Pipeline Stage View插件在Flow Project的索引页面的Stage View下,包括对管道构建历史记录的扩展可视化。 (您也可以单击“完整舞台视图”以获取全屏视图。) 要利用此视图,您需要在流程中定义阶段。 您可以按照...
  • e-stage 6.6

    2020-11-20 17:37:33
    制作3d模型支撑时,必备工具。 3D打印机的完美搭配,Materialise Magics。 3D打印magics 21对接e-stage 6.6实现一键自动加支撑
  • 由于广泛的应用和技术上的突破,目标检测(object detection)在近些年吸引了越来越多的注意力,以飞快的速度发展着。在导致目标检测领域飞速发展的众多因素中,深度卷积神经网络和GPU算力无疑占据着重要的地位。...
  • gentoo-stage4 目录 主意 我们所有人都知道,与任何其他发行版相比,安装Gentoo会花费一些时间。 在过去的几年中,我一直通过自动安装程序脚本进行安装,该过程需要花费几分钟,但是在每次安装时都会进行一些重复...
  • E-Stage 6.6.rar

    2020-08-11 10:45:12
    Magices的加支撑插件,网上很难获取到资源,博主重金买了份,和大家分享,5积分的资源,便宜实惠,谢谢观众老爷捧场。
  • Stage划分算法原理剖析
  • STAGE TEN Connect上参与实况广播时,请使用屏幕共享作为源。 在STAGE TEN中共享计算机的屏幕作为实时信号源。 显示演示文稿,游戏供稿,照片或屏幕上的任何内容。 第十阶段可让您在一个简单的Web应用程序中利用...
  • buildstage交互脚本

    2018-12-20 23:21:06
    Oracle E-Business Suite 12.2.0 安装时,在执行 builstage.sh 时的交互脚本参考
  • JavaFX+Jfoenix 学习笔记(二)--Stage和Scene文章中用到的源码,主要是展示了Stage的一些常用属性
  • stagefright实例,主要讲述android的多媒体架构
  • 2019年6月思科新推出的合作伙伴认证考试,Black Belt ACI Deployment - Stage1 题库
  • Pardoe的论文“回归传递的提升(ICML 2010)”中的两阶段TrAdaBoost.R2算法 描述 这是Pardoe等人提出的基于Boost的回归任务转移学习算法... 第一类Stage2_TrAdaBoostR2是sklearn软件包中AdaBoostRe
  • 尝试同时使用babel-preset-react-native和babel-preset-stage-0时,您在React Native中遇到奇怪的错误吗? 对于使用RN上最新和最出色的Babel功能有多么困难,您是否通常感到困惑和沮丧? 该预设适合您! 安装 npm ...
  • 基于深度学习One-stage方法的焊缝缺陷智能识别研究.pdf
  • Stage-源码

    2021-03-05 17:53:17
    Stage
  • Hydro 上用于 IGVC Stage_ros 的 ROS Stage World 目前支持相机(对于 ROS Fuerte,请查看 stageroscam Fuerte 分支) 在 ROS Hydro 上测试 不使用 wstool 安装 cd ~/catkin_ws/src git clone ...
  • 国际优质教学资源:ROS下Stage仿真器以及TF详解PPT(含例程代码),通俗易懂。
  • weblogic部署方式nostage和stage优劣对比(英文版) weblogic部署方式nostage和stage优劣对比(英文版) weblogic部署方式nostage和stage优劣对比(英文版)
  • serverless plugin install --name serverless-stage-manager 使用npm安装 使用npm安装模块: npm install serverless-stage-manager --save-dev 将serverless-stage-manager添加到serverless.yml文件的插件列表中...
  • Laya Stage

    2019-09-20 00:03:18
    Laya.stage 是 Laya 全局类的属性,是使用单例访问 laya.display.Stage 舞台类的对象,舞台类是显示列表的根节点,所有显示对象都在舞台上显示。 结构 描述 Package laya.display Class Laya.Stage ...

    舞台是显示游戏元素的平台,在游戏视觉编程中,一切游戏的元素必须添加到舞台才能被显示。因此,舞台是放置对象的最终容器。舞台自身也是一种可以显示的对象,从编程角度来讲,任何对象都具有属性和行为。

    • 舞台提供适配模式,不同适配模式产生不同大小的画布,画布越大渲染压力越大。
    • 舞台提供不同的帧率模式,帧率越高渲染压力越大,也越耗电。

    环境

    • 操作系统:Windows10
    • 引擎版本:LayaAir2.2.0beta4
    • 编程语言:ES6

    舞台

    Laya是全局对象的引入入口类,Laya类引用常用全局对象。舞台可通过 Laya 类的 stage 属性 Laya.stage 单例访问。

    属性含义
    Laya.stage单例访问,获取舞台 laya.display.Stage 对象的引用。

    Laya.stage 是 Laya 全局类的属性,是使用单例访问 laya.display.Stage 舞台类的对象,舞台类是显示列表的根节点,所有显示对象都在舞台上显示。

    结构描述
    Packagelaya.display
    ClassLaya.Stage
    InheritanceStage / Sprite / Node / EventDispatcher / Object

    初始化引擎

    Laya.init()初始化引擎,使用引擎前需要先初始化引擎,否则可能会报错。

    $ vim ./libs/LayaAir.d.ts
    
    /*
    * 初始化引擎。使用引擎需要先初始化引擎,否则可能会报错。
    * @param width 初始化的游戏窗口宽度,又称设计宽度。
    * @param height 初始化的游戏窗口高度,又称设计高度。
    * @param plugins 插件列表,比如 WebGL(使用WebGL方式渲染)。
    * @return 返回原生canvas引用,方便对canvas属性进行修改
    */
    static init(width:number,height:number,...plugins:any[]):any;
    

    例如:根据IDE设置初始化引擎

    if (window["Laya3D"]){
        Laya3D.init(GameConfig.width, GameConfig.height);
    }else{
        Laya.init(GameConfig.width, GameConfig.height, Laya["WebGL"]);
    } 
    

    例如:使用默认的Canvas渲染引擎

    //创建舞台,尺寸以iPhone5宽高1136x640为基准,16:9标准。
    const width = 1136;
    const height = 640;
    const canvas = Laya.init(width, height);
    console.log(Laya.stage.width, Laya.stage.height);//1136 640
    console.log(convas);// <canvas id="layaCanvas" width="1136" height="640" style="position: absolute; left: 0px; top: 0px; background: rgb(35, 35, 142); transform-origin: 0px 0px 0px; transform: matrix(0.5, 0, 0, 0.5, 0, 0);"></canvas>
    

    例如:使用WebGL渲染引擎

    注意使用WebGL渲染引擎时,需要在项目中提前将laya.webgl.js类库导入,在编辑模式下使用【F9】打开项目设置,勾选类库设置中的laya.webgl.js

    //创建舞台,尺寸以iPhone5宽高1136x640为基准,16:9标准。
    const width = 1136;
    const height = 640;
    const webgl = Laya.init(width, height, Laya.WebGL);
    console.log(webgl);
    

    宽高

    LayaAir中的宽高可以分为以下几种类型:

    宽高描述
    Laya.Stage.width / Laya.Stage.height舞台实际宽高
    Laya.Stage.designWidth / Laya.Stage.designHeight舞台设计宽高
    Laya.Browser.clientWidth / Laya.Browser.clientHeight设备屏幕宽高
    Laya.Browser.width / Laya.Browser.height设备物理宽高

    设计宽高

    设计分辨率是内容产生者在制作场景时使用的分辨率蓝本,屏幕分辨率则是游戏在设备上运行时的实际屏幕显示分辨率。通常设计分辨率会采用市场目标群体中使用率最高的设备的屏幕分辨率,比如目前在Android设备中 800 x 4001280 x 720两种屏幕分辨率,或iOS设备中1136 x 640960 x640两种屏幕分辨率。

    设计宽高是LayaAir引擎初始化时设置的宽高

    //引擎初始化
    Laya.init(designWidth, designHeight);
    //获取设计宽高
    console.log(Laya.Stage.designWidth);
    console.log(Laya.Stage.designHeight);
    

    舞台宽高

    游戏舞台实际大小的宽高

    Laya.stage.width;
    
    Laya.stage.height;
    

    适配宽高

    通过引擎适配模式scaleMode对设计宽高缩放后的宽高。

    画布宽高

    HTML5中Canvas节点的宽高,游戏中所有可见内容都在画布区域内。

    早期的移动设备中,屏幕分辨率较低,比如iPhone3的分辨率为320 x 480,此时一个“像素”等于一个屏幕物理像素。随着设备屏幕像素密度越来越高,从iPhone4开始Apple开始推出Retina屏,分辨率提高到了640 x 960,也就是说分辨率提高了一倍,但设备屏幕尺寸并没有变化,这就意味着同样面积大小的屏幕上,像素却多了一倍,这提高的也就是设备像素比devicePixelRatio

    在LayaAir中可以通过Laya.Browser.pixelRatio获取设备像素比。

    //获取设备像素比
    const pixelRatio = Laya.Browser.pixelRatio;
    

    屏幕宽高

    手机浏览器屏幕的宽高即设备像素分辨率 ,比如iPhone6竖屏宽高为376x667。

    //获取手机浏览器屏幕宽高
    const clientWidth = laya.utils.Browser.clientWidth;
    //const clientWidth = Laya.Browser.clientWidth;
    
    const clientHeight = laya.utils.Browser.clientHeight;
    //const clientHeight = Laya.Browser.clientHeight;
    

    默认从Browser浏览器上获得clientWidthclientHeight并不是像素分辨率,而是经过缩放后的分辨率。如果想要获得正确的像素分辨率,则需要在HTML文件中设置视区的宽度为设备宽度且不缩放。

    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scale=no" />
    

    物理宽高

    手机屏幕窗口的实际宽高,平时比较常用的一般是设备物理分辨率,它代表着浏览器窗口的实际分辨率。

    //获取手机屏幕窗口的实际宽高
    //const browserWidth = laya.utils.Browser.width;
    const deviceWidth = Laya.Browser.width;
    
    //const browserHeight = laya.utils.Browser.height;
    const deviceHeight = Laya.Browser.height;
    

    例如:

    //创建舞台,尺寸以iPhone5宽高1136x640为基准,16:9标准。
    const designWidth = 1136;//设计宽度
    const designHeight = 640;//设计高度
    const canvas = Laya.init(designWidth, designHeight);
    //设置缩放模式
    //Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;//最小比例缩放,缩放后全部都在屏幕内,但可能会出现黑边。
    Laya.stage.scaleMode = Laya.Stage.SCALE_NOBORDER;//最大比例缩放,缩放后全屏幕显示无黑边,但可能有部分显示在屏幕外边。
    
    //获取设备像素比
    const pixelRatio = Laya.Browser.pixelRatio;
    console.log(`pixelRatio = ${pixelRatio}`);//pixelRatio = 2
    //获取设备像素分辨率即屏幕宽高
    const clientWidth = Laya.Browser.clientWidth;
    const clientHeight = Laya.Browser.clientHeight;
    console.log(`clientWidth = ${clientWidth}`, `clientHeight = ${clientHeight}`);//clientWidth = 667 clientHeight = 375
    //获取设备物理分辨率即物理宽高
    const width = Laya.Browser.width;
    const height = Laya.Browser.height;
    console.log(`width = ${width}`, `height = ${height}`);//width = 1334 height = 750
    
    4933701-3a7293349757db28.png
    LayaAir中的宽高

    对齐模式

    属性描述
    Laya.stage.alignH横向水平对齐
    Laya.stage.alignV纵向垂直对齐

    Laya.stage.alignH 舞台横向对齐 分为左中右

    水平对齐描述
    Laya.stage.alignH = Laya.Stage.ALIGN_LEFT;设置舞台水平居左对齐
    Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;设置舞台水平居中对齐
    Laya.stage.alignH = Laya.Stage.ALIGN_RIGHT;设置舞台水平居右对齐

    Laya.stage.alignV 舞台纵向对齐 分为上中下

    垂直对齐描述
    Laya.stage.alignV= Laya.Stage.ALIGN_TOP;设置舞台垂直居上对齐
    Laya.stage.alignV= Laya.Stage.ALIGN_MIDDLE;设置舞台垂直居中对齐
    Laya.stage.alignV= Laya.Stage.ALIGN_BOTTOM;设置舞台垂直居下对齐

    例如:设置舞台或画布水平居中显示

    class Test {
        constructor() {
            Laya.init(Laya.Browser.clientWidth, Laya.Browser.clientHeight, Laya.WebGL);
            this.initStage();
            this.run();
        }
        initStage(){
            this.setStageAlign("center", "middle");
            Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;
            Laya.stage.bgColor = "#000000";
        }
        setStageAlign(h, v){
            h = h.toLowerCase();
            if(h == "left"){
                Laya.stage.alignH = Laya.Stage.ALIGN_LEFT;
            }else if(h == "center"){
                Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;
            }else if(h == "right"){
                Laya.stage.alignH = Laya.Stage.ALIGN_RIGHT;
            }
            v = v.toLowerCase();
            if(v == "top"){
                Laya.stage.alignV = Laya.Stage.ALIGN_TOP;
            }else if(v == "middle"){
                Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;
            }else if(v == "bottom"){
                Laya.stage.alignV = Laya.Stage.ALIGN_BOTTOM;
            }
        }
        run(){
            console.log(Laya.stage.width, Laya.stage.height);//414 736
            console.log(Laya.stage.clientWidth, Laya.stage.clientHeight);//undefined undefined
            console.log(Laya.Browser.width, Laya.Browser.height);//1242 2208
            console.log(Laya.Browser.clientWidth, Laya.Browser.clientHeight);//414 736
        }
    }
    //启动
    new Test();
    

    屏幕模式

    LayaAir可以根据浏览器显示的比例设置自动横屏或竖屏,不会受到锁屏而影响。简单来说,LayaAir的屏幕方向是智能适配设置的。改变LayaAir的屏幕方向并不会改变操作系统的的屏幕方向,因此LayaAir的屏幕方向不会受到操作系统屏幕方向的影响。

    属性描述
    Laya.stage.screenMode = Laya.Stage.SCREEN_HORIZONTAL;自动横屏
    Laya.stage.screenMode = Laya.Stage.SCREEN_VERTICAL;自动竖屏
    • 设置自动横屏后,游戏的方向会始终与舞台较长的边保持垂直。
    • 设置自动竖屏后,游戏的方向会始终与舞台较短的边保持垂直。

    例如:使用新窗口打开,拖动改变浏览器尺寸查看自动横屏效果。

    class Test {
        constructor() {
            //初始化引擎
            Laya.init(Laya.Browser.clientWidth, Laya.Browser.clientHeight, Laya.WebGL);
            //初始化舞台
            this.initStage();
            //运行
            this.run();
        }
        /**初始化舞台*/
        initStage(){
            //设置舞台对齐方式
            this.setStageAlign("center", "middle");
            //设置舞台屏幕模式
            this.setStageScreen("horizontal");
            //设置舞台缩放模式
            Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;
            Laya.stage.bgColor = "#000000";
        }
        /**设置舞台屏幕模式 */
        setStageScreen(mode = "horizontal"){
            mode = mode.toLowerCase();
            if(mode == "horizontal"){
                Laya.stage.screenMode = Laya.Stage.SCREEN_HORIZONTAL;
            }else if(mode == "vertical"){
                Laya.stage.screenMode = Laya.Stage.SCREEN_VERTICAL;
            }
        }
        /**设置舞台对齐方式 */
        setStageAlign(h, v){
            h = h.toLowerCase();
            if(h == "left"){
                Laya.stage.alignH = Laya.Stage.ALIGN_LEFT;
            }else if(h == "center"){
                Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;
            }else if(h == "right"){
                Laya.stage.alignH = Laya.Stage.ALIGN_RIGHT;
            }
            v = v.toLowerCase();
            if(v == "top"){
                Laya.stage.alignV = Laya.Stage.ALIGN_TOP;
            }else if(v == "middle"){
                Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;
            }else if(v == "bottom"){
                Laya.stage.alignV = Laya.Stage.ALIGN_BOTTOM;
            }
        }
        run(){
            console.log(Laya.stage.width, Laya.stage.height);//414 736
            console.log(Laya.stage.clientWidth, Laya.stage.clientHeight);//undefined undefined
            console.log(Laya.Browser.width, Laya.Browser.height);//1242 2208
            console.log(Laya.Browser.clientWidth, Laya.Browser.clientHeight);//414 736
    
            console.log(Laya.stage.alignH, Laya.stage.alignV);//center middle
            console.log(Laya.stage.screenMode);//horizontal
        }
    }
    //启动
    new Test();
    

    缩放模式

    舞台提供不同的适配模式scaleMode,不同缩放模式下会产生不同的画布大小,画布越大,渲染压力也就越大。

    属性描述
    Laya.stage.scaleMode = Laya.Stage.NOSCALE;noscale不缩放
    Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;showall最小比例缩放
    Laya.stage.scaleMode = Laya.Stage.SCALE_EXACTFIT;exactfit全屏不等比缩放
    Laya.stage.scaleMode = Laya.Stage.SCALE_NOBORDER;noborder无框缩放 最大比例缩放
    Laya.stage.scaleMode = Laya.Stage.SCALE_FULL;full全屏缩放 舞台宽高等于屏幕宽高
    Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_WIDTH;fixedwidth宽度固定 宽度不变 高度根据屏幕比缩放
    Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_HEIGHT;fixedheight高度固定 高度不变 宽度根据屏幕比缩放
    Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_AUTO;fixedauto自动选择 根据宽高比自动使用fixedwidth或fixedheight
    class Test {
        constructor() {
            //初始化引擎
            Laya.init(Laya.Browser.clientWidth, Laya.Browser.clientHeight, Laya.WebGL);
            //初始化舞台
            this.initStage();
            //运行
            this.run();
        }
        /**初始化舞台*/
        initStage(){
            //设置舞台对齐方式
            this.setStageAlign("center", "middle");
            //设置舞台屏幕模式
            this.setStageScreen("horizontal");
            //设置舞台缩放模式
            this.setStageScale("showall");
    
            Laya.stage.bgColor = "#000000";
        }
        /**设置舞台缩放模式 */
        setStageScale(mode){
            mode = mode.toLowerCase();
            if(mode == "noscale"){
                //不缩放
                Laya.stage.scaleMode = Laya.Stage.SCALE_NOSCALE;
            }else if(mode == "showall"){
                //显示所有 最小比例缩放
                Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;
            }else if(mode == "exactfit"){
                //全屏不等比缩放
                Laya.stage.scaleMode = Laya.Stage.SCALE_EXACTFIT;
            }else if(mode == "noborder"){
                //无框缩放 最大比例缩放
                Laya.stage.scaleMode = Laya.Stage.SCALE_NOBORDER;
            }else if(mode == "full"){
                //全屏缩放 舞台宽高等于屏幕宽高
                Laya.stage.scaleMode = Laya.Stage.SCALE_FULL;
            }else if(mode == "fixedwidth"){
                //宽度固定 宽度不变 高度根据屏幕比缩放
                Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_WIDTH;
            }else if(mode == "fixedheight"){
                //高度固定 高度不变 宽度根据屏幕比缩放
                Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_HEIGHT;
            }else if(mode == "fixedauto"){
                //自动选择 根据宽高比自动选择使用fixedwidth或fixedheight
                Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_AUTO;
            }
        }
        /**设置舞台屏幕模式 */
        setStageScreen(mode = "horizontal"){
            mode = mode.toLowerCase();
            if(mode == "horizontal"){
                Laya.stage.screenMode = Laya.Stage.SCREEN_HORIZONTAL;
            }else if(mode == "vertical"){
                Laya.stage.screenMode = Laya.Stage.SCREEN_VERTICAL;
            }
        }
        /**设置舞台对齐方式 */
        setStageAlign(h, v){
            h = h.toLowerCase();
            if(h == "left"){
                Laya.stage.alignH = Laya.Stage.ALIGN_LEFT;
            }else if(h == "center"){
                Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;
            }else if(h == "right"){
                Laya.stage.alignH = Laya.Stage.ALIGN_RIGHT;
            }
            v = v.toLowerCase();
            if(v == "top"){
                Laya.stage.alignV = Laya.Stage.ALIGN_TOP;
            }else if(v == "middle"){
                Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;
            }else if(v == "bottom"){
                Laya.stage.alignV = Laya.Stage.ALIGN_BOTTOM;
            }
        }
        run(){
            console.log(Laya.stage.width, Laya.stage.height);//414 736
            console.log(Laya.stage.clientWidth, Laya.stage.clientHeight);//undefined undefined
            console.log(Laya.Browser.width, Laya.Browser.height);//1242 2208
            console.log(Laya.Browser.clientWidth, Laya.Browser.clientHeight);//414 736
    
            console.log(Laya.stage.alignH, Laya.stage.alignV);//center middle
            console.log(Laya.stage.screenMode);//horizontal
            console.log(Laya.stage.scaleMode);//showall
        }
    }
    //启动
    new Test();
    

    例如:舞台中心添加精灵图,查看不同缩放模式下的效果。

    //创建舞台
    const designWidth = 400;//设计宽度
    const designHeight = 300;//设计高度
    const canvas = Laya.init(designWidth, designHeight);
    //设置舞台背景颜色
    Laya.stage.bgColor = "black";
    //设置舞台水平对齐
    Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;//水平居中
    //设置舞台垂直对齐
    Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;//垂直居中
    //设置舞台缩放模式
    Laya.stage.scaleMode = Laya.Stage.SCALE_EXACTFIT;//缩放显示所有
    //设置舞台屏幕模式
    Laya.stage.screenMode = Laya.Stage.SCREEN_HORIZONTAL;//自动横屏
    
    //创建精灵
    let sprite = new Laya.Sprite();
    //精灵图绘制黄色矩形
    sprite.graphics.drawRect(-100, -100, 200, 200, "gray");
    //向舞台中添加精灵节点
    Laya.stage.addChild(sprite);
    //设置精灵在舞台中的坐标位置
    sprite.x = Laya.stage.width >> 1;
    sprite.y = Laya.stage.height >> 1;
    
    • SCALE_EXACTFIT 伸缩适应

    Exact Fix模式是不考虑内容的原始比例,直接通过非等比缩放填满整个浏览器屏幕的模式。在此种模式下,画布宽高与舞台宽高都等同于设计宽高,而且不会发生改变。但当物理宽高与设计宽高不相同时,这种非等比的缩放可能会导致原有设计明显缺陷。

    整个应用程序在指定区域中可见,但不尝试保持原始宽高比,可能会发生扭曲,应用程序可能会拉伸或压缩显示。


    4933701-0fda64bfde51fbe5.png
    SCALE_EXACTFIT
    • SCALE_NOBORDER 无边框

    No Border无边框模式下,画布宽高等同于设计宽高。当缩放时,按照屏幕宽高与设计宽高最大比率的一方进行缩放。

    比如设计尺寸为1136x640,屏幕物理宽高为750x1334,经过计算得到宽的比例为750/1136=0.66,高的比例1334/640=2.08,按照最大比例一方将适配拉伸至物理高度的1334,适配宽度等比拉升 1334/640*1136=2368,此时超出屏幕宽度的部分将会被自动裁剪掉。

    整个应用程序填满指定区域,不会发生扭曲,但有可能进行一些裁剪,同时保持应用程序的原始宽高比。

    • SCALE_NOSCALE 不缩放

    No Scale不缩放模式下,画布与舞台的宽高等同于设计宽高,并在保持1:1原始设计比例的基础上,将舞台与浏览器屏幕左上角对齐。当屏幕宽高小于内容时将进行裁切,当屏幕宽高大于内容时则会出现黑边。

    整个应用程序大小固定,即使播放器窗口大小更改,应用程序也会保持不变。如果播放器窗口比内容小,则可能进行裁剪。

    • SCALE_SHOWALL 显示所有

    Show All显示所有模式下,舞台与画布的宽高等同于缩放后的适配宽高,缩放按照屏幕宽高与设计宽高最小比率一方进行等比缩放。

    比如设计尺寸为1136x640,屏幕物理宽高为750 x 1334,通过计算得到宽的比率为 750 / 1136 = 0.66,高的比率为 1334 / 640 = 2.08。按照最小比率一方即宽为基准,画布宽高会被缩放为屏幕的物理宽度750,适配高度经过等比缩放 750 / 1136 * 640 = 423,由于423远远小于屏幕物理高度1134,因此会出现大量留黑的空屏。

    整个应用程序在指定区域中可见,不会发生扭曲,同时保持应用程序的原始宽高比,应用程序两侧可能会显示边框。

    查看默认缩放模式

    //创建舞台,尺寸以iPhone5宽高1136x640为基准,16:9标准。
    const width = 1136;
    const height = 640;
    const canvas = Laya.init(width, height);
    console.log(Laya.stage.scaleMode);//noscale
    

    设置缩放模式

    //创建舞台,尺寸以iPhone5宽高1136x640为基准,16:9标准。
    const designWidth = 1136;//设计宽度
    const designHeight = 640;//设计高度
    const canvas = Laya.init(designWidth, designHeight);
    //设置缩放模式
    Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;//最小比例缩放,缩放后全部都在屏幕内,但可能会出现黑边。
    //Laya.stage.scaleMode = Laya.Stage.SCALE_NOBORDER;//最大比例缩放,缩放后全屏幕显示无黑边,但可能有部分显示在屏幕外边。
    console.log(Laya.stage.scaleMode);//showall
    

    自动计算

    Laya.stage.autoSize = false;
    

    由于Stage舞台类继承自Sprite精灵类,Sprite精灵类提供了autoSize属性,用于指定是否自动计算宽高数据,默认为 false。默认Sprite精灵宽高为0,不会随着绘制内容的变化而变化。如果想要根据绘制内容获取宽高,可以设置autoSize=true,或者通过getBounds()方法获取。不过开启autoSize后会对性能有一定影响。

    帧率类型

    Laya.stage.frameRate = Laya.Stage.FRAME_SLOW;
    

    Laya 的 Stage 舞台类提供了 frameRate 存取器,用于获取和设置舞台的帧率类型。

    帧率类型类型默认值描述
    Laya.Stage.FRAME_FASTstringfase全速模式,以60FPS的帧率运行。
    Laya.Stage.FRAME_SLOWstringslow慢速模式,以30FPS的帧率运行。
    Laya.Stage.FRAME_MOUSEstringmouse自动模式,以30FPS的帧率运行,鼠标活动后会自动加速到60FPS,鼠标不动2秒后降低为30FPS,以节省性能。
    Laya.Stage.FRAME_SLEEPstringsleep休眠模式,以1FPS的帧率运行。

    FPS是画面每秒传输帧数(Frames Per Second),是指动画或视频的画面数(帧数)。FPS是用测量用于保存、显示动态视频的信息数量,秒条帧数越多所显示的动作就越流畅。通常要避免动作不流程的最低FPS是30。

    FPS可理解为刷新率,单位Hz,比如装机选购显卡和显示器时默认刷新率都在75Hz以上,75Hz的刷新率表示屏幕1秒内扫描75次。当刷新率太低时肉眼会感觉到屏幕闪烁且不连贯,对图像显示效果和视觉感观不好。

    电影以每秒24张画面的速度播放,一秒内在屏幕上连续投射出24张静止画面。游戏中一般人能接受的最低FPS为30Hz,基本流畅等级则需要高于50Hz。

    常见媒体的FPS帧率

    媒体FPS帧率
    电影24FPS
    电视 PAL25FPS
    电视 NTSC30FPS
    CRT 显示器75Hz
    液晶显示器60Hz

    显示分辨率不变的情况下,FPS刷新率越高对显卡的处理能力要求越高,计算机中所显示的画面都是由显卡输出的,屏幕上每个像素的填充都是由显卡计算输出的,当画面的分辨率为1024 x 768 时,画面的刷新率达到 24FPS,显卡在一秒钟内需要处理的像素就需要达到 1024 x 768 x24 = 18874368。FPS与分辨率和显卡处理能力的关系:显卡处理能力 = 分辨率 x 刷新率。

    当前PC与手机等移动设备的满帧为60帧,如果游戏对画面的流畅度要求不高可采用Laya引擎的帧数限制方法Laya.Stage.FRAME_SLOW将FPS帧数限制为最高30帧。

    Laya项目由于实际运行环境是在浏览器中,所以性能还取决于JavaScript解释器的效率,对此同一款游戏的FPS在不同的浏览器中可能会存在不同的差异。这部分不是开发者能够决定的,开发者能作的尽可能使用更好的引擎和游戏项目,争取在低端设备和低性能浏览器中提升FPS帧率。

    Laya引擎支持Canvas和WebGL两种渲染模式,因此在查看FPS帧率时需要注意当前引擎在哪种渲染模式下。

    封装

    TypeScript封装舞台工具类

    /**
     * 舞台工具类
     */
    export default class Stage{
        //单例模式
        private static _instance:Stage;
        public static getInstance():Stage{
            if(!this._instance){
                this._instance = new Stage();
            }
            return this._instance;
        }
        private constructor(){}
        /**
         * 舞台初始化
        */
       init(width:number=1334, height:number=750, isWebGL:boolean=false, isStat:boolean=false):void{
            //引擎渲染方式
            if(isWebGL){
                Laya.init(width, height, Laya.WebGL);//指定WebGL
            }else{
                Laya.init(width, height);//默认Canvas
            }
            //是否显示统计信息
            if(isStat){
                Laya.Stat.show();
            }
            //自动计算
            Laya.stage.autoSize = false;//开启后影响性能
            //帧率类型
            Laya.stage.frameRate = Laya.Stage.FRAME_SLOW;//30帧
            //对齐方式
            Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;//水平居中
            Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;//垂直居中
            //屏幕模式
            Laya.stage.screenMode = Laya.Stage.SCREEN_HORIZONTAL;//横屏
            //缩放模式
            Laya.stage.scaleMode = Laya.Stage.SCALE_FIXED_AUTO;
            //背景颜色
            Laya.stage.bgColor = "#808080";
       }
    }
    
    展开全文
  • one-stage和two-stage目标检测算法

    千次阅读 2019-08-26 22:41:31
    目前目标检测领域的深度学习方法主要分为两类:two stage 的目标检测算法;one stage 的目标检测算法。前者是先由算法生成一系列作为样本的候选框,再通过卷积神经网络进行样本分类;后者则不用产生候选框,直接将...

    AI 科技评论按:本文作者 Ronald,首发于作者的知乎专栏「炼丹师备忘录」,AI 科技评论获其授权转发。

    目前目标检测领域的深度学习方法主要分为两类:two stage 的目标检测算法;one stage 的目标检测算法。前者是先由算法生成一系列作为样本的候选框,再通过卷积神经网络进行样本分类;后者则不用产生候选框,直接将目标边框定位的问题转化为回归问题处理。正是由于两种方法的差异,在性能上也有不同,前者在检测准确率和定位精度上占优,后者在算法速度上占优。

    1. two stage 的方法

    在早期深度学习技术发展进程中,主要都是围绕分类问题展开研究,这是因为神经网络特有的结构输出将概率统计和分类问题结合,提供一种直观易行的思路。国内外研究人员虽然也在致力于将其他如目标检测领域和深度学习结合,但都没有取得成效,这种情况直到 R-CNN 算法出现才得以解决。

    1.1 R-CNN

    2014 年加州大学伯克利分校的 Ross B. Girshick 提出 R-CNN 算法,其在效果上超越同期的 Yann Lecun 提出的端到端方法 OverFeat 算法,其算法结构也成为后续 two stage 的经典结构。R-CNN 算法利用选择性搜索(Selective Search)算法评测相邻图像子块的特征相似度,通过对合并后的相似图像区域打分,选择出感兴趣区域的候选框作为样本输入到卷积神经网络结构内部,由网络学习候选框和标定框组成的正负样本特征,形成对应的特征向量,再由支持向量机设计分类器对特征向量分类,最后对候选框以及标定框完成边框回归操作达到目标检测的定位目的。虽然 R-CNN 算法相较于传统目标检测算法取得了 50%的性能提升,但其也有缺陷存在:训练网络的正负样本候选区域由传统算法生成,使得算法速度受到限制;卷积神经网络需要分别对每一个生成的候选区域进行一次特征提取,实际存在大量的重复运算,制约了算法性能。

    1.2 SPP-Net

    针对卷积神经网络重复运算问题,2015 年微软研究院的何恺明等提出一种 SPP-Net 算法,通过在卷积层和全连接层之间加入空间金字塔池化结构(Spatial Pyramid Pooling)代替 R-CNN 算法在输入卷积神经网络前对各个候选区域进行剪裁、缩放操作使其图像子块尺寸一致的做法。利用空间金字塔池化结构有效避免了 R-CNN 算法对图像区域剪裁、缩放操作导致的图像物体剪裁不全以及形状扭曲等问题,更重要的是解决了卷积神经网络对图像重复特征提取的问题,大大提高了产生候选框的速度,且节省了计算成本。但是和 R-CNN 算法一样训练数据的图像尺寸大小不一致,导致候选框的 ROI 感受野大,不能利用 BP 高效更新权重。

    1.3 Fast R-CNN

    针对 SPP-Net 算法的问题,2015 年微软研究院的 Ross B. Girshick 又提出一种改进的 Fast R-CNN 算法,借鉴 SPP-Net 算法结构,设计一种 ROI pooling 的池化层结构,有效解决 R-CNN 算法必须将图像区域剪裁、缩放到相同尺寸大小的操作。提出多任务损失函数思想,将分类损失和边框回归损失结合统一训练学习,并输出对应分类和边框坐标,不再需要额外的硬盘空间来存储中间层的特征,梯度能够通过 RoI Pooling 层直接传播。但是其仍然没有摆脱选择性搜索算法生成正负样本候选框的问题。

    1.4 Faster R-CNN

    为了解决 Fast R-CNN 算法缺陷,使得算法实现 two stage 的全网络结构,2015 年微软研究院的任少庆、何恺明以及 Ross B Girshick 等人又提出了 Faster R-CNN 算法。设计辅助生成样本的 RPN(Region Proposal Networks)网络,将算法结构分为两个部分,先由 RPN 网络判断候选框是否为目标,再经分类定位的多任务损失判断目标类型,整个网络流程都能共享卷积神经网络提取的的特征信息,节约计算成本,且解决 Fast R-CNN 算法生成正负样本候选框速度慢的问题,同时避免候选框提取过多导致算法准确率下降。但是由于 RPN 网络可在固定尺寸的卷积特征图中生成多尺寸的候选框,导致出现可变目标尺寸和固定感受野不一致的现象。

    1.5 MR-CNN

    2015 年巴黎科技大学提出 MR-CNN 算法,结合样本区域本身的特征,利用样本区域周围采样的特征和图像分割的特征来提高识别率,可将检测问题分解为分类和定位问题。

    分类问题由 Multi-Region CNN Model 和 Semantic Segmentation-Aware CNN Model 组成。前者的候选框由 Selective Search 得到,对于每一个样本区域,取 10 个区域分别提取特征后拼接,这样可以强制网络捕捉物体的不同方面,同时可以增强网络对于定位不准确的敏感性,其中 adaptive max pooling 即 ROI max pooling;后者使用 FCN 进行目标分割,将最后一层的 feature map 和前者产生的 feature map 拼接,作为最后的 feature map。

    为了精确定位,采用三种样本边框修正方法,分别为 Bbox regression、Iterative localization 以及 Bounding box voting。Bbox regression:在 Multi-Region CNN Model 中整幅图经过网路的最后一层卷积层后,接一个 Bbox regression layer,与 RPN 不同,此处的 regression layer 是两层 FC 以及一层 prediction layer,为了防止 Selective Search 得到的框过于贴近物体而导致无法很好的框定物体,将候选框扩大为原来的 1.3 倍再做。Iterative localization:初始的框是 Selective Search 得到的框,然后用已有的分类模型对框做出估值,低于给定阈值的框被筛掉,剩下的框用 Bbox regression 的方法调整大小,并迭代筛选。Bounding box voting:首先对经过 Iterative localization 处理后的框应用 NMS, IOU = 0.3,得到检测结果,然后对于每一个框,用每一个和其同一类的而且 IOU >0.5 的框加权坐标,得到最后的目标样本框。

    1.6 HyperNet

    2016 年清华大学提出 HyperNet 算法,其利用网络多个层级提取的特征,且从较前层获取的精细特征可以减少对于小物体检测的缺陷。将提取到的不同层级 feature map 通过最大池化降维或逆卷积扩增操作使得所有 feature map 尺寸一致,并利用 LRN 正则化堆叠,形成 Hyper Feature maps,其具有多层次抽象、合适分辨率以及计算时效性的优点。接着通过 region proposal generation module 结构进行预测和定位,仅保留置信度最高的 N 个样本框进行判断。

    1.7 CRAFT

    R-CNN 系列算法的第一阶段是生成目标 proposals,第二阶段是对目标 proposals 进行分类,2016 年中科院自动化所提出的 CRAFT 算法分别对 Faster R-CNN 中的这两个阶段进行了一定的改进。对于生成目标 proposals 阶段,在 RPN 的后面加了一个二值的 Fast R-CNN 分类器来对 RPN 生成的 proposals 进行进一步的筛选,留下一些高质量的 proposals;对于第二阶段的目标 proposals 分类,在原来的分类器后又级联了 N 个类别(不包含背景类)的二值分类器以进行更精细的目标检测。

    1.8 R-FCN

    随着全卷积网络的出现,2016 年微软研究院的 Jifeng Dai 等提出 R-FCN 算法。相较于 Faster R-CNN 算法只能计算 ROI pooling 层之前的卷积网络特征参数,R-FCN 算法提出一种位置敏感分布的卷积网络代替 ROI pooling 层之后的全连接网络,解决了 Faster R-CNN 由于 ROI Pooling 层后面的结构需要对每一个样本区域跑一次而耗时比较大的问题,使得特征共享在整个网络内得以实现,解决物体分类要求有平移不变性和物体检测要求有平移变化的矛盾,但是没有考虑到 region proposal 的全局信息和语义信息。

    1.9 MS-CNN

    针对 Faster R-CNN 算法的遗留问题,2016 年加州大学圣地亚哥分校的 Z Cai提出了 MS-CNN 算法,通过利用 Faster R-CNN 算法结构的多个不同层级输出的特征结果来检测目标,将不同层级的检测器互补形成多尺度的强检测器,应用浅层特征检测小尺寸目标,应用深层特征检测大尺寸目标。并且利用去卷积层代替图像上采样来增加图像分辨率,减少内存占用,提高运行速度。

    1.10 PVANet

    针对的就是算法的运算速度提升问题,2016 年底 Intel 图像技术团队提出了一个轻量级的网络,取得了 state-of-the-art 的效果。PVANet 主要分为特征抽取网络和检测网络,基于多层少通道的基本原则,在网络浅层采用 C.ReLU 结构,在网络深层采用 Inception 模块,其中前者是将 K×K 卷积结构表示 1×1 - K×K - 1×1 的卷积层的堆叠,后者设计原则是由于为了检测图像中的大目标,需要足够大的感受野,可通过堆叠 3×3 的卷积核实现,但是为了捕获小目标,则需要小一点的感受野,可通过 1×1 的卷积核实现,且可以避免大卷积核造成的参数冗余问题。

    PVANet 应用多尺度特征级联最大化目标检测任务的多尺度性质,权重衰减策略采用一定迭代次数内 loss 不再下降,则将学习速率降低常数倍的方式,通过 batch normalization 和 residual 连接实现高效的训练。

    1.11 FPN

    2017 年 Facebook 的 Tsung-Yi Lin 等提出了 FPN 算法,利用不同层的特征图进行不同尺寸的目标预测。原来多数的目标检测算法都是只采用深层特征做预测,低层的特征语义信息比较少,但是目标位置准确;高层的特征语义信息比较丰富,但是目标位置比较粗略。另外虽然也有些算法采用多尺度特征融合的方式,但是一般是采用融合后的特征做预测,而 FPN 算法不一样的地方在于预测是在不同特征层独立进行的,利用深层特征通过上采样和低层特征做融合。

    FPN 算法主网络是 ResNet,结构主要是一个自底向上的线路横向连接一个自顶向下的线路。自底向上其实就是网络的前向过程,在前向过程中,feature map 的大小在经过某些层后会改变,而在经过其他一些层的时候不会改变,FPN 算法将不改变 feature map 大小的层归为一个 stage,因此每次抽取的特征都是每个 stage 的最后一个层输出,这样就能构成特征金字塔。自顶向下的过程采用上采样进行,而横向连接则是将上采样的结果和自底向上生成的相同大小的 feature map 并一一对应进行融合,在融合之后还会再采用 3×3 的卷积核对每个融合结果进行卷积,目的是消除上采样的混叠效应。

    1.12 Mask R-CNN

    为了解决 R-CNN 算法为代表的 two stage 的方法问题,2017 年 Facebook 的何恺明等提出了 Mask R-CNN 算法,取得了很好的识别效果。Mask R-CNN 算法将 ROI_Pooling 层替换成了 ROI_Align,并且在边框识别的基础上添加分支 FCN 层(mask 层),用于语义 Mask 识别,通过 RPN 网络生成目标候选框,再对每个目标候选框分类判断和边框回归,同时利用全卷积网络对每个目标候选框预测分割掩膜。加入的掩膜预测结构解决了特征图像和原始图像上的 ROI 不对准问题,避免对 ROI 边界做任何量化,而用双线性插值到对准特征,再用池化操作融合。掩膜编码了输入图像的空间布局,用全卷积网络预测每个目标候选框的掩膜能完整的保留空间结构信息,实现目标像素级分割定位。

    1.13 A-Fast-RCNN

    A-Fast-RCNN 算法是 2017 年卡内基梅隆大学提出的,其将对抗学习引入到目标检测问题中,通过对抗网络生成一下遮挡和变形的训练样本来训练检测网络,从而使得网络能够对遮挡和变形问题更加的鲁棒。使用对抗网络生成有遮挡和有形变的两种特征,两种网络分别为 ASDN 和 ASTN。

    ASDN 利用 Fast R-CNN 中 ROI 池化层之后的每个目标 proposal 卷积特征作为对抗网络的输入,给定一个目标的特征,ASDN 尝试生成特征某些部分被 dropout 的掩码,导致检测器无法识别该物体。在前向传播过程中,首先使用 ASDN 在 ROI 池化层之后生成特征掩码,然后使用重要性采样法生成二值掩码,使用该掩码将特征对应部位值清零,修改后的特征继续前向传播计算损失,这个过程生成了困难的特征,用于训练检测器。

    ASTN 主要关注特征旋转,定位网络包含三层全连接层,前两层是 ImageNet 预训练的 FC6 和 FC7,训练过程与 ASDN 类似,ASTN 对特征进行形变,将特征图划分为 4 个 block,每个 block 估计四个方向的旋转,增加了任务的复杂度。两种对抗网络可以相结合,使得检测器更鲁棒,ROI 池化层提取的特征首先传入 ASDN 丢弃一些激活,之后使用 ASTN 对特征进行形变。

    1.14 CoupleNet

    针对 R-FCN 算法没有考虑到 region proposal 的全局信息和语义信息的问题,2017 年中科院自动化所提出 CoupleNet 算法,其在原来 R-FCN 的基础上引入了 proposal 的全局和语义信息,通过结合局部、全局以及语义的信息,提高了检测的精度。

    CoupleNet 结构利用三支并行网络实现检测,上面的支路网络使用原本的 R-FCN 结构的位置敏感分布图提取目标的局部信息;中间的支路网络用于提取目标的全局信息,对于一个 region proposal,依次通过 K×K 的 ROI Pooling,K×K 的 conv 以及 1×1 的 conv;下面的支路网络用于提取目标的语义信息,对于一个 region proposal,首先选择以这个 proposal 为中心,面积是原来 2 倍的 proposal,同样依次通过 K×K 的 ROI Pooling,K×K 的 conv 以及 1×1 的 conv。最后先各自通过 1×1 的 conv 调整激活值的尺寸,然后把 Local FCN 和 Global FCN 结果对应位置元素相加,再通过一个 softmax 实现分类。

    1.15 MegDet

    基于 CNN 的物体检测研究一直在不断进步,从 R-CNN 到 Fast/Faster R-CNN,再 Mask R-CNN,主要的改进点都在于新的网络架构、新的范式、或者新的损失函数设计,然而 mini-batch 大小,这个训练中的关键因素并没有得到完善的研究。由于输入图片尺寸的增长,图像检测所需显存量也会同比例增长,这也使得已有的深度学习框架无法训练大 mini-batch 的图像检测模型,而小 mini-batch 的物体检测算法又常常会引入不稳定的梯度、BN 层统计不准确、正负样本比例失调以及超长训练时间的问题。因此,2017 年 12 月 Face++提出一种大 mini-batch 的目标检测算法 MegDet。

    MegDet 算法可以使用远大于以往的 mini-batch 大小训练网络(比如从 16 增大到 256),这样同时也可以高效地利用多块 GPU 联合训练(在论文的实验中最多使用了 128 块 GPU),大大缩短训练时间。同时解决了 BN 统计不准确的问题,也提出了一种学习率选择策略以及跨 GPU 的 Batch Normalization 方法,两者共同使用就得以大幅度减少大 mini-batch 物体检测器的训练时间(比如从 33 小时减少到仅仅 4 个小时),同时还可以达到更高的准确率。

    1.16 Light-Head R-CNN

    2017 年 12 月 Face++提出了一种为了使 two stage 的检测算法 Light-Head R-CNN,主要探讨了 R-CNN 如何在物体检测中平衡精确度和速度。Light-Head R-CNN 提出了一种更好的 two-stage detector 设计结构,使用一个大内核可分卷积和少量通道生成稀疏的特征图。该设计的计算量使随后的 ROI 子网络计算量大幅降低,检测系统所需内存减少。将一个廉价的全连接层附加到池化层上,充分利用分类和回归的特征表示。因其轻量级头部结构,该检测器能够实现速度和准确率之间的最优权衡,不管使用的是大主干网络还是小主干网络。

    基于 ResNet101 网络达到了新的 state-of-the-art 的结果 40.6,超过了 Mask R-CNN 和 RetinaNet。同时如果是用一个更小的网络,比如类似 Xception 的小模型,达到了 100+FPS,30.7mmap,效率上超过了 SSD 和 YOLO。

     

    2. one stage 的方法

    以 R-CNN 算法为代表的 two stage 的方法由于 RPN 结构的存在,虽然检测精度越来越高,但是其速度却遇到瓶颈,比较难于满足部分场景实时性的需求。因此出现一种基于回归方法的 one stage 的目标检测算法,不同于 two stage 的方法的分步训练共享检测结果,one stage 的方法能实现完整单次训练共享特征,且在保证一定准确率的前提下,速度得到极大提升。

    2.1 OverFeat

    2013 年 Yann Lecun 在纽约大学的团队提出了著名的 OverFeat 算法,其利用滑动窗口和规则块生成候选框,再利用多尺度滑动窗口增加检测结果,解决图像目标形状复杂、尺寸不一问题,最后利用卷积神经网络和回归模型分类、定位目标。该算法首次将分类、定位以及检测三个计算机视觉任务放在一起解决,获得同年 ILSVRC 2013 任务 3(分类+定位)的冠军,但其很快就被同期的 R-CNN 算法取代。

    2.2 YOLO

    2015 年华盛顿大学的 Joseph Redmon 等提出的 YOLO 算法继承了 OverFeat 算法这种基于回归的 one stage 方法,速度能达到每秒 45 帧,由于其速度优势迅速成为端到端方法的领先者。YOLO 算法是基于图像的全局信息进行预测的,整体结构简单,通过将输入图像重整到 448×448 像素固定尺寸大小,并划分图像为 7×7 网格区域,通过卷积神经网络提取特征训练,直接预测每个网格内的边框坐标和每个类别置信度,训练时采用 P-Relu 激活函数。但是存在定位不准以及召回率不如基于区域提名方法的问题,且对距离很近的物体和很小的物体检测效果不好,泛化能力相对较弱。

    2.3 YOLOv2 & YOLO9000

    经过 Joseph Redmon 等的改进,YOLOv2 和 YOLO9000 算法在 2017 年 CVPR 上被提出,并获得最佳论文提名,重点解决召回率和定位精度方面的误差。采用 Darknet-19 作为特征提取网络,增加了批量归一化(Batch Normalization)的预处理,并使用 224×224 和 448×448 两阶段训练 ImageNet 预训练模型后 fine-tuning。相比于原来的 YOLO 是利用全连接层直接预测 bounding box 的坐标,YOLOv2 借鉴了 Faster R-CNN 的思想,引入 anchor 机制,利用 K-Means 聚类的方式在训练集中聚类计算出更好的 anchor 模板,在卷积层使用 anchor boxes 操作,增加候选框的预测,同时采用较强约束的定位方法,大大提高算法召回率。结合图像细粒度特征,将浅层特征与深层特征相连,有助于对小尺寸目标的检测。

    2.4 G-CNN

    由于巨大的 proposal 数量使得后续检测效率降低,2016 年马里兰大学的 M Najibi 等提出一种起始于网格迭代的 G-CNN 算法。通过初始化对图像划分回归后得到更加接近物体的候选框,再利用回归框作为原始窗口进行回归调整,解决了以往的基于区域提名方法通过海量潜在候选框直接进行目标搜索,抑制负样本的缺陷。

    在训练阶段,首先在图像中获取叠加的多尺度的规则网格(实际网格相互叠加),然后通过 ground truth 与每一个网格的 IOU 进行每一个网格 ground truth 的分配,并完成训练过程,使得网格在回归过程中渐渐接近 ground truth。在检测阶段,对于每一个样本框针对每一类获得置信分数,用最可能类别的回归器来更新样本框的位置。

    2.5 SSD

    针对 YOLO 类算法的定位精度问题,2016 年 12 月北卡大学教堂山分校的 Wei Liu 等提出 SSD 算法,将 YOLO 的回归思想和 Faster R-CNN 的 anchor box 机制结合。通过在不同卷积层的特征图上预测物体区域,输出离散化的多尺度、多比例的 default boxes 坐标,同时利用小卷积核预测一系列候选框的边框坐标补偿和每个类别的置信度。在整幅图像上各个位置用多尺度区域的局部特征图边框回归,保持 YOLO 算法快速特性的同时,也保证了边框定位效果和 Faster R-CNN 类似。但因其利用多层次特征分类,导致其对于小目标检测困难,最后一个卷积层的感受野范围很大,使得小目标特征不明显。

    2.6 R-SSD

    2017 年首尔大学提出了 R-SSD 算法,解决了 SSD 算法中不同层 feature map 都是独立作为分类网络的输入,容易出现相同物体被不同大小的框同时检测出来的情况,还有对小尺寸物体的检测效果比较差的情况。R-SSD 算法一方面利用分类网络增加不同层之间的 feature map 联系,减少重复框的出现;另一方面增加 feature pyramid 中 feature map 的个数,使其可以检测更多的小尺寸物体。特征融合方式采用同时利用 pooling 和 deconvolution 进行特征融合,这种特征融合方式使得融合后每一层的 feature map 个数都相同,因此可以共用部分参数,具体来讲就是 default boxes 的参数共享。

    2.7 DSSD

    为了解决 SSD 算法检测小目标困难的问题,2017 年北卡大学教堂山分校的 Cheng-Yang Fu 等提出 DSSD 算法,将 SSD 算法基础网络从 VGG-16 更改为 ResNet-101,增强网络特征提取能力,其次参考 FPN 算法思路利用去卷积结构将图像深层特征从高维空间传递出来,与浅层信息融合,联系不同层级之间的图像语义关系,设计预测模块结构,通过不同层级特征之间融合特征输出预测物体类别信息。

    DSSD 算法中有两个特殊的结构:Prediction 模块;Deconvolution 模块。前者利用提升每个子任务的表现来提高准确性,并且防止梯度直接流入 ResNet 主网络。后者则增加了三个 Batch Normalization 层和三个 3×3 卷积层,其中卷积层起到了缓冲的作用,防止梯度对主网络影响太剧烈,保证网络的稳定性。

    2.8 DSOD

    2017 年复旦大学提出 DSOD 算法,其并不是在 mAP 上和其他检测算法做比较,看谁的算法更有效或者速度更快,而是从另一个角度切入说明 fine-tune 和直接训练检测模型的差异其实是可以减小的,也就是说训练一个检测模型可以不需要大量的数据和预训练好的模型。这是由于预训练模型的限制导致:迁移模型结构灵活性差,难以改变网络结构;分类任务预训练模型和检测任务训练会有学习偏差;虽然微调会减少不同目标类别分布的差异性,但深度图等特殊图像迁移效果差异较大。

    SSD 算法是在六个尺度的特征图上进行检测,将这六个检测结果综合起来,DSOD 算法则则根据 DenseNet 的设计原理,将相邻的检测结果一半一半的结合起来。DSOD 算法是基于 SSD 算法基础上做的修改,采用的特征提取网络是 DenseNet。采用 Dense Block 结构,能避免梯度消失的情况。同时利用 Dense Prediction 结构,也能大大减少模型的参数量,特征包含更多信息。设计 stem 结构能减少输入图片信息的丢失,stem 结构由 3×3 卷积和 2×2 的 max pool 层组成,其还可以提高算法检测的 mAP。

    2.9 RON

    2017 年清华大学提出了 RON 算法,结合 two stage 名的方法和 one stage 方法的优势,更加关注多尺度对象定位和负空间样本挖掘问题。

    • 多尺度对象定位——各种尺度的物体可能出现在图像的任何位置,因此应考虑成千上万个具有不同位置/尺度/方位的区域。多尺度表征将显著改善各种尺度的物体检测,但是这些方法总是在网络的一层检测到各种尺度的对象;
    • 负空间挖掘——对象和非对象样本之间的比例严重不平衡。因此,对象检测器应该具有有效的负挖掘策略。

    RON 算法通过设计方向连接结构,利用多尺度表征显著改善各种多尺度物体检测,同时为了减少对象搜索空间,在卷积特征图创建 objectness prior 引导目标对象搜索,训练时将检测器进行联合优化。并通过多任务损失函数联合优化了反向连接、objectness prior 和对象检测,因此可直接预测各种特征图所有位置的最终检测结果。

     

    3. 总结

    随着深度学习技术在图像各领域的研究深入,出现越来越多的新理论、新方法。two stage 的方法和基于回归思想的 one stage 方法两者相互借鉴,不断融合,取得了很好的效果,也为我们展示了一些未来发展趋势:

    • 参考上下文特征的多特征融合;
    • 多尺度的对象定位;
    • 结合循环神经网络(RNN)的图像语义分析。

     

     

     

    展开全文
  • Stage :移动机器人模拟器
  • 对Spark 中Stage划分的分析,很详细。如果有不清楚的地方可以一起谈论
  • 以OpenStage 15 HFA话机为例,一步步设置拍照截图做出的文档,供参考!
  • FCOS: 完全卷积一步(One-Stage)物体检测
  • 开源项目-itwars-Docker-multi-stage-build#an-example-of-docker-multi-stage-building-with-golang.zip,An example of Docker multi-stage building with Golang
  • EventThread: Visual Summarization and Stage Analysis of Event Sequence Data.
  • Uboot Bootstage

    2019-09-02 15:56:50
    了解Uboot Bootstage 1.Kconfig Introduction CONFIG_BOOTSTAGE common/Kconfig: config BOOTSTAGE bool "Boot timing and reporting" help Enable recording of boot time while booting. To use i...
    • 了解Uboot Bootstage

    1.Kconfig Introduction

    • CONFIG_BOOTSTAGE
    common/Kconfig:
    config BOOTSTAGE
        bool "Boot timing and reporting"
        help
          Enable recording of boot time while booting. To use it, insert
          calls to bootstage_mark() with a suitable BOOTSTAGE_ID from
          bootstage.h. Only a single entry is recorded for each ID. You can
          give the entry a name with bootstage_mark_name(). You can also
          record elapsed time in a particular stage using bootstage_start()
          before starting and bootstage_accum() when finished. Bootstage will
          add up all the accumulated time and report it.
    
          Normally, IDs are defined in bootstage.h but a small number of
          additional 'user' IDs can be used by passing BOOTSTAGE_ID_ALLOC
          as the ID.
    
          Calls to show_boot_progress() will also result in log entries but
          these will not have names.
    
    • CONFIG_BOOTSTAGE_REPORT
    config BOOTSTAGE_REPORT
        bool "Display a detailed boot timing report before booting the OS"
        depends on BOOTSTAGE
        help
          Enable output of a boot time report just before the OS is booted.
          This shows how long it took U-Boot to go through each stage of the
          boot process. The report looks something like this:
    
            Timer summary in microseconds:
                   Mark    Elapsed  Stage
                  0          0  reset
              3,575,678  3,575,678  board_init_f start
              3,575,695         17  arch_cpu_init A9
              3,575,777         82  arch_cpu_init done
              3,659,598     83,821  board_init_r start                                                           
              3,910,375    250,777  main_loop
             29,916,167 26,005,792  bootm_start
             30,361,327    445,160  start_kernel
    
    • CONFIG_BOOTSTAGE_STASH_ADDR
    config BOOTSTAGE_STASH_ADDR
        hex "Address to stash boot timing information"
        default 0
        help
          Provide an address which will not be overwritten by the OS when it
          starts, so that it can read this information when ready.
    
    • CONFIG_BOOTSTAGE_STASH_SIZE
    config BOOTSTAGE_STASH_SIZE
        hex "Size of boot timing stash region"
        default 0x1000
        help                                                                                                     
          This should be large enough to hold the bootstage stash. A value of
          4096 (4KiB) is normally plenty.
    

    2.BOOTSTAGE_ID_*

      enum bootstage_id {
          BOOTSTAGE_ID_START = 0,
          BOOTSTAGE_ID_CHECK_MAGIC,   /* Checking image magic */
          BOOTSTAGE_ID_CHECK_HEADER,  /* Checking image header */
          BOOTSTAGE_ID_CHECK_CHECKSUM,    /* Checking image checksum */
          BOOTSTAGE_ID_CHECK_ARCH,    /* Checking architecture */
      
          BOOTSTAGE_ID_CHECK_IMAGETYPE = 5,/* Checking image type */
          BOOTSTAGE_ID_DECOMP_IMAGE,  /* Decompressing image */
          BOOTSTAGE_ID_KERNEL_LOADED, /* Kernel has been loaded */
          BOOTSTAGE_ID_DECOMP_UNIMPL = 7, /* Odd decompression algorithm */
          BOOTSTAGE_ID_CHECK_BOOT_OS, /* Calling OS-specific boot function */
          BOOTSTAGE_ID_BOOT_OS_RETURNED,  /* Tried to boot OS, but it returned */
          BOOTSTAGE_ID_CHECK_RAMDISK = 9, /* Checking ram disk */                                                
      
          BOOTSTAGE_ID_RD_MAGIC,      /* Checking ram disk magic */
          BOOTSTAGE_ID_RD_HDR_CHECKSUM,   /* Checking ram disk heder checksum */
          BOOTSTAGE_ID_RD_CHECKSUM,   /* Checking ram disk checksum */
          BOOTSTAGE_ID_COPY_RAMDISK = 12, /* Copying ram disk into place */
                BOOTSTAGE_ID_RAMDISK,       /* Checking for valid ramdisk */
          BOOTSTAGE_ID_NO_RAMDISK,    /* No ram disk found (not an error) */
      
          BOOTSTAGE_ID_RUN_OS = 15,   /* Exiting U-Boot, entering OS */
      
          BOOTSTAGE_ID_NEED_RESET = 30,
          BOOTSTAGE_ID_POST_FAIL,     /* Post failure */
          BOOTSTAGE_ID_POST_FAIL_R,   /* Post failure reported after reloc */
          ...
    

    3.代码分析

    3.1. 常用函数

     common/bootstage.c:
     int bootstage_init(bool first);
     ulong bootstage_add_record(enum bootstage_id id, const char *name,
                     int flags, ulong mark);
      ulong bootstage_mark(enum bootstage_id id);
      ulong bootstage_mark_name(enum bootstage_id id, const char *name);  
      ulong bootstage_mark_code(const char *file, const char *func,
                    int linenum);
      uint32_t bootstage_start(enum bootstage_id id, const char *name); 
      uint32_t bootstage_accum(enum bootstage_id id);
      int bootstage_stash(void *base, int size);
      int bootstage_unstash(const void *base, int size);
    

    3.2.bootstage初始化

     498 int bootstage_init(bool first)
      499 {
      500     struct bootstage_data *data;
      501     int size = sizeof(struct bootstage_data);
      502 
      503     gd->bootstage = (struct bootstage_data *)malloc(size);
      504     if (!gd->bootstage)
      505         return -ENOMEM;
      506     data = gd->bootstage;
      507     memset(data, '\0', size);
      508     if (first) {
      509         data->next_id = BOOTSTAGE_ID_USER;
      510         bootstage_add_record(BOOTSTAGE_ID_AWAKE, "reset", 0, 0);
      511     }
      512                                                                                                        
      513     return 0;
      514 }
    

      初始化全局变量gd->bootstage,然后调用bootstage_add_record添加record到结构体数组struct bootstage_record record[RECORD_COUNT]; 数组大小由RECORD_COUNT决定。

       19 enum {
       20     RECORD_COUNT = CONFIG_VAL(BOOTSTAGE_RECORD_COUNT),                                                 
       21 };
    

    3.3.添加自定义

    • bootstage_mark(BOOTSTAGE_ID_RUN_OS);
    • bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, “board_init_f”);

    3.4. config配置

    CONFIG_ BOOTSTAGE=y
    CONFIG_ SPL_BOOTSTAGE=y
    CONFIG_ CMD_BOOTSTAGE=y
    CONFIG_ BOOTSTAGE_STASH=y
    CONFIG_ BOOTSTAGE_STASH_SIZE=0x4096
    CONFIG_ BOOTSTAGE_REPORT=y
    CONFIG_ BOOTSTAGE_RECORD_COUNT=40
    CONFIG_ SPL_BOOTSTAGE_RECORD_COUNT=40
    

    3.5.Debug

    => bootstage report
    Timer summary in microseconds (6 records):
           Mark    Elapsed  Stage
     13,284,026          0  board_init_f
     16,594,567  3,310,541  board_init_r
     17,887,992  1,293,425  id=64
     17,898,594     10,602  main_loop
     17,961,225     62,631  id=173
    
    Accumulated time:
                   102,461  dm_r
                   849,307  dm_f
    
     => bootstage stash 0 0x4096
    Stashed 7 records
     => bootstage unstash 0 0x4096
    Unstashed 7 records
    
    展开全文
  • FCOS Fully Convolutional One-Stage Object Detection论文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 185,221
精华内容 74,088
关键字:

stage