source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/image3dstiching/MetricRecon.m @ 86

Last change on this file since 86 was 37, checked in by (none), 15 years ago

Added original make3d

File size: 16.5 KB
Line 
1% *  This code was used in the following articles:
2% *  [1] Learning 3-D Scene Structure from a Single Still Image,
3% *      Ashutosh Saxena, Min Sun, Andrew Y. Ng,
4% *      In ICCV workshop on 3D Representation for Recognition (3dRR-07), 2007.
5% *      (best paper)
6% *  [2] 3-D Reconstruction from Sparse Views using Monocular Vision,
7% *      Ashutosh Saxena, Min Sun, Andrew Y. Ng,
8% *      In ICCV workshop on Virtual Representations and Modeling
9% *      of Large-scale environments (VRML), 2007.
10% *  [3] 3-D Depth Reconstruction from a Single Still Image,
11% *      Ashutosh Saxena, Sung H. Chung, Andrew Y. Ng.
12% *      International Journal of Computer Vision (IJCV), Aug 2007.
13% *  [6] Learning Depth from Single Monocular Images,
14% *      Ashutosh Saxena, Sung H. Chung, Andrew Y. Ng.
15% *      In Neural Information Processing Systems (NIPS) 18, 2005.
16% *
17% *  These articles are available at:
18% *  http://make3d.stanford.edu/publications
19% *
20% *  We request that you cite the papers [1], [3] and [6] in any of
21% *  your reports that uses this code.
22% *  Further, if you use the code in image3dstiching/ (multiple image version),
23% *  then please cite [2].
24% * 
25% *  If you use the code in third_party/, then PLEASE CITE and follow the
26% *  LICENSE OF THE CORRESPONDING THIRD PARTY CODE.
27% *
28% *  Finally, this code is for non-commercial use only.  For further
29% *  information and to obtain a copy of the license, see
30% *
31% *  http://make3d.stanford.edu/publications/code
32% *
33% *  Also, the software distributed under the License is distributed on an
34% * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
35% *  express or implied.   See the License for the specific language governing
36% *  permissions and limitations under the License.
37% *
38% */
39function [defaultPara ImgInfo fail] = MetricRecon(defaultPara, ImgInfo)
40
41% This function do Metric Reconstruction for a pair of images
42% Step outline:
43%       1) Mono calulation
44%       2) Robust Pose and Match generation
45%       3) Dense match
46%       4) Re-inference
47%       5) Coherence Texture Process
48%       6) Volumatric refining
49%       7) Rendering
50%
51% Input:
52%       1) defaultPara - camera intrinsic, ....etc.
53%       2) ImgInfo - special structure with Exif, GPS, IMU, Model info
54%
55% Return:
56%       1) TriPoint - Triangluated point
57
58Debug = 0;
59NumPcik = 10;
60fail= 0;
61
62% Parameter Setting
63Img1 = ImgInfo(1).ExifInfo.IDName;
64Img2 = ImgInfo(2).ExifInfo.IDName;
65disp([ 'Processing ' Img1 ' & ' Img2]);
66I1=imreadbw([defaultPara.Fdir '/pgm/' Img1 '.pgm']); % function from sift
67I2=imreadbw([defaultPara.Fdir '/pgm/' Img2 '.pgm']); % function from sift               
68ImgScale1 = size(I1);
69ImgScale2 = size(I2);
70[Img1Index] = ImgInfoIndexFromName(ImgInfo, Img1);
71[Img2Index] = ImgInfoIndexFromName(ImgInfo, Img2);
72NegI = diag([1 1 -1]);
73
74% 1. Mono calulation or load the pre-calculated data ------------------------
75[ ImgInfo] = SingleModelInfo(defaultPara, ImgInfo);
76
77% 2. Robust Pose and Match generation ---------------------------------------------
78if defaultPara.Flag.PoseMatches
79        [Pair, ImgInfo, Matches, fail] = PoseMatchEst(defaultPara, ImgInfo);
80        Pair.matches = Matches;
81        if fail > 0             
82                disp('End of Metric Reconstruction');
83                return;
84        end
85        if defaultPara.Flag.PoseMatchStor
86                save([ defaultPara.Fdir '/data/' Img1 '_' Img2 '_PoseMatch.mat'],'Pair','Matches','fail');
87        end
88end
89% To Check if Placing MonoModel using R T make sense
90% Indep_Mono_Model_CheckRT(defaultPara, ImgInfo, R, T);
91
92% 3. Re-inference -----------------------------------------------------------------
93[status1, result] = system(['ls ' defaultPara.Fdir '/data/' Img1 '/' defaultPara.Wrlname '_' Img1 '_NonMono.mat']);
94[status2, result] = system(['ls ' defaultPara.Fdir '/data/' Img2 '/' defaultPara.Wrlname '_' Img2 '_NonMono.mat']);
95if defaultPara.Flag.ReInference || status1 || status2
96        if ~defaultPara.Flag.PoseMatches
97                [Pair, Matches, fail] = LoadPoseMatch(defaultPara.Fdir, Img1, Img2);
98                Pair.matches = Matches;
99        end
100     [defaultPara ImgInfo] = PairReInferenceSepRender(defaultPara, Pair, ImgInfo, defaultPara.Flag.FlagFirstPair);
101end
102
103% 4. Pair-Wise Occlusion detection and Corrolation Matching ----------------------------------------------------
104if defaultPara.Flag.Refinement
105        if ~defaultPara.Flag.ReInference && ~defaultPara.Flag.PoseMatches
106                [ImgInfo1 ImgInfo2 Img1Index Img2Index Pair GlobalScale] = ... % only deal with pairs have been matched
107                        LoadDataForFindOcclu(defaultPara, defaultPara.Wrlname, Img1, Img2, ...
108                        defaultPara.Flag.FlagImgInfoLoadPreStorage); % load all imformation needed for occlusion detection
109                ImgInfo = [ImgInfo1 ImgInfo2];
110        else
111                GlobalScale(1) = LoadModelStatus(defaultPara.Fdir, defaultPara.Wrlname, Img1, 'Scale');
112                GlobalScale(2) = LoadModelStatus(defaultPara.Fdir, defaultPara.Wrlname, Img2, 'Scale');
113        end
114
115        % First to Occlusion detection
116        % time consuming about 5mins
117        disp('Start Surf Feature Point Occlusion detection');
118        [status, result] = system(['ls ' defaultPara.Fdir '/data/' Img1 '_' Img2 '_' defaultPara.PostFixStrAfter '_OccluDetect_Match.mat']);
119        if ~defaultPara.Flag.FlagPreloadOccluDetectMatches || status
120                s = warning('off');
121                [PointPix1 PointDepth1 FaceSetPickedIND1 POriReprojM1 FieldOccluPix1 OccluDist1 OccluedFaceSetIND1 OccluedFaceSetIDRemained1...
122                PointPix2 PointDepth2 FaceSetPickedIND2 POriReprojM2 FieldOccluPix2 OccluDist2 OccluedFaceSetIND2 OccluedFaceSetIDRemained2] = ...
123                FindOccluPair(defaultPara, ImgInfo(1), ImgInfo(2), Pair, GlobalScale, 1); % detect occlsion (use Ray as detector not the surf Features)
124                % data Struction define:
125                % PointPix PointDepth FaceSetPickedIND POriReprojM FieldOccluPix OccluDist OccluedFaceSetIND
126                % -- allof the size that single ray pass through both FaceSet
127                % FaceSetPickedIND1 used in DepthMap size or surfFeature size
128                % OccluedFaceSetIND1 used in DepthMap size
129                save([ defaultPara.Fdir '/data/' Img1 '_' Img2 '_' defaultPara.PostFixStrAfter '_OccluDetect_Match.mat'],...
130                'PointPix1','PointDepth1','FaceSetPickedIND1','POriReprojM1','FieldOccluPix1','OccluDist1',...
131                        'OccluedFaceSetIND1','OccluedFaceSetIDRemained1', ...
132                'PointPix2','PointDepth2','FaceSetPickedIND2','POriReprojM2','FieldOccluPix2','OccluDist2',...
133                        'OccluedFaceSetIND2','OccluedFaceSetIDRemained2');
134                s = warning('on');
135        else
136                load([defaultPara.Fdir '/data/' Img1 '_' Img2 '_' defaultPara.PostFixStrAfter '_OccluDetect_Match.mat']);
137        end       
138       
139        % Define occlusion if OccluDist > CentainThreshold
140        if defaultPara.Flag.FlagRecipicalOccluDetection
141                Mask1 = PointDepth1./OccluDist1 > defaultPara.OcclusionRatioThre | OccluDist1./PointDepth1 > defaultPara.OcclusionRatioThre;
142                Mask2 = PointDepth2./OccluDist2 > defaultPara.OcclusionRatioThre | OccluDist2./PointDepth2 > defaultPara.OcclusionRatioThre;
143        else
144                Mask1 = PointDepth1./OccluDist1 > defaultPara.OcclusionRatioThre;%defaultPara.OccluDistThre;
145                Mask2 = PointDepth2./OccluDist2 > defaultPara.OcclusionRatioThre;%defaultPara.OccluDistThre;
146        end
147
148        % Second do Surf Features Matches given Occlusion infomation
149        disp('Start Finding Surf Feature Point Occlusion Match');
150        [status, result] = system(['ls ' defaultPara.Fdir '/data/' Img1 '_' Img2 '_SurfOccluMatches.mat']);
151    if defaultPara.Flag.LoadStoragedSurfOccluMatches && ~status
152        load([defaultPara.Fdir '/data/' Img1 '_' Img2 '_SurfOccluMatches.mat']);
153        SurfMatches = matches;
154    else
155        [SurfMatches fail] = MatchPointsGivenOcclusion(defaultPara, ImgInfo(1), ImgInfo(2), ImgScale1, ImgScale2, ...
156            Img1, Img2, Img1Index, Img2Index, ...
157            Pair,  GlobalScale, defaultPara.Wrlname, 'SurfOccluMatches', ...
158            POriReprojM1(:,Mask1), FieldOccluPix1(:,Mask1), FaceSetPickedIND1(:,Mask1), ...
159            POriReprojM2(:,Mask2), FieldOccluPix2(:,Mask2), FaceSetPickedIND2(:,Mask2), true );
160    end   
161    if fail > 0         
162                disp('End of Metric Reconstruction');
163                return;
164    end
165   
166        % 6. Pair-Wise Robust Pose and Match generation (Second time) given the new Occlusion Matches
167        % ===== Debug Only
168        if defaultPara.Flag.FlagStorageBeforePairNew
169                disp('Storaging Data Before Runing PairNew');
170                save([defaultPara.Fdir '/data/' Img1 '_' Img2 '_BeforePairNew.mat']);
171        end
172        % ===============
173        PriorPose.R = [Pair.R; Pair.R'];
174        PriorPose.T = [Pair.T; -Pair.R'*Pair.T];
175    [status, result] = system(['ls ' defaultPara.Fdir '/data/' Img1 '_' Img2 '_PairNew.mat']);
176    if ~defaultPara.Flag.loadStoragedPairNew || status
177        [PairNew fail]=TestWholePostMatch(defaultPara, ImgInfo(1), ImgInfo(2), PriorPose);
178        if defaultPara.Flag.FlagStorageAfterPairNew           
179            save([defaultPara.Fdir '/data/' Img1 '_' Img2 '_PairNew.mat'],'PairNew','fail');
180        end
181    else
182        load([defaultPara.Fdir '/data/' Img1 '_' Img2 '_PairNew.mat']);
183    end   
184    if fail > 0         
185                disp('End of Metric Reconstruction');
186                return;
187    end
188   
189        % Given PairNew info do Correlation Matches
190        % Need to detect Occlusion for Correlation matches
191        % time consuming about 5mins
192        disp('Start Ray Point Occlusion detection');
193        [status, result] = system(['ls ' defaultPara.Fdir '/data/' Img1 '_' Img2 '_' defaultPara.PostFixStrAfter '_OccluDetect_Ray.mat']);
194        if ~defaultPara.Flag.FlagPreloadOccluDetectRay || status
195                s = warning('off');
196                [PointPix1 PointDepth1 FaceSetPickedIND1 POriReprojM1 FieldOccluPix1 OccluDist1 OccluedFaceSetIND1 OccluedFaceSetIDRemained1...
197                PointPix2 PointDepth2 FaceSetPickedIND2 POriReprojM2 FieldOccluPix2 OccluDist2 OccluedFaceSetIND2 OccluedFaceSetIDRemained2] = ...
198                FindOccluPair(defaultPara, ImgInfo(1), ImgInfo(2), Pair, GlobalScale, false); % detect occlsion (use Ray as detector not the surf Features)
199                % data Struction define:
200                % PointPix PointDepth FaceSetPickedIND POriReprojM FieldOccluPix OccluDist OccluedFaceSetIND
201                % -- allof the size that single ray pass through both FaceSet
202                % FaceSetPickedIND1 used in DepthMap size or surfFeature size
203                % OccluedFaceSetIND1 used in DepthMap size
204                save([ defaultPara.Fdir '/data/' Img1 '_' Img2 '_' defaultPara.PostFixStrAfter '_OccluDetect_Ray.mat'],...
205                'PointPix1','PointDepth1','FaceSetPickedIND1','POriReprojM1','FieldOccluPix1','OccluDist1',...
206                        'OccluedFaceSetIND1','OccluedFaceSetIDRemained1', ...
207                'PointPix2','PointDepth2','FaceSetPickedIND2','POriReprojM2','FieldOccluPix2','OccluDist2',...
208                        'OccluedFaceSetIND2','OccluedFaceSetIDRemained2');
209                s = warning('on');
210        else
211                load([defaultPara.Fdir '/data/' Img1 '_' Img2 '_' defaultPara.PostFixStrAfter '_OccluDetect_Ray.mat']);
212        end       
213               
214        % Define occlusion if OccluDist > CentainThreshold
215        if defaultPara.Flag.FlagRecipicalOccluDetection
216                Mask1 = PointDepth1./OccluDist1 > defaultPara.OcclusionRatioThre | OccluDist1./PointDepth1 > defaultPara.OcclusionRatioThre;
217                Mask2 = PointDepth2./OccluDist2 > defaultPara.OcclusionRatioThre | OccluDist2./PointDepth2 > defaultPara.OcclusionRatioThre;
218        else
219                Mask1 = PointDepth1./OccluDist1 > defaultPara.OcclusionRatioThre;%defaultPara.OccluDistThre;
220                Mask2 = PointDepth2./OccluDist2 > defaultPara.OcclusionRatioThre;%defaultPara.OccluDistThre;
221        end
222
223        disp('Start Finding Ray Point Occlusion Match');
224        [status, result] = system(['ls ' defaultPara.Fdir '/data/' Img1 '_' Img2 '_CorrMatches.mat']);
225        if defaultPara.Flag.LoadCorrMatches && ~status
226                load([defaultPara.Fdir '/data/' Img1 '_' Img2 '_CorrMatches.mat']);
227                CorrMatches = Matches;
228    else
229        % debuging purpose ==========
230        if Debug
231            Mask1 = find(Mask1);
232            Mask2 = find(Mask2);           
233            RandPcik1 = randperm(length(Mask1));
234            NumPcik1 = min(NumPcik,length(Mask1));
235            Mask1 = Mask1(RandPcik1(1:NumPcik1));
236            RandPcik2 = randperm(length(Mask2));
237            NumPcik2 = min(NumPcik,length(Mask2));
238            Mask2 = Mask2(RandPcik2(1:NumPcik));
239        end   
240        % ===========================
241                CorrTime = tic;
242                fprintf(' Running CorrMatches ........');
243                [ CorrMatches]=CorrMatchPointsGivenOcclusion( ...
244                        defaultPara, PairNew, GlobalScale,...
245                        POriReprojM1(:,Mask1), FieldOccluPix1(:,Mask1), PointPix1(:,Mask1),...
246                        POriReprojM2(:,Mask2), FieldOccluPix2(:,Mask2), PointPix2(:,Mask2),...
247                        ImgInfo(1), ImgInfo(2), ImgScale1, ImgScale2, ...
248                        true);
249                disp(['         ' num2str( toc( CorrTime)) ' seconds.']);
250        end
251
252        % Remove redundant matches in SurfMatches & CorrMatches
253        Coeff = [ones(1, size(SurfMatches, 2)) zeros(1, size(CorrMatches, 2))];
254        AllMatches = [ SurfMatches CorrMatches];
255        [Inliers] = CleanMatch(AllMatches, Coeff);
256        [ReverseInliers] = CleanMatch(AllMatches([3 4 1 2], Inliers), Coeff(Inliers));
257        Inliers = Inliers(ReverseInliers);
258        AllMatches = AllMatches(:,Inliers);     
259
260        % triangulate depth and put into constrain for inference
261        if ~isempty(AllMatches)%
262                disp('Start Triangluation and Storage constrain for inference');
263                PostFixStrAfter = 'NewPair';
264                tempf1 = AllMatches(1:2,:);
265                tempf2 = AllMatches(3:4,:);
266                x_calib = [ inv(defaultPara.InrinsicK1)*[ tempf1; ones(1,size(tempf1,2))];...
267                inv(defaultPara.InrinsicK2)*[ tempf2; ones(1,size(tempf2,2))]];
268                [ lamda1 lamda2 Error] = triangulation( defaultPara, Pair.R, Pair.T, x_calib);
269                % notice lamda re-scale to local model scale
270                lamda1 = lamda1./GlobalScale(1);
271                lamda2 = lamda2./GlobalScale(2);
272                % Storage the match result for later ReInference
273                AddMatch2Model(defaultPara, defaultPara.Wrlname, lamda1, AllMatches(1:2,:), ImgInfo(1), ImgScale1, Img1Index, Img2Index, PostFixStrAfter, Error);
274                AddMatch2Model(defaultPara, defaultPara.Wrlname, lamda2, AllMatches(3:4,:), ImgInfo(2), ImgScale2, Img2Index, Img1Index, PostFixStrAfter, Error);
275                % Storage the New Matches                   
276                if defaultPara.Flag.FlagRefinementDisp
277                        disp('Storaging Occlusion Correlation Matches');
278                        save([defaultPara.Fdir '/data/' Img1 '_' Img2 '_AllMatches.mat'],'AllMatches','Error');
279                end
280        end
281
282
283        % 7. Re-inference ------ with new Pose and Matchese
284        if defaultPara.Flag.RefinementInference
285                % For Img1 ======================================================
286                disp('PaieNew Inference for Img1');
287                % Data preparing and ReInfernece
288                Default.Wrlname{1} = [defaultPara.Wrlname '_' Img1 '_' PostFixStrAfter];   
289                load([defaultPara.Fdir '/data/' Img1 '/' defaultPara.Wrlname '_' Img1 '_' PostFixStrAfter '.mat']);
290                R = LoadModelStatus( defaultPara.Fdir, defaultPara.Wrlname, Img1, 'R');
291                T = LoadModelStatus( defaultPara.Fdir, defaultPara.Wrlname, Img1, 'T');
292                Scale = LoadModelStatus(defaultPara.Fdir, defaultPara.Wrlname, Img1, 'Scale');
293                GroundLevel = LoadModelStatus(defaultPara.Fdir, defaultPara.Wrlname, Img1, 'GroundLevel');
294                SingleImgReInference(defaultPara, model, Img1, GroundLevel, defaultPara.Wrlname, ...
295                        R, T, Scale ,PostFixStrAfter);
296
297                %   Build Meta Wrl file =========
298                Path = [ defaultPara.OutPutFolder defaultPara.Wrlname '_' PostFixStrAfter '.wrl'];
299                InLinePath = ['./'  Img1 '/' Default.Wrlname{1} '.wrl'];
300                Q = Rotation2Q(NegI*R*NegI);% for Wrl (-) z component;
301                if any(isnan(Q))
302                        Q = zeros(4,1);
303                end
304                WRLT = T;
305                WRLT(3) = -WRLT(3);% for Wrl (-) z component;
306                Scale = LoadModelStatus(defaultPara.Fdir, defaultPara.Wrlname, Img1, 'Scale');
307                [status, result] = system(['ls ' Path]);
308                if status
309                        BuildVrmlMetaModel(1, defaultPara.OutPutFolder, Path, InLinePath, Q, WRLT, repmat(Scale,3,1));
310                else
311                        BuildVrmlMetaModel(0, defaultPara.OutPutFolder, Path, InLinePath, Q, WRLT, repmat(Scale,3,1));
312                end
313                % ===============================
314
315                % For Img2 ===================================
316                disp('PaieNew Inference for Img2');
317                % Data preparing and ReInfernece
318                Default.Wrlname{1} = [defaultPara.Wrlname '_' Img2 '_' PostFixStrAfter];   
319                load([defaultPara.Fdir '/data/' Img2 '/' defaultPara.Wrlname '_' Img2 '_' PostFixStrAfter '.mat']);
320                T = T + R*(-PairNew.R'*(PairNew.T/PairNew.DepthScale(1)*Scale ));
321                R = R*PairNew.R';
322                Scale = PairNew.DepthScale(2)/PairNew.DepthScale(1)*Scale;
323                SingleImgReInference(defaultPara, model, Img2, GroundLevel, defaultPara.Wrlname, ...
324                        R, T, Scale ,PostFixStrAfter);
325
326                %   Build Meta Wrl file =========
327                Path = [ defaultPara.OutPutFolder defaultPara.Wrlname '_' PostFixStrAfter '.wrl'];
328                InLinePath = ['./'  Img2 '/' Default.Wrlname{1} '.wrl'];
329                Q = Rotation2Q(NegI*R*NegI);% for Wrl (-) z component;
330                if any(isnan(Q))
331                        Q = zeros(4,1);
332                end
333                WRLT = T;
334                WRLT(3) = -WRLT(3);% for Wrl (-) z component;
335                Scale = LoadModelStatus(defaultPara.Fdir, defaultPara.Wrlname, Img2, 'Scale');
336                [status, result] = system(['ls ' Path]);
337                if status
338                        BuildVrmlMetaModel(1, defaultPara.OutPutFolder, Path, InLinePath, Q, WRLT, repmat(Scale,3,1));
339                else
340                        BuildVrmlMetaModel(0, defaultPara.OutPutFolder, Path, InLinePath, Q, WRLT, repmat(Scale,3,1));
341                end
342                % Storge the New GlobalPose info of Img2
343                SaveModelSatus( defaultPara, defaultPara.Wrlname, {Img1,Img2}, GroundLevel, R, T, Scale, defaultPara.Flag.FlagFirstPair);
344                % ==============================
345        end
346end
347
348disp('End of Metric Reconstruction');
349return;
350
Note: See TracBrowser for help on using the repository browser.