使用反向ssh从外网访问内网主机

通过本方法可以从外网通过ssh访问内网的主机,前提是内网的主机要能够访问Internet,还需要一台具有公网地址的主机。

在内网主机上执行以下命令,其中:120.24.3.x是一台公网主机,该主机可以是云主机或者通过路由器端口映射到内网的一台主机,1111是这台公网主机映射的端口。

ssh -NfR 1111:localhost:22 root@120.24.3.x -p 22

执行完毕,会有一个后台进程运行

[root@localhost ~]# ps -ef |grep ssh
root 1115 1 0 10:59 ? 00:00:00 /usr/sbin/sshd
root 1258 1115 0 11:00 ? 00:00:01 sshd: root@pts/0 
root 3604 1 0 11:50 ? 00:00:00 ssh -NfR 1111:localhost:22 root@120.24.3.x -p 22
root 3606 1115 0 11:50 ? 00:00:00 sshd: root@pts/1 
root 3647 3610 0 11:57 pts/1 00:00:00 grep ssh

然后在公网主机上ssh本地的端口1111就可以访问内网的主机了

ssh root@localhost -p 1111

在线的UML绘图工具

在网上找到几种在线UML工具:diagramo,jsUML2

功能比较全,但是也比较繁琐,适合专业人士,不方便的地方是不能把元素拖进画布

轻量级,基于HTML5,可导出为json格式的文档,也可以保存为图片,简单易用

软采优化-2

经过一个星期的折腾,软件采集基本稳定下来了,性能比之前有所提高,基本满足系统要求。优化的步骤:

打开ffmpeg和x264的yasm编译选项,由于我是在windows下用mingw64编译,所以需要下载yasm windows版本,编译过程还算顺利;该选项开关打开以后,单机采集1080p30视频窗口效率明显提高很多,主要是scaler部分提高了50%,每帧只需要10ms左右,系统瓶颈转移到了编码部分,编码受图像的影响比较大,动态图像耗时较长,所以需要在scaler和x264之间添加缓存。我将整个图像处理过程分成:采集,缩放,编码三个任务/线程,每个任务之间通过消息队列传递帧数据,尽可能的减少内存拷贝,但是仍然不可避免的需要在采集=》缩放,缩放=》编码两处进行内存拷贝,如果要优化的话就得修改ffmpeg的代码了。减少内存拷贝可以减少几个ms,真正消耗CPU最多的还是编码,目前对编码参数研究不多,简单的通过以–present参数可以起到一定作用,ultrafast的编码速度非常快,但是图像马赛克也非常严重,我现在使用superfast图像质量基本满足要求,没有马赛克。

软采优化

这段时间在研究软件采集,其中几个关键技术难点
1. 采集帧率,主要受限于系统API截屏效率,图像格式转换效率和编码效率
2. 图像质量
3. 实时性

截屏效率,目前采用WINDOWS GDI貌似1080p30没有什么问题,但是在图像转换时由于window截屏得到的是BGRA格式32位图像,这在转成YUV420p的时候,影响了效率,比BMP24bit要慢50%,也就1080p20帧的水平,目前还没有想到什么好方法来解决,准备研究一下ffmpeg的编译优化,或者试试多线程。

编码效率若是对静态网页窗口进行编码效率非常高,1080p60,但是换成采集视频播放器窗口,却只能达到20帧,这有点让人失望。后续看看x264的编译选项和编码参数上能不能有些突破。

下面是一些思路
1. 编译选项,打开asm开关
2. 采用多线程
3. 编码参数,–present ultrafast
4. msys1.0升级到msys2.0

编码器时间戳应该在采集时打

最近接了一个活——在安卓盒子上做视音频编码网络串流。这个玩意貌似没有什么难度,live555/vlc在这方面的应用已经很多了,但是用安卓盒子来完成还是比较有挑战性的。最大的问题在于安卓系统并非实时系统,采样频率很难保证,特别是在1080p这种高分辨率的时候,采样频率无法保证的话就很难保证画面的连续性。

一开始我像大多数人那样自己造时间戳,基于编码器收上来的帧的时间,对一段时间内接收的帧求均值做为相邻两帧的时间戳delta,用VLC测试的结果并不理想,一直提示picture may delay的告警,时间长了就会导致VLC重连。后来我发现从编码器收帧的时间delta波动非常大,因为I帧大接收时间长,P帧小接收时间短,而且系统的负载对这个问题也有一定影响。这个波动越大就需要延长统计周期,从而得到一个相对平滑的值。理论上这样做问题就会得到解决,可实际上图像播放还是会出现不流畅,卡顿。最后,我意识到应该让正确的人做正确的事,这才是解决问题做有效的方法。编码时间戳本应该由采集端在采集的时候打上去,它标识了该图像发生的时刻,假设采集频率均匀,帧率足够,那么播放器只需严格按照时间戳播放就能得到流畅的画面。而实际上各个厂商的采集盒,采集频率和帧率都不是稳定的,做的好的可能波动小一点,由于波动较小,而人眼对画面之间间隔的感知有一定承受程度,所以感觉不到画面跳动/卡顿。也就是说,即使有时候相邻两帧采集时间相差了100~200ms,如果这两帧播放的时间间隔小于60ms,那么人眼都无法察觉出来。

既然知道了这个原理那问题就好办了,采集端需要讲系统做得实时,稳定,最大程度的保证采集的帧率和频率恒定。播放端根据采集端的时间戳进行调整和均衡,保证画面流畅播放。如果想要让系统适应不同播放器,也可以将时间戳调整和均衡的工作交给编码盒做。关键的一环,编码时间戳在采集的时候打。

Realsense–想说爱你并不容易

如今3D扫描技术已经不稀奇了,市面上大多数3D扫描仪价格不菲(几千至上万)。如何打造家用的3D扫描仪成为了热点,先有微软用kinect实现了3D扫描(见fusion项目),然后有Apple收购primesense,推出structure-io,通过ipad上的摄像头外加structure-io附件,定制成非常便携的3D扫描仪。

上述方案大概估算一下成本,xbox kinect 1000多,windows kinect 3000~4000;ipad加structure-io,最起码得5000~6000。xbox kinect虽然便宜,但是属于破解方案,因为微软官宣xbox kinect只能用于xbox主机,所以不可商用。因此上面两个方案成本都需要5000+,与专业的3D扫描仪相比价格优势不那么明显,而且对家庭用户来说接受度不高。

相比之下realsense的方案,一个realsense F200摄像头只需要99美元,然而并没有什么卵用,看看它的系统和硬件要求:

4th generation (or later) Intel® Core™ processor
8GB free hard disk space
Supported systems: Ultrabook™ devices, notebooks, 2 in 1’s, and all-in-one PCs
An Intel® RealSense™ 3D Camera F200 (system-integrated or peripheral version)

Microsoft Windows* 8.1 OS 64-bit Desktop Mode

win8还不是致命的,4th gen CPU,开始我并没在意这个,后来调查了一番才知道这是Intel近两年的技术,也就说两年前买的电脑或者非Intel的电脑就不要想了,装了也没什么用,不是说用不了,而是会出现各种奇怪的问题,闪退,时不时找不到设备等等。论坛上,和我自己的亲身经历充分证明了这一点。

还是期待Intel能够open一点,把安卓和linux的驱动发布出来吧。

real monopoly (1)

折腾了两三个星期,终于决定不再加新东西了。本来是想做成像大富翁一样的游戏,通过位置定位让好友分享在相同位置的有趣的事情,比如上传一些图片,留个言什么之类的。后来觉得估计没什么人会用,因为已经有强大的微信了,所以不得不找点其他乐子,开始想到猜谜语,可还是没有解决“别人为什么要用你的东西”的问题。最后索性来个简单粗暴的,先弄一个简单的游戏试试。

在游戏的选择上,由于是网页版,又不想让用户同时在线,所以需要找一个一来一回的游戏,这让我想起小时候玩的打船的游戏。然后考虑的是如何可以减少用户操作,于是我将5艘船改为3艘,将炸弹改为5个且没有枪的概念了。这样基本上一场战役攻和守各5到6次点击就可以完成。由于和真实位置有关系,于是我将船的概念改成士兵,这样配合真实地图就好多了。

上面这些活其实不难期间走了些弯路,最后还把人脸给做进去了,这点时间实际上我是把这个系统推到重做了三次。现在,终于有个样子了,不想再加东西了。先做好做稳定再看看。感兴趣的朋友可以访问:real monopoly

最后上图:

将深度数据转换成点云(cloud point)

自从用了openni2以后,又得从造轮子开始了。openni1.x版本还有个xnConvertProjectiveToRealWorld函数可以将深度图转化成点云,openni2将这些接口都删光光了,无奈之下只好自己研究原理,然后将算法porting过来。

什么是深度图?2D图像里面,每个坐标(x,y)都有一个向量来表示该点的颜色,同理,深度图就是每个坐标(x,y)都有一个浮点数表示该点距离测量平面(比如深度摄像头镜面所在平面)的距离。

什么是点云?实际上就是三维空间里面点的集合,这些点具有相同的参照坐标系(原点)。

深度图与点云之间有什么关系?假设三维空间用xyz坐标系表示,以相机中心点为原点,那么深度值实际就是z。由于深度图中的,x,y分别表示图像的横向和纵向的点序列(而非距离),所以必须统一单位才能输出点云。

参考网友的文章:http://blog.csdn.net/opensource07/article/details/7804246,然后加上自己的理解,从深度图转化为点云,其实很简单,只需知道相机的Field of View。Structure sensor的FOV为:Horizontal: 58 degrees, Vertical: 45 degrees。原理如下图:IMG_0498

最后生成的点云:

cloudpoint

structure sensor试用(2)——Nite2

Nite是一套基于openni开发的手势识别中间件,如果使用structure sensor的话,Nite的其他版本基本不用考虑了,因为openni2跟openni1.x相比架构上做了大调整,这里我使用的是NiTE-Windows-x86-2.0.0版本。安装完毕以后,记住参考(1)介绍的,修改PS1080.ini文件。

structure sensor试用(1)

前两天structure sensor到手,简单试用了一下网站上提供的APP还有openni2,老实说目前这款sensor的支持还是非常有限。

先说说安装,sensor如果要固定到ipad上,需要通过4颗螺钉固定到支架上,然后通过支架卡在ipad上,再将数据线连接ipad和sensor就可以了。貌似ipad无法给sensor直接供电,所以数据线仅仅是将sensor的数据传送给ipad处理而已。如果购买了hacker usb cable线的话,则可以将sensor通过usb连接到PC上使用,驱动在openni2中自带了,安装完毕就可以通过open2自带的tools NiViewer查看深度视图。这里需要注意到是,structure io的官网上介绍,需要修改PS1080.ini文件,将“UsbInterface=2”修改为“UsbInterface=0”,很多人忘了把这句话前面的“;”号去掉,导致修改不生效。运行的结果如下图所示,由于没有color camera,所以只有depth camera的图像显示出来。

niviewer

Scanner,使用之前还需要下载一个标定软件标定一下,标定的过程非常简单,找一个光线充足,有足够清晰纹理的视角,左右缓慢移动就可以了。标定的作用主要是将color camera的图像与depth camera的图像进行匹配,这样才能扫描出带颜色的3D模型。标定完成以后,运行Scanner就可以开始扫描了,官网的视频里面有扫描过程的视频,这里就不累述了。从实际使用的体验来看,扫描一个人体上半身大概需要3,4分钟左右,整个轮廓还是比较平滑的,注意光线一定要充足,不然就会扫出来的3D模型就会偏黑。对于比较复杂的物体,扫描效果不好,比如一盆花什么的,花瓣位置简直无法无法忍受。