| 凯凯's profile十年一剑 LIVE SPACEPhotosBlogLists | Help |
十年一剑 LIVE SPACE棋逢对手,琴遇知音,才是人生最愉快的事情! June 27 Paper Reading on Li Guan(1)3D Shape Estimation with Heterogeneous Sensor Network (3DPVT_2008)其实这篇文章和他的另一篇文章 A Unified Approach to Calibrate a Network of Camcorders and ToF Cameras (M2SFA2_ECCV_2008) 是同一个工作的两个不同的侧重点(后者更侧重于标定网络),这个工作附有相关的Matlab代码。 他的这个工作本来不是我研究的重点,我更关注的是他们组在处理遮挡情况下进行三维重建的工作。但是这个工作他贡献了Matlab源代码,源码很深刻的反映了作者的积累,所以我主要是要逼迫自己研究一下这个代码。这个工作应该说是JS Franco and E Boyer在ICCV_2005的那篇文章 Fusion of multi-view silhouette cues using a space occupancy grid 的思路上的大扩展,从Fuse多个轮廓,到Fuse异质数据,这是一个不小的跨越,而使用的方法本质上都是相同的,就是Bayes的概率模型。Franco的EPVH代码被4dView买断,要不然研究一下EPVH的代码一定会大有收获的。 先看论文,定标的部分我暂时不感兴趣,只关注Object Reconstruction的部分,就是一个Space Occupancy Grid(或Occupancy Volume)进行三维场景表达的过程。这篇文章题目是说使用异质数据进行对象重建,第一部分:After defining the probabilistic sensing models for each type of sensors, the reconstruction simply becomes a Bayesian inference.就这句话点出了作者的思路,也是全文的关键句。作者的想法就是要对每种介质类型的源数据分别进行概率方式的建模,然后使用Bayes Model进行fusion。于是,第二部分:介绍了RIM Camera的定标,这是另一篇定标工作的延续性描述,而且重建的整体方法离不开异质数据传感器网络的定标方法。第三部分:问题形式化,作者将自己的系统定位于Probabilistic Shape Inference Framework,接下来将统一的联合概率分解为多个单数据源的条件概率之间的运算,于是将问题分解为各个数据源的概率建模问题。第四部分:分别对作者自己所使用的两种异质数据源(Camcorder Sensor和RIM Camera Sensor)进行概率建模,基本是根据依赖关系建立的Bayes置信网(或Bayes网络)模型。至此,理论上的问题算是解决了,很一般的思路,没有什么可圈可点之处,不过思路很清晰这是很难得的。 看实验之前,有必要先了解一下作者所用的两种异质数据源:Camcorder(便携式摄像机,例如:Canon HG10) 和 RIM Camera(肯定不是BlackBerry手机上的照相机,呵呵!指的是距离传感器,可以直接拍到对象和场景的深度,例如:Swiss Ranger 3100)。但是实验部分并不十分有趣,作者还是在不断炫耀定标的精度带来的重建精度上的优势。实质上,由距离传感器SR3100得到的深度图参与重建的概率推理过程,是这种重建过程能比一般的Visual Hull更加强大的重要原因,因为一个深度图能顶上好多轮廓图所能提供的信息呢。Discussion部分,作者强调了这种Fusion是可以在任意各种异质数据之间进行的,只要知道了各种数据源的概率模型。 代码的结构很好,跟论文的中心句所暗示的结构吻合得很好。此代码的一个优点是:把每个摄像机的数据依次载入,记录每个摄像机的概率之和的做法,使得不必同时为所有摄像机申请内存,这样可以很好的处理很多的摄像机而不会使程序崩溃。 (1)probabilisticVolume.m 主函数。 global Cam;定义全局的相机变量,它的结构如下定义: Cam = struct('type', {1}, ... %摄像机类型:Camera或ToF 打开脚本文件: fid = fopen(script); %之后fid就是script脚本指针 然后,读取script的第一行参数,这12个参数都是全局的参数,非常重要: camNum 摄像机数目 xlength, ylength, zlength 体积大小 xscale, yscale, zscale 缩放因子 xtranslate, ytranslate, ztranslate 平移向量 Aperture 体素投影在图像上的孔径大小 PfPrior 重建对象存在的先验概率 继而,初始化三个体积: volume = PG1 = PG0 = zeros(xlength,ylength,zlength); 再然后,开始循环: 外层循环是对每个照相机做循环: for c=1:camNum 初始化传感器(就是读取摄像机参数矩阵等) 接下来遍历每个体素单元,对每个体素单元进行操作: for X = 1:xlength { P = [(X-xtranslate)*xscale; (Y-ytranslate)*yscale; (Z-ztranslate)*zscale; 1]; %对体素进行全局伸缩和平移 p = projectionRadial(P); %求出投影在当前图像上的点坐标 % 根据孔径大小找到当前体素投影在图像上的BoundingBox x0 = max(ceil((p(2)/p(3)-Aperture)),1); norm = (x1-x0+1)*(y1-y0+1); % BoundingBox的面积,作为摄像机视图内概率推理的输入参数 %do the main probability computation (对单个体素在单个视角上进行概率推理) % PG1和PG2分别是各个视角的概率和,所形成的概率Volume空间 PG1(X,Y,Z) = PG1(X,Y,Z)+tempP1; } end % 接着对每个体素进行归一化得到最终的Volume概率模型 for X=1:xlength { % volume(X,Y,Z) = PfPrior/(PfPrior+(1.0-PfPrior)*exp(-PG0(X,Y,Z)+PG1(X,Y,Z))); } %display the volume (概率体素Volume的三维显示) %display the surface (表面三角网的三维显示) (2)initializeSensor.m 初始化视觉传感器(就是读取和Global Cam变量相关的全局参数) Cam.type = tline; %获得照相机类型 Cam.input = ... ; %获得输入源图像 Cam.background = ... ; %获得背景图像 calibrationFile = fopen(tline); %获取定标文件名并打开文件 tmp = fscanf(calibrationFile, '%f', 3*3+3*3+3*1+5*1); %读取所有参数值 %分配给K R t kk 等矩阵和向量: Cam.K = K = [tmp(1) tmp(2) tmp(3); tmp(4) tmp(5) tmp(6); tmp(7) tmp(8) tmp(9)]; Cam.imWidth = tmp(1); %图像宽度 Cam.silhouetteProbability = double(imread(tline))/255.0; %获取silhouetteProbability轮廓概率图(最白的是前景) (3)projectionRadial.m 将体素投影到当前图像上 tmp = [Cam.R Cam.T]*P; % 左乘外参矩阵[3*4][4*1] = [3*1] (4)voxelOccupancyCam.m 照相机的概率图模型推理过程,推理单个体素在某个视角上的概率 %概率VH的摄像机参数(这五个参数是手动设置的***): Uf = 0.5; %将BoundingBox里的每一个像素,对当前体素的概率贡献计算加和 for ii=x0:x1 PF1G1 = (1-1.0/norm)*Uf+1.0/norm*Pd; %marginalize over F, and take the log %Px = PR*Pd+(1.0-PR)*Pf; % 如果计数count为零,则置为tempP0 = tempP1 = -1 , 否则,给它们取反后返回 (5)voxelOccupancyToF.m 距离传感器的概率图模型推理过程 这个模型暂时不重点研究。 (6)drawCameras.m 第一步:读入摄像机的全局参数 Cam.K = K; Cam.imWidth = tmp(1); Cam.silhouetteProbability = double(imread(tline))/255.0; 第二步:求出摄像机在三维空间中的位置 PP1 = [PP1(1) PP1(2) PP1(3)]; 第三步:通过三维坐标的相对画出个摄像机的形状 line([PP1(1); PP2(1)],[PP1(2); PP2(2)],[PP1(3); PP2(3)], 'LineWidth',1); ...... (7)displayVolume.m 显示空间体素概率图 axis equal; (8)displaySurface.m 三角表面表示,进行三维显示,并打上光照 [x,y,z] = meshgrid(1:xl,1:yl,1:zl); (9)P2KRT.m 此函数将投影矩阵分解成为K R t。 (10)vol3dtool.m 和 vol3dtool.fig 这个是用来画示意图的工具。 June 26 哈工大计算机学院研究生:北京“高企之旅”行程确定本次高企之旅由1位带队老师、7位博士生和3位硕士生共11人组成。 7月20日晚出发。 7月21日~7月25日访问百度、腾讯、微软、富士通、东芝、NEC等著名公司和研究院,进行技术交流、校友访谈和参观学习等。 好期待@FIGHTING!!!@^@ 近三年SIGGRAPH的papers on webSIGGRAPH2009的文章出来了,有空应该选择一些看一下了,把这三年的链接都收集过来。SIGGRAPH 2007 的papers on the webSIGGRAPH 2008 的papers on the webSIGGRAPH 2009 的papers on the web@FIGHTING@ Marathon Match 54Problem Statement In this problem you will solve a puzzle by placing tiles on a square board. You need to place all the tiles on the board, and can place each tile only once on the board. Each tile is square and contains four edges. Tiles can be placed rotated on the board. Your goal is to place all the tiles on the board such that the number of matching tile edges is maximized. 这个问题是要把瓷砖放到一个正方形面板上。需要把所有的瓷砖都放上,而且每个只能放一次。每个瓷砖是正方形且包含四条边。瓷砖可以被旋转之后再放到面板上。我们的目标是把所有的瓷砖放在面板上,使得相匹配的瓷砖的边的数量最大化。 面板包含N行N列。给定一个N*N的瓷砖列表,需要把所有瓷砖放到面板上。瓷砖每条边的颜色将从C个不同的颜色中选取。 代码要实现一个方法solvePuzzle。面板大小事N。vector <string> tiles 包含对将要放到面板上的瓷砖的描述;每个string是对一个瓷砖的定义。tiles 的每个元素的格式为"N E S W",这里N对应于北边的那条边的颜色,E对应于东边的那条边的颜色,S对应南边,W对应西边。颜色用一个整数描述。 方法要返回一个N*N的列表来制定瓷砖的摆放。返回值的每个元素的格式为"TILE ROTATION"。第i个元素对应于放在(i mod N)列(i div N)行位置上的瓷砖。"TILE"对应于vector <string> tiles中瓷砖的索引。"ROTATION" 可以是0,1,2,3。0 = 不旋转,1 = 顺时针旋转90°,2 = 旋转180°,3 = 顺时针旋转270°。 对于一个测试用例的得分是匹配边的数量除以N*(N-1)*2。这样,单个测试用例的最大得分是1。任何不合法的返回值都将得0分:如果将同一块瓷砖放在面板上多次,将得0分;如果没有把所有的瓷砖都放到面板上,将得0分。总得分将是在所有测试用例上的得分总和。 面板大小限制在[8,20],颜色数量限制在[10,30]。面板将被瓷砖随机填充使得每个相邻的边的颜色都匹配(查看visualizer的源代码来得到细节),然后瓷砖被提取出来并作为程序输入提供给你,且瓷砖已经被一个随机的旋转调整过了。 这是一个用于离线测试的工具。 To use the visualizer for testing your solution locally, you'll have to adopt your solution to read parameters from standard in and write the output to standard out. This doesn't affect the functioning of the solution you submit to our server. 要用它在本地测试我们的解决方案,必须采用标准的输入输出,这不会影响提交到服务器的解决方案的功能。 程序应该先读面板的大小N。然后读N*N行,每行对应于tiles数组的一个元素。最后要输出N*N行,每行对应于返回值的一个元素,标准输出。实现类似以下的伪代码: main
{
N = int(readLine())
for (i=0; i<N*N; i++)
tiles[i] = readLine()
ret = solvePuzzle(N, tiles)
for (i=0; i<N*N; i++)
printLine(ret[i])
flush(stdout)
}
To run the visualizer with your solution, you should run: java -jar Visualizer.jar -exec "<command>" -seed <seed> Here, <command> is the command to execute your program, and <seed> is seed for test case generation. Additionally you can use "-vis <name>" option to generate a file <name>.png which shows the board with the tiles you placed. White numbers indicates matching edges, while red numbers indicates edges that do not match their neighbors. The numbers corresponds to the color index of the each edge. If you set <name> to "-" (quotes for clarity only) for -vis, the image will be displayed in a window instead of written to the file. 要使用如上命令运行解决方案。这里<command>是执行程序的命令,<seed> 测试用例生成的种子。另外,我们可以使用附加选项 "-vis <name>" 生成一个<name>.png的图像来显示你生成的贴上瓷砖的面板。数字对应于每条边的颜色索引,白色数字表示边匹配了,红色数字表示相邻边没有匹配上。如果把附加选项命令中的<name>替换成“-”,则这幅图像会不是保存成文件,而是在一个Windows窗口中显示出来。 最后,我们可以打印解决方案中的任何调试信息到标准错误,它会被重定向到visualizer的标准输出。 @FIGHTING@ (6月25日 至 7月8日) 星期四 6月25日,早上1:00 CST CODING June 24 征战TopCoder(1):DP和Search还要加强今天上午参加了TopCoder的SRM443的比赛,第一次参加Single Round Match,总体感觉还可以,不过这是DIVi2的题,比较简单。 Coding阶段:第一道题做得有点慢,就是一道计数的题,只拿到160+分,很失误,没看清题目导致重新审题后调试修改花了过多的时间;第二道题做得很顺利,不到20分钟搞定,其实也简单,是道关于几何的题,但是只要理解正确了,编程序是So Easy的,题目是求从起点到终点至少需要跨越几个圆的边界,由于题目对圆之间的关系限制了不会相交,起点和终点又都不会在圆上,因此只要判断点是否在圆内并进行计数相加就Over了,这题得到了450+分;第三道题是个组合数量级的测试问题,问给定的线段长度组成K边的凸多边形有多少种不同的组合方法,而且提示了只要每条边长都严格大于剩余边长的总和即可构成凸多边形,这个问题可以用DP来解,时候在房间里讨论,有人确实是用DP做出来的,但是当时剩下半个小时的时候,我却久久的想不明白子问题怎么分解,导致最后时间不够用,没做完,这题0分。 Challenge阶段:这个阶段表现一般,跟上次有道复赛时相比差得远。分析一下,原因在于做得是DIV2的题,这些题相对比较简单,整一个大的随机数据去测自然成功率不高,但是估计在DIV1的话就会高一些了。有道复赛的时候出的题相对来说也是比较难的,而且第一题就有隐藏很深的陷阱在里面,所以我使用那个分析过大多数人都不考虑的数据去challenge竟然最终得到了200分。今天challenge的结果是-25分,成功challenge了2个,失败3个,但是都是运气challenge对的,之前基本没有仔细看别人代码,后来想了想,大致看一下代码很明显有些代码是对的,而有些代码是不对的,值得告诫自己的就是:对于简单题一定要看别人的代码,不能乱challenge。对于难的题在尽量challenge水平不太高的选手,可以尝试用大的随机数据,challenge他超时或者边界处理。 值得高兴的是:毕竟第一次比赛,得了1228分还是可以的,直接从白色标记升为蓝色标记,希望下次到DIV1去的时候能够保住蓝色标记。 需要加强的方面RT所说,今天的第三道题就是DP,但是没有在短时间内分析清楚,另外以前做DIV1的练习题发现用图论进行Search的问题很多,这也是我的软肋。加强这两个方面后,才有可能在DIV1站住脚,并向黄色标记冲击的,所以,加油吧~ June 23 严重检讨不知道有多长时间没有在MSN写日志了,好像都是上个世纪的事情了吧!大半年来活得不像个人了都,但是又没出什么成绩。真是羞愧难当。当初刚入学时,经常以MSN上的日志经常性的自我反省,感觉生活得很充实,每天都知道自己在干什么,要干什么;每件事情都知道收获了什么,需要反省的又是什么。可以后来的忙碌中,缺乏经常性的自我反省,导致现在回首这8个月来,真的是一塌糊涂! 从研究3D Geometry Reconstruction以来,在VH算法的基础上做了较多相关的编码工作,但是都是重复前人的工作,自己就是没有创新的点子。现在感觉仅仅从Geometry的角度来做是不可能超越前人了,毕竟从VH发明以来都十几二十年的事情了,必须加入场景的颜色、纹理的相关信息。概率VH在这些东西的融合上应该是一个重要的平台,而要找的只是一个支点,这个支点就是能够把别人没有用VH做过的问题拿过来做,方法本质上的创新真的已经很少了。 Master这第一年已经接近尾声,而自己内心却越来越不平静了。刚进来的时候觉得这里真是好,比undergraduate时候的氛围要好很多,但是一年之后,却又觉得要走出去了。一个矛盾出现了,人啊,最难以认识清楚的就是你自己。究竟是出去读博士,搞着所谓的学术和科研,一声平淡而平安的过完拉倒?还是及早走出这个小圈,跳到社会的熔炉中去,实现曾经的商业梦想?越到该抉择的时候却越是犹豫,无法专注的自身弱点重新凸显出来,很是痛苦。两位初中时代的学长已经邀我在学业之余一起搞个网站,我与最好的朋友也一起成立了一个技术性的工作室,我想我最终还是要去实现我的商业梦想的,但是读博和不读博最终只是导致梦想实现的性质和程度的差异吧。我仍然无法决断,还是一起准备吧。把自己的惰性彻底的从生命中过滤掉,去活出一个充实的人生,不管结果如何,都不会后悔的。 October 23 今天看来要失眠今天小先给我们做Lecture,将PR&&ML那本书的Chapter One,终于看到了这个和我同一级的帅哥对PR的理解程度,我与之的差距真是可用天壤之别来形容都不为过,那些数学推导完全是数学系学生才能有的素质,那种对于PR和ML的整体理解则是一个真正深入理解并实际干过东西并发过MIR文章的人才能有的水准,面对数十人的听讲,和其中的几位博士师兄探讨关于SVM、关于神经网络,并将Bayesian的理论理解的那么深入,镇静自如的回答师兄们的炮轰! 这就是和我同一级,坐在我侧对面,研究生一年级刚入学的小先! 这样的人和我在一起,我有什么理由不奋起直追呢?我晚上怎么能够高枕安睡呢? 同时我想说一句,以前在威海的时候总是觉得哈工大威海的学生不比总校学生差,得了吧,我现在真得承认,也许威海最优秀的学生不比总校的common student差,这个我信,但是威海的best student和总校的popular student相比就不是那么一回事儿了,我们在思维方式、学习方法和勤奋努力方面都和总校学生差的太远了,尤其是学术研究的思维上,我真是见识到了啊!所以吧,如果有威海的同学们看到这篇BLOG,不要在津津自乐于那句话,不要在嘴上抢风头,踏踏实实学好基础并多去参加科研吧!还有,看论文是必然的,尤其是英文论文,各个领域顶级会议的论文,不要说自己将来找工作,不搞科研,这不是理由,因为你只有看论文并试着照那些论文去做,才能掌握最先进的方法(当然前提是我们要打好数学和英语基础,并懂得运用它们),威海的部分老师并没有很高的科研的素质,所以不要说你进实验室帮老师编程序就是参加科研实践,其实还是有很大差别的。或许这也是很多本科生相对于研究生的差别!希望以后威海的同学能够有更高的科研素质。 小先昨天做公式推导到五点(今天凌晨5点),白天继续上课并完善PPT,没有睡觉,下午后两节有刘家峰老师的PR课,他不忍心耽误这门课,上完课是5:30分,他在课上有了更深的理解,因此下课后奔回实验室添加了10页左右的PPT来阐述他对VC维的概念以及在SVM中VC维总能有上界的这些东西的更深入理解,6:05分赶到A103开始给我们做这个Lecture,讲课持续了两个小时,讨论了半个多小时,课后有给个别同学解答疑问,然后我们一起回去,9:00小先下去黑店买披萨,这是他的下午饭!现在他又在工位上修改前几天写的专利申请书,并为MIR那篇文章写Poster的稿子!他说:我晚上11点之前是不可能睡觉的! 我怎么能安睡?! October 19 检点上周工作周末又将结束,检查一下上周工作,读书上的任务基本都完成了,但是编程上的练习还是差很多,自从进研究生以来论文看的颇多,编程练习太少,导致现在怎么也拣不起以前那种感觉了,这正是火烧眉毛的时候,编程要迅速是拾起来,从今天晚上开始吧! October 12 下午要做Presentation根据纪师兄的建议,要按照一种理出世界上在本领域所有研究组及其研究优势和特点的方法去读论文,按图索骥,并列出表来,更好的是列出一个restraint的列表。这样才能将Review做出立体的感觉。问自己一个问题:当前最热的点是哪些?最新的方法有哪些?谁在做? 这样弄了一个多星期,但是由于对于这个领域的基础知识欠缺太多,想要整体把握真的是不太现实。往往是大量访问SIGGRAPH/CVPR的作者主页,知道他们连年发文章,也看一下他们publications的题目,相关性较大的看一下Abstract,但是往往对这些东西并没有真正理解掉,所以也很难形成系统,铭刻在心。 昨天下午在Group里做Review的报告,由于时间问题,我讲的不是很仔细。于是在匆匆忙忙之中,由于我展示的搜集资料很多,大家貌似觉得我的Review还不错,但是我自己明白,对于上面那三个问题,我还是不能很好很明确的回答。我的Review其实大部分停留在2003年以前,来源于一些Survey,对于06、07、08的CVPR的相关paper虽然看了很多,也都做了笔记,但是并没有真正提炼出最热的研究点在哪里,并且他们那些方法也并没有能够分出类来整理一下。这是需要继续做的事情。 本周在看一本《3D数学基础》的书,补充一下3D图形学的基础数学知识,我觉得还是很有必要的,收获也比较大,至少在推理方面,对于射影几何怎样从线性代数的角度表示出来并进行计算有了一些了解,需要批评的是,即使对于这样一本比较通俗易懂的书,我的进度太慢了,至今才看完第十章。下周必须完成的任务之一就是看完这本书并将笔记整理出来,以备以后查阅。 本周的任务艰巨,读书方面:数学基础看完,OpenGL红宝书开始看,尽量完成前三章,并选做一些书上的例子。在数学基础充实以后,看这本书的前面部分应该会比较快吧:-)。算法导论,把动态规划部分看一下,可能要用。 在编程上,现在只做到实现了张正友的定标算法,并做出重建视差图,对于Rendering丝毫没有涉及,但是下周还是把重建视差图做好,自定标的最新论文再温习一下,有一篇做出视频序列的real time视差图的CVPR文章开始着手实现一下,Fighting@ 英语方面,本周还有一个presentation要做,呵呵,上周的演讲效果还不错,第一轮居然没有被淘汰,A Touching Moment,写的老爸对我的爱,自己还是狠狠的感动了一回,好好爱家!OK啦,明天开始奋斗吧,路还很长,一步一步走踏实才好! October 01 十一放假了实验室的网络终于无法再忍受了 服务器又Down掉了 昨天买了笔记本,以后可以在寝室里办公了 虽然这里的网费比威海要贵好多,而且有强取豪夺的架势 但是,所有网站都可以无阻碍的登陆上去,所以,我忍了! 争取十一期间,将3D Reconstruction的Review做完 拿出一个方案,做一个平台出来。 哪怕是最粗糙的...Fighting! |
||||
|
|