Monocular Depth Estimation 2

  1. 入门篇:图像深度估计相关总结
  2. 应用篇:Learning to be a Depth Camera
  3. 尺度篇:Make3D
  4. 迁移篇:Depth Extraction from Video Using Non-parametric Sampling
  5. 深度篇:David Eigen
  6. 无监督篇:Left-Right Consistency & Ego Motion
  7. 相对深度篇:Depth in the Wild & Size to Depth
  8. SLAM辅助篇:MegaDepth
  9. 方法比较篇:Evaluation of CNN-based Methods

单目图像深度估计 - 2. 应用篇:Learning to be a Depth Camera

Learning to be a Depth Camera
Fig. 1 Learning to be a Depth Camera

第二篇借助Learning to be a Depth Camera for Close-Range Human Capture and Interaction(Website)这篇论文谈一下相关应用。

上篇文章中提到过,有了深度信息后,图片就从二维变成了三维,机器对图像的理解成几何倍数的增长,自然利用这更多的信息可以做到更多的事情。
当机器人可以实时获取空间的三维信息,当人机交互只需要手势和表情,当智能汽车可以实时推断周围物体距离……

Learning to be a Depth Camera这篇论文提供了一种把普通摄像头改造成深度摄像头的方法,结合硬件的改造机器学习算法推断可实时获取近距离物体的深度信息。在论文配套的视频中展示了多种应用,如人脸3D建模,手势识别等。
Learning to be a Depth Camera
Fig. 2 不同应用场景
之所以把这篇叫做应用篇,也是因为在视频中给出的应用场景非常丰富,并且能够直观的深度信息看出在人机交互和3D建模方面的重要性。

硬件改造部分

文中对两种摄像头进行了改造,分别是普通的电脑外接摄像头Microsoft LifeCam(Fig.1 d)和Nexus手机摄像头(Fig.1 c)。
Camera
Fig. 3 摄像头改造步骤
如上图,改造的步骤为:

  1. 去掉相机原有的近红外滤光片(NIR cut filter)
  2. 增加一个带通滤波片(bandpass filter)
  3. 增加一圈红色LED光源
    其中带通滤波片带宽和新增的LED光源波长均为850nm。
    在视频中有详细的改造过程,但此处值得注意的是,目前手机相机镜头可能不是单独的带通滤波片结构,而是一层滤波涂层,因此效果可能会打折。
    这种改造的目的是让原本不能感知近红外的镜头对特定波长的近红外光波敏感,改造后的相机输出结果不再为彩色RGB图片。

深度估计算法部分

文章使用机器学习的方法对深度信息进行估计。
Multi-layer decision forest
Fig. 4 多层决策森林
Fig.4为文章进行深度估计使用的多层决策森林结构,输入为一个红外图像的像素点,输出为深度距离值。网络为两层结构,第一层为分类森林,第二层为回归森林。为了让预测过程更有效率,文章限制了目标物体的距离范围(20cm到1m)。
如图所示,Layer1为每一个像素分配一块对应的深度范围(每一个叶子节点表示一个深度范围),并且生成整幅图片的预测深度概率分布(计算分别属于c个叶子的概率)。由于叶子节点的输出并不是具体的深度值,且输出中有全局概率分布,因此第一层可理解为全局的粗略深度估计。
此处插播一句,深度特征不同于其他特征的地方有一点就在于深度信息是全局性的,是一种相对的值,人类也会通过相对距离来判断深度,因此大多数深度估计方法都采用一种由粗到细由全局到局部的预测过程,典型的例子就是多尺度深度网络。

Layer2针对layer1的c种分类结果,训练了c个对应的专家树,每一个专家树都由属于此范围的train集进行训练得到。通过激活不同的专家树,并赋予每个(被激活的专家树的)预测结果对应的权重(权重由Layer1给的概率分布决定),获得每个像素点最终的深度预测值。第二层的输出是mm单位的连续深度预测值。
值得注意的是,论文中提到可以使用Kinect获得的真实深度数据对模型进行训练,在应用时使用改造后的摄像头数据,也可以实时产生令人满意的效果。

由于决策树这块我还没吃透,再此不对训练过程做详细说明,大致是通过最大化信息增益得到每个节点的判断阈值的过程。实验对比部分也一并略过。

不足及展望部分

本文提出的方法软硬结合的解决了单目摄像头深度估计问题,优点有成本低廉,实时性强,不需要手动提取特征等,缺点有如下几点:

  1. 不适用于表面介质不同的物体。文中作对比的SFS方法是基于物体的反射特等物理特性进行深度推测的方法,因此作者强调了此种方法只适用于均一介质的人的皮肤,在视频中也有对塑料模型建模失败的效果展示。
  2. 需要大量覆盖不同情况的train set。这可能是机器学习和深度学习方法的通病了,过于依赖train集,如用室外数据集KITTI训练得到的深度网络在室内数据集NYU_Depth上的表现往往不尽如人意。
  3. 只能探测近距离的物体。由于对距离进行了限制(20cm到1m),但也正是因此可以忽略背景的干扰降低了算法复杂度,更适合于人机交互的应用。

作者也提出了可以改进的方向,如利用已有可直接获取红外值的Camera(Omni Vision)获取更精确的结果。

总结和思考

这篇文章值得学习的地方有很多,比如引人入胜的视频,通过视频可以看出作者团队做了多少工作;比如丰富的实验,不仅仅横向与其他算法对比,而且与不同的训练方式对比,同时在论文的结尾还对手部区域分类的应用进行了详细的实验说明;比如软硬结合的方法,在工业应用上这篇文章比其他单独对算法进行改进的论文无疑更有实用价值。

最近一直在思考论文的价值,是发表了论文就算有价值吗?为了提高百分之零点几的正确率让算法变得更加复杂真的是正确的研究方向吗?我个人还是比较喜欢简洁的方法,简洁即优雅,就像Science上的CFSFDP一样,提出全新的思路和方向的论文对我来说更有意思一些。
以上。

[1] Fanello S R, Keskin C, Izadi S, et al. Learning to be a depth camera for close-range human capture and interaction[J]. Acm Transactions on Graphics, 2014, 33(4):1-11.

Monocular Depth Estimation - 1

单目图像深度估计 - 1.入门篇

最近一直在看单目深度图像估计相关的Paper,小白入门困难多多,于是打算把看过的几篇论文和相关理论总结一下。
顺序如下:

  1. 入门篇:图像深度估计相关总结
  2. 应用篇:Learning to be a Depth Camera
  3. 尺度篇:Make3D
  4. 迁移篇:Depth Extraction from Video Using Non-parametric Sampling
  5. 深度篇:David Eigen
  6. 无监督篇:Left-Right Consistency & Ego Motion
  7. 相对深度篇:Depth in the Wild & Size to Depth
  8. SLAM辅助篇:MegaDepth
  9. 方法比较篇:Evaluation of CNN-based Methods

作为入门篇,这篇写的大部分是我个人的想法,脉络的话大约按照是什么,为什么和怎么做三部分进行。

什么是图像深度估计

顾名思义,深度估计就是从RGB图像中估计图像中物体的深度,是一个从二维到三维的艰难过程。此处的艰难是对计算机来说,而人类的视觉系统是天生的双目系统,并且通过大脑的计算可以实时生成深度信息甚至空间的三维建模。

所谓双目立体视觉,即模仿人眼成像原理,在同一时刻不同位置用两台相同的设备对物体进行观测。光沿直线传播,因此同一物体在不同位置的成像可最终确定物体的真实位置。
双目立体视觉
在两个相机已经校准的前提下,已知相机的光点距离、焦距和物体在画面内的水平距离等参数时,可计算得到真实距离信息。
双目立体视觉计算方法
双目立体视觉是目前常见的深度信息获取方法,在SLAM、智能车、体感游戏等领域都有大规模的应用。其缺点也较为明显,如硬件体积大,计算量大(图像校准),精度受限(复杂重复画面如树林影响图像校准,时间轴校准困难)等。目前常见的深度信息获取方法除双目立体视觉方法外还有结构光、TOF等方法(见下图),但各有优缺点,比如体积大(TOF)、能耗高(Kinect配有散热系统)、受环境影响(阳光中红外线影响)、算法复杂度高、实时性差(TOF实时性最高但精度较低)等。
深度图像获取方法

由于以上基于硬件的深度获取方法还存在一定缺点,在深度学习、机器学习、人工智能飞速发展的今天,用更“智能”的方法对图像深度进行估计,弥补硬件的不足,同时为其他图像应用如语义分割、物体识别等提供更多的特征信息成了大牛们研究的方向。

为什么是单目图像深度估计

无论是深度学习、机器学习还是机器视觉的目标,到目前为止仍然是:更接近人类。那么有趣的问题来了,就算我们闭上一只眼睛(神盾局长、海盗船长)仍然可以分辨物体深度。我们是怎么做到的?从眼睛的成像原理来看,人类获取到的也只是某一时刻物体的二维成像,我们没有类似深度传感器的结构,那么深度信息是什么时候附加在我们看到的画面上的?
因为我们的大脑利用了已有的知识:
深度知识
近大远小
深度知识
轮廓和遮挡
深度知识
消失点

这些透视知识学习过绘画的人会更了解,我们的大脑总结出了这些知识和经验,并对每次观测附加相应的信息,形成了精度极高的深度估计系统,在捂住一只眼睛的情况下,也可以对深度进行相应的估计和预测。
很有趣吧。

无论是深度学习还是机器学习,核心都是学习,我们希望机器能拥有像人脑一样的学习能力,所谓学习就是总结并利用知识和经验的能力。因此,若是能训练机器完成对单幅图像的深度估计,那么在知识的理解和运用上也是一种突破,更别提单目相比传统深度获取方法的优点(成本低,体积小,能耗低等)了。
并且单目图像深度估计的应用广泛,常见的有电影2D转3D,网络图片理解,3D建模,机器人,智能车等。

怎么进行单目图像深度估计

由于我刚刚进行这方面的研究,只看了不到10篇论文,这几篇论文的方法大致可以分为:基于深度迁移的方法,基于相对深度的方法和基于深度网络的方法三类。在之后的文章中会详细讲解每一篇论文。
毫无疑问,随着深度学习方法的发展,应用深度网络进行深度估计越来越成为主流的单目图像深度估计方法,但这种越来越复杂化的方法真的是正确的发展方向吗?

SSH for Windows

Windows7进行SSH连接

最近尝试在GPU服务器上运行深度网络的推断,因为我的电脑为Windows 7系统,所以用到了Windows和Linux进行SSH通信的一些方法,在此记录一下。

  1. 连接服务器
    • Windows进行SSH连接需要使用特定软件,我下载的是PUTTY,一款小巧的软件,可以建立连接,连接成功后界面相当于Linux的控制台。
    • 连接方法:
      打开PUTTY,输入服务器的地址,默认SSH端口为22,点击open后提示输入用户名,回车之后输入密码即可。
    • 常用命令:
      记几个Linux中常用的命令:
      1) pwd —— 显示当前地址
      2) cd 地址 —— 地址跳转
      3)ifconfig —— 显示网络信息
      4)rm 文件名 —— 删除文件
      5)mkdir —— 创建地址、文件夹
      6)ls —— 显示当前目录下的所有文件及文件夹
      7)nvidia-sim —— 显示显卡使用情况
  2. 上传、下载文件
    • 文件操作需要使用PUTTY中的PSFTP软件,打开软件以后输入指令open 服务器地址,系统提示输入用户名,回车后输入密码则显示连接成功。文件上传和下载时需要注意确定当前路径是否正确。
    • 上传文件:
      1) 上传文件夹:需要-r表示递归
      put -r c:/Users/Desktop/abc —— abc为文件夹名
      
      2) 上传文件:
      put c:/Users/Desktop/a.jpg
      
    • 下载文件:
      1) 首先需要设定下载到本地的存储目录:
      lcd c:/Users/Desktop
      
      2)get 文件名
  3. 注意事项
    • 如果两次上传的文件名相同,则默认覆盖已有文件且不进行报错,可能会造成文件损失
    • 下载文件时如果不指定本地位置(lcd指令)则会报unable to open错误

Install OpenCV on Raspberry Pi

树莓派上OpenCV的安装

想在树莓派上链接手机摄像头作为IP摄像头在树莓派上实现人脸识别,于是开始了漫长的OpenCV安装之路。
参考资料:

Rasberry Pi(Python3) + OpenCV 3.0.0

sudo apt-get update
sudo apt-get upgrade
sudo rpi-update
sudo apt-get install build-essential git cmake pkg-config
sudo apt-get install libjpeg8-dev libtiff5-dev libjasper-dev libpng12-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libgtk2.0-dev
sudo apt-get install libatlas-base-dev gfortran
cd ~
git clone https://github.com/Itseez/opencv.git
cd opencv
git checkout 3.0.0
cd ~
git clone https://github.com/Itseez/opencv_contrib.git
cd opencv_contrib
git checkout 3.0.0
sudo apt-get install python3-dev
sudo python3 get-pip.py
sudo pip3 install virtualenv virtualenvwrapper
sudo rm -rf ~/.cache/pip
nano ~/.profile
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
source ~/.profile
mkvirtualenv p3cv
workon p3cv
pip3 install numpy
# 若报没有权限的错误执行sudo rm -rf ~/.cache/pip/
cd ~/opencv
mkdir build 
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_C_EXAMPLES=OFF \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
-D BUILD_EXAMPLES=ON ..
# 检查python环境是否正常,ImportError:No module named cv2则检查.profile加入export LD_LIBRARY_PATH=/usr/lib/:$LD_LIBRARY_PATH
make -j4
sudo make install
sudo ldconfig
cd ~/.virtualenvs/p3cv/lib/python3.4/site-packages/
ln -s /usr/local/lib/python3.4/site-packages/cv2.so cv2.so

有用的指令

  1. 更改管理员权限的密码:

    sudo passwd root
    sudo passwd –unlock root

  2. 设置代理服务器
    1)打开profile文件

    vi /etc/profile
    

    2) 添加如下语句

    http_proxy=1.1.1.1:8080
    no_proxy=10.2.44.44
    export http_proxy no_proxy
    

    3) 打开文件指令为vi,打开后按insert键开始编辑,编辑完成按esc键输入:wq保存(或输入:q!不保存直接关闭),执行文件指令为source

    source /etc/profile
    
  3. 进入虚拟环境

    source /usr/local/bin/virtualenvwrapper.sh
    workon p3cv

存在问题

  1. ImportError:No module named cv2:将cv2.so文件复制在各种文件夹内
  2. 忘记是什么问题,解决方法是把ffe…的文件复制到python文件夹内
  3. 目前仍然没有解决的问题是树莓派无法连接公司的代理服务器上外网
  4. 环境变量配置不成功,每次需要手动进入虚拟环境

Tensorflow install with Anaconda

在Anaconda的python环境中安装TensorFlow

  1. 安装Anaconda
  2. 创建python3.5环境
    • cmd中conda create -n tensorflow python=3.5,其中tensorflow为环境的名称
    • 目前TensorFlow对python3.5的支持最好
    • 如果无法使用conda命令则需要手动添加环境变量:path中增加Anaconda3\Script路径
      Anaconda Python环境搭建
  3. 安装TensorFlow
    • Activate tensorflow:启动tensorflow环境
    • Pip install tensorflow
      ** 在有代理的网络下需要设置pip代理服务器:pip install –proxy(anaconda环境貌似不需要)
    • deactivate:退出环境
  4. 配置PyCharm
    • File->Settings->Project:plug-n-learn->Project Interpreter 选择Anaconda目录中env(虚拟环境)下的 环境名称\python.exe
    • pycharm包管理:想用pycharm下载更新包需要设置代理服务器(设置方法为 file-settings-appearance & behavior-system settings-HTTP Proxy)
      Pycharm配置
  5. 配置spyder
    • 打开anaconda navigator,下拉菜单选择tensorflow环境后点击spyder图标下的install按钮
  6. 测试
    • activate tensorflow
    • python
    • import tensorflow
    • 成功

TensorFlow Install

Tensor Flow安装步骤

  1. 安装python3.5(一开始装成3.6了,装完了才发现tensorflow目前只支持到3.5)
  2. 安装pip:python -m ensurepip
  3. 解决pip -v报错: 到scripts文件夹查看pip的文件名,发现应为pip3.5,因此到cmd pip3.5 -v成功
  4. 下载tensorflow
  5. 依赖包安装顺序:
    • Wheel>=0.26
    • Numpy>=1.12.1
    • Tensorflow-tensorboard<0.5.0>=0.4
      • Bleach==1.5.0
        • Six(1.11.0)
        • Html5lib 0.999999(6个9)
          • Webencodings0.5.1
      • Werkzeug>=0.11.10
      • Protobuf>=3.3.0
      • Markdown>=2.6.8
    • Absl-py
    • Enum34>=1.1.6
  6. 显示Tensorflow安装成功(要哭了)
  7. Import tensorflow as tf 报错could not find解决方法:
    ‘msvcp140.dll’,网上搜到可通过下载文件放入System32文件夹解决,也可以通过安装matplotlib解决,想到以后要用到matplotlib所以决定用第二种方法。
  8. 安装matplotlib2.1.0,依赖包安装顺序:
    • Python-dateutil>=2.0
    • Cycler>=0.10
    • Pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>2.0.1
    • Pytz
  9. 安装成功后,将matplotlib文件夹里的msvcp140.dll拷贝到system32文件夹中
  10. Import tensorflow成功

python包手动安装方法:

* `.whl` : pip install xxx.whl
* `.tar.gz源代码` : 
    ** 1) 解压缩 
    ** 2)cd到相应目录
    ** 3) python setup.py install(此处的python若不指定则为defaultpython,如果想装到某个版本或anaconda环境中需要指定python,方法是更改anaconda env文件夹下的python.exe的名字,如改为python27.exe则安装的时候使用python27 setup.py install安装)

PS.附上pip代理服务器设置方法

* pip --proxy http://xxx:xxx

Mobile-Web-Develope2

总结一下最近遇到的问题:

布局方面:

  • margin是根据父元素width宽度计算百分比的,并不是垂直方向根据父元素高度水平方向根据父元素宽度;===》解决方案:尽量不用百分比;
  • 并不是所有手机都支持vw和vh单位(比如魅族M1)===》解决方案:不用vw和vh,vmin和vmax,改用rem
  • em相比px更具有响应式特点,但em是相对值,而如果通篇用rem写布局会出现大屏手机整平内容过少或小屏手机整平内容过多的现象,sad ===》解决方案:flexible.js,字体px
  • inline-block自动产生的间隙可用display:table解决(目前还没找到适合强迫症的看起来不投机取巧的解决方法,负margin的方法亲测无用不知为何)
  • 当input的type属性为search时,手机上会自动出现一个难看的‘X’作为清空按钮 ===》解决方案:
1
2
3
4
5
6
input[type='search']::-webkit-search-decoration, 
input[type='search']::-webkit-search-cancel-button,
input[type='search']::-webkit-search-results-button,
input[type='search']::-webkit-search-results-decoration {
display: none;
}

其他方面:

  • input的placeholder在某些手机浏览器上垂直不居中,stackoverflow上有相关提问,提出的解决方案多种多样,然而我并没有找到真正有效的,可能是魅族自带浏览器比较奇葩吧。附stackoverflow相关讨论地址。
  • 锚点跳转时若存在fixed导航条时则跳转结果有微妙差别,知乎上有人回答了==》知乎问题

啊暂时就想到以上这些,晚安吧。

Mobile-Web-Develope

最近开始一项大工程:从零开始的移动端网页开发。
说实话到现在我也分不清移动端网页到底该怎么称呼才更显专业,因为说起移动端应该都想到Ios和Android客户端,但按照老板的意思我要完成的是
在移动设备上浏览时功能和外观与客户端基本一样的网站
蛤?老板你好看得起我哦。
于是,本着生命不息学习不止的精神,我开始了这方面学习。


总结如下:

  • 手机浏览器内核基本都为(webkit),因此对HTML5和CSS3支持很好,想到不用搞麻烦的css hack禁不住叉腰仰天笑!
  • Retina屏幕的解决方案很重要,即想用高分辨率屏幕就要做好流量消耗快的准备
  • 就算是响应式也不用所有长度单位都用百分比—>此为血泪教训
  • 抛弃点击和悬停等等指针检测,手机的操作和鼠标完 全 不 一 样
  • 各种好用的库都小巧又可爱,目前接触到了font awesome, swiper, owl carousel都非常有意思,用着用着不禁想自己什么时候也能写一个啊
  • chrome自带的调试功能比较好用
  • 程序员需要一个好用的键盘
  • 夏天应该多喝水

以上 :)

Hexo Blog

想实现一个博客的原因是看到了这个项目–>一个简单的博客是用Node.js+Express+MongoDB实现的有登录功能的博客,缺点就是界面过于简单了。
我想到个人博客的内容并不多,这个登录功能像是完全为了学习MongoDB才硬加上去的,那么有没有界面好看又不用连接数据库的简单的个人博客,于是发现了以下几种:

  • Webpress
  • JekyII + Github pages
  • Hexo + Github pages

然后因为JekyII基于Ruby我的电脑并没有装Ruby,而用到github pages的话气氛上是更适合程序员的感觉于是就选择了Hexo。

步骤比较简单,但还是花费了一下午时间,现在总结如下:
利用Hexo + Gitpages建立blog拢共分三步:

  1. 各种下载 Node.js,Git
  2. 建立/username.github.io/仓库
  3. 部署Hexo

然后就可以写文章啦,需要使用Markdown语法,很新鲜,挺有意思。
目前就做到这,更加深入的研究使用留在日后再说吧。

Deploy Blog

部署步骤
(内容来自网络)

每次部署的步骤,可按以下三步来进行。

  1. hexo clean
  2. hexo generate
  3. hexo deploy

一些常用命令:

  • hexo new”postName” #新建文章
  • hexo new page”pageName” #新建页面
  • hexo generate #生成静态页面至public目录
  • hexo server #开启预览访问端口(默认端口4000,’ctrl + c’关闭server)
  • hexo deploy #将.deploy目录部署到GitHub
  • hexo help # 查看帮助
  • hexo version #查看Hexo的版本