source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/image3dstiching/PosrEst/PoseMatchEst.m @ 37

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

Added original make3d

File size: 15.3 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 [Pair ImgInfo matches fail]=PoseMatchEst(defaultPara, ImgInfo)
40
41% This function estimate the relative Pose of the camera using first camera coordinate
42% as world coordinate
43
44% Input:
45%       default - camera intrinsic, etc
46%       ImgInfo - Exif, Model info, GPS, IMU info
47%
48% Return:       
49%       R - rotation - (R*Posi2+ T to A's coordinate)
50%       T - translation
51
52% step outline
53%       1) extract Measuesd Position and orientation from GPS or IMU info
54%       2) Using Measures R and T and Mono-Depth to define mach search space constrain
55%       3) Do match search with all combinations satisfying Constrain from 2) using ralative threshould
56%       4) Ransac
57%       5) Bundle Adjustment
58%       6) up to scale translation reconstruction
59%       7) matches 3D triangulation
60%       8) Modified ImgInfo.Model.Depth up to accurate scale
61
62% initialize variables
63fail = 0;
64Pair.R = [];
65Pair.t = [];
66Pair.Xim = [];
67Pair.DepthScale = [];
68
69Img1 = ImgInfo(1).ExifInfo.IDName;
70Img2 = ImgInfo(2).ExifInfo.IDName;
71I1=imreadbw([defaultPara.Fdir '/pgm/' Img1 '.pgm']); % function from sift
72I2=imreadbw([defaultPara.Fdir '/pgm/' Img2 '.pgm']); % function from sift
73[f1] = readSurf(Img1, defaultPara.Fdir, 'Dense'); % Dense features
74[f2] = readSurf(Img2, defaultPara.Fdir, 'Dense'); % Dense features
75[D1 IND] = PorjPosi2Depth(size(I1), size(ImgInfo(1).Model.Depth.FitDepth), f1, ImgInfo(1).Model.Depth.FitDepth);
76[D2 IND] = PorjPosi2Depth(size(I2), size(ImgInfo(2).Model.Depth.FitDepth), f2, ImgInfo(1).Model.Depth.FitDepth);
77
78% 1) extract Measuesd Position and orientation from GPS or IMU info
79% Depends on what data we have, MeasR or MeasT, or both might be empty
80[MeasR MeasT] = InitPoseMeas(defaultPara, ImgInfo(1), ImgInfo(2));
81
82if ~isempty(MeasR)
83        % 2) Using Measures R and T and Mono-Depth to define match search space constrain
84        % read in all surf features
85        [ Rc1, Rc2, ConS1, ConS2, ConSRough1, ConSRough2] = CalMatchSearchRegin(defaultPara, MeasR, MeasT, I1, I2, f1, f2, D1, D2, 1, defaultPara.Flag.FlagDisp);
86
87        % write the match search space constrain in to files for surfMatchRConS.sh script to read
88        Vector2Ipoint([Rc1; ConS1],[defaultPara.Fdir '/surf/'],['RConS_' Img1]);
89        Vector2Ipoint([Rc2; ConS2],[defaultPara.Fdir '/surf/'],['RConS_' Img2]);
90        Vector2Ipoint([ConSRough1],[defaultPara.Fdir '/surf/'],['RConSRough_' Img1]);
91        Vector2Ipoint([ConSRough2],[defaultPara.Fdir '/surf/'],['RConSRough_' Img2]);
92
93        % 3) Do match search with all combinations satisfying Constrain from 2) using ralative threshould
94        cd match
95        [status, result] = system(['ls ' defaultPara.Fdir '/surf_matches/' Img1 '-' Img2 '.matchRConSDense_' num2str(defaultPara.AbsThre) '_' num2str(defaultPara.RatioThre)]);
96        [statusReverse, resultReverse] ...
97                         = system(['ls ' defaultPara.Fdir '/surf_matches/' Img2 '-' Img1 '.matchRConSDense_' num2str(defaultPara.AbsThre) '_' num2str(defaultPara.RatioThre)]);
98        if status && statusReverse
99                SurfMatchTime = tic;
100                system(['./surfMatchRConS.sh ' defaultPara.Fdir ' ' Img1 ' ' Img2 ' Dense ' num2str(defaultPara.AbsThre) ' ' num2str(defaultPara.RatioThre)]);
101                disp(['         ' num2str( toc( SurfMatchTime)) ' seconds.']);
102        end   
103        cd ..
104else
105        cd match
106        [status, result] = system(['ls ' defaultPara.Fdir '/surf_matches/' Img1 '-' Img2 '.matchDense_' num2str(defaultPara.AbsThre) '_' num2str(defaultPara.RatioThre)]);
107        [statusReverse, resultReverse] ...
108                         = system(['ls ' defaultPara.Fdir '/surf_matches/' Img2 '-' Img1 '.matchDense_' num2str(defaultPara.AbsThre) '_' num2str(defaultPara.RatioThre)]);
109        if status && statusReverse
110                SurfMatchTime = tic;
111                system(['./surfMatch.sh ' defaultPara.Fdir ' ' Img1 ' ' Img2 ' Dense ' num2str(defaultPara.AbsThre) ' ' num2str(defaultPara.RatioThre)]);
112                disp(['         ' num2str( toc( SurfMatchTime)) ' seconds.']);
113        end   
114        cd ..
115end
116% 4. Ransac
117if ~isempty(MeasR)
118        [f1, f2, matches] = readSurfMatches(Img1, Img2, defaultPara.Fdir, ...
119                                [ defaultPara.Type 'Dense_' num2str(defaultPara.AbsThre) '_' num2str(defaultPara.RatioThre)], 1, 1);
120else
121        [f1, f2, matches] = readSurfMatches(Img1, Img2, defaultPara.Fdir, ...
122                                [ 'Dense_' num2str(defaultPara.AbsThre) '_' num2str(defaultPara.RatioThre)], 1, 1);
123end
124if isempty(matches)
125   disp('Zeros Surf matches');
126   fail = 1;
127   return;
128end   
129[D1 IND1] = PorjPosi2Depth(size(I1), size(ImgInfo(1).Model.Depth.FitDepth), f1(:,matches(1,:)), ImgInfo(1).Model.Depth.FitDepth);
130[D2 IND2] = PorjPosi2Depth(size(I2), size(ImgInfo(2).Model.Depth.FitDepth), f2(:,matches(2,:)), ImgInfo(1).Model.Depth.FitDepth);
131
132% Ensemble method to determine confidence of inliers
133fittingfn = @fundmatrix;
134distfnEnsmble = @fundistEnsmble;
135degenfn   = @isdegenerate;
136nmatches = size(matches, 2);
137x = [[f1(:, matches(1,:)); ones(1, nmatches)]; [f2(:, matches(2,:)); ones(1, nmatches)]];
138[ SampsonDist ] = EnsembleRansac(defaultPara, x, fittingfn, distfnEnsmble, degenfn, 8, ones(1,nmatches)', min(nmatches*10, defaultPara.MAXEnsembleSamples), 0);
139kurtosisValue =kurtosis(SampsonDist');
140
141% Ransac
142[F0, inliers, NewDist, fail, ind]=GeneralRansac(defaultPara, f1, f2, matches, D1, D2, kurtosisValue', 8);
143if defaultPara.Flag.FlagDisp
144    figure; plotmatches(I1,I2,f1, f2,matches(:,inliers), 'Stacking', 'v', 'Interactive', defaultPara.Flag.FlagDisp);
145end   
146% *** Stop maunally to pick out the bad matches*** -----------------
147matches = matches(:,inliers);
148if isempty(matches)
149   disp('Zeros Matches After Ransac');
150   fail = 2;
151   return;
152end
153% ------------------------------------------------------------------
154
155x_calib = [ inv(defaultPara.InrinsicK1)*[ f1(:,matches(1,:)); ones(1,length(matches))];...
156              inv(defaultPara.InrinsicK2)*[ f2(:,matches(2,:)); ones(1,length(matches))]];
157
158% Estimate F using NonLine LS on every inlier
159MatchDensityWeights1 = CalMatchDensityWeights(f1(:,matches(1,:)), max(size(I1))/defaultPara.radius2imageSizeRatio);
160MatchDensityWeights2 = CalMatchDensityWeights(f2(:,matches(2,:)), max(size(I2))/defaultPara.radius2imageSizeRatio);
161MatchDensityWeights =mean([MatchDensityWeights1; MatchDensityWeights2], 1);
162F = getFnpt( F0, f1(:, matches(1,:))',  f2(:, matches(2,:))', MatchDensityWeights);
163E = defaultPara.InrinsicK2'*F*defaultPara.InrinsicK1; % Camera essential Matrix
164if ~isempty(MeasR)
165        [ R0, T0, lamda1, lamda2, inlier, Error] = EstPose( defaultPara, E, x_calib, [], MeasR(1:3,:));
166else
167        [ R0, T0, lamda1, lamda2, inlier, Error] = EstPose( defaultPara, E, x_calib, [], []);
168end
169T0 = [T0; - R0'*T0];
170R0 = [R0; R0'];
171matches = matches(:,inlier); % delet matches give negative depths
172x_calib = x_calib(:,inlier);
173lamda1 = lamda1(inlier);
174lamda2 = lamda2(inlier);
175
176% Estimated X_obj by triangulation
177X_obj_1 = x_calib(1:3,:).*repmat(lamda1, 3, 1);
178X_obj_2 = R0(4:6,:)*(x_calib(4:6,:).*repmat(lamda2, 3, 1)) + repmat(T0(4:6), 1, size(matches,2));
179X_obj = (X_obj_1+X_obj_2)/2;
180
181% 5. Bundle Adjustment
182[R T X_obj_BA X_im_BA dist1_BA dist2_BA]=SparseBAWraper(defaultPara, R0(1:3,:), T0(1:3), [f1(:,matches(1,:)); f2(:,matches(2,:))], X_obj, ImgInfo, 1);
183if all(isnan( dist1_BA)) || isempty(R) || any(isnan(R(:)))
184        disp('BA failed');
185        fail = 3;
186        return;
187end
188while length(X_im_BA) >= defaultPara.MinimumNumMatches
189        outlier_thre1 = prctile(dist1_BA,90);
190        outlier_thre2 = prctile(dist2_BA,90);
191        Outlier = logical(zeros( size( dist1_BA)));
192        if max(dist1_BA) >= defaultPara.ReProjErrorThre
193%               Outlier = Outlier | dist1_BA > max( outlier_thre1, defaultPara.ReProjErrorThre);
194                Outlier = Outlier | dist1_BA > outlier_thre1;       
195        end
196        if max(dist2_BA) >= defaultPara.ReProjErrorThre
197%               Outlier = Outlier | dist2_BA > max( outlier_thre2, defaultPara.ReProjErrorThre);
198        Outlier = Outlier | dist2_BA > outlier_thre2;
199        end
200        matches(:,Outlier) = [];
201        if isempty(matches)
202            disp('Zeros Matches After BA Pruning');
203            fail = 4;
204            return;
205        end
206        if all( Outlier == 0)
207                % Non Outlier detected for BA
208                break;
209        end
210        lamda1(Outlier) = [];
211        lamda2(Outlier) = [];
212        X_obj_BA(:,Outlier) = [];
213        x_calib(:,Outlier) = [];
214        [R T X_obj_BA X_im_BA dist1_BA dist2_BA]=SparseBAWraper(defaultPara, R, T, [f1(:,matches(1,:)); f2(:,matches(2,:))], X_obj_BA, ImgInfo, 1);
215        if all(isnan( dist1_BA)) || isempty(R) || any(isnan(R(:)))
216                disp('BA failed');
217            fail = 5;
218                return;
219        end
220end   
221if defaultPara.Flag.FlagDisp
222    figure;  plotmatches(I1,I2,f1, f2, matches, 'Stacking', 'v', 'Interactive', defaultPara.Flag.FlagDisp);
223end
224   
225% 6. find T up to scale
226
227% 7. Triangulation
228% modified the x_calib So that perfact triangulation but the image is distorted a little bit
229tempf1 = X_im_BA(1:2,:);
230tempf2 = X_im_BA(3:4,:);
231x_calib = [ inv(defaultPara.InrinsicK1)*[ tempf1; ones(1,length(tempf1))];...
232             inv(defaultPara.InrinsicK2)*[ tempf2; ones(1,length(tempf2))]];
233% ------------------
234[ lamda1 lamda2 Error] = triangulation( defaultPara, R, T, x_calib);
235
236% 8. modify ImgInfo.Model.Depth .... (not sure do it or not??????)
237[D1 IND1] = PorjPosi2Depth(size(I1), size(ImgInfo(1).Model.Depth.FitDepth), f1(:,matches(1,:)), ImgInfo(1).Model.Depth.FitDepth);
238[D2 IND2] = PorjPosi2Depth(size(I2), size(ImgInfo(2).Model.Depth.FitDepth), f2(:,matches(2,:)), ImgInfo(2).Model.Depth.FitDepth);
239Depth1ProjDepthRatio = sqrt(sum(x_calib(1:3,:).^2, 1));
240Depth2ProjDepthRatio = sqrt(sum(x_calib(4:6,:).^2, 1));
241DProj1 = D1./Depth1ProjDepthRatio;
242DProj2 = D2./Depth2ProjDepthRatio;
243[DepthScale1] = UniformDepthScale( defaultPara, DProj1, lamda1, ones(1,length(lamda1)));
244[DepthScale2] = UniformDepthScale( defaultPara, DProj2, lamda2, ones(1,length(lamda2)) );
245%if DepthScale1 > 20 | DepthScale1 <0.05 | DepthScale2 > 20 | DepthScale2 <0.05 %//Min used to use 10 and 0.2
246%   disp('Unrealistic in Rescaleing the depth, Check matchings');
247%   fail = -1;
248%end
249
250Pair.lamda = [lamda1; lamda2];
251Pair.DepthScale = [DepthScale1; DepthScale2];
252Pair.R = R;
253Pair.T = T;
254Pair.Xim = [f1(:,matches(1,:)); f2(:,matches(2,:))];
255
256% check is triangulation reasonable
257if defaultPara.Flag.FlagDisp
258figure(50); clf; title('Closest point Match Point'); hold on;
259ClosestMatchPosition2 = x_calib(4:6,:).*repmat( lamda2, 3,1);
260ClosestMatchPosition1 = R*(x_calib(1:3,:).*repmat( lamda1, 3,1)) + repmat(T, 1, length(lamda1));
261MonoStichPosition2 = x_calib(4:6,:).*repmat( DProj2.*DepthScale2, 3,1);
262MonoStichPosition1 = R*(x_calib(1:3,:).*repmat( DProj1.*DepthScale1, 3,1)) + repmat(T, 1, length(DProj1));
263% =====================
264[VDepth HDepth] = size(ImgInfo(2).Model.Depth.FitDepth);
265[VImg HImg] = size(I1);
266VIndexDepthRes = repmat((1:VDepth)', [1 HDepth]);
267HIndexDepthRes = repmat((1:HDepth), [VDepth 1]);
268VIndexImgRes = ( VIndexDepthRes -0.5)/VDepth*VImg;
269HIndexImgRes = ( HIndexDepthRes -0.5)/HDepth*HImg;
270ImgPositionPix = cat(3, HIndexImgRes, VIndexImgRes);
271All_x_calib = inv(defaultPara.InrinsicK1)*[ reshape( permute(ImgPositionPix, [ 3 1 2]), 2, []); ones(1, VDepth*HDepth)];%
272All_Ray = All_x_calib./repmat( sqrt(sum(All_x_calib.^2, 1)), 3, 1);
273All_Ray = repmat( All_Ray, 2, 1);
274% ====================
275ReScaledPosi2 = All_Ray(4:6,:).*repmat( ImgInfo(2).Model.Depth.FitDepth(:)'*DepthScale2, 3,1);
276ReScaledPosi1 = R*(All_Ray(1:3,:).*repmat( ImgInfo(1).Model.Depth.FitDepth(:)'*DepthScale1, 3,1)) + repmat(T, 1, length(All_Ray));
277ReScaledPosi2(:,IND2) = [];
278ReScaledPosi1(:,IND1) = [];
279scatter3(ReScaledPosi2(1,:)', ReScaledPosi2(3,:)', ReScaledPosi2(2,:)', 0.5*ones(1,size( ReScaledPosi2,2)));
280scatter3(ReScaledPosi1(1,:)', ReScaledPosi1(3,:)', ReScaledPosi1(2,:)', 1*ones(1,size( ReScaledPosi1,2)));
281scatter3(ClosestMatchPosition2(1,:)', ClosestMatchPosition2(3,:)', ClosestMatchPosition2(2,:)', 40, 'g');
282scatter3(ClosestMatchPosition1(1,:)', ClosestMatchPosition1(3,:)', ClosestMatchPosition1(2,:)', 40, 'b');
283line( [ ClosestMatchPosition2(1,:); ClosestMatchPosition1(1,:)], ...
284      [ ClosestMatchPosition2(3,:); ClosestMatchPosition1(3,:)], ...
285      [ ClosestMatchPosition2(2,:); ClosestMatchPosition1(2,:)]);
286% line( [ MonoStichPosition2(1,:); MonoStichPosition1(1,:)], ...
287%       [ MonoStichPosition2(3,:); MonoStichPosition1(3,:)], ...
288%       [ MonoStichPosition2(2,:); MonoStichPosition1(2,:)]);
289if ~isempty(ImgInfo(1).Model.Constrain.RayMatche)
290  ClosestMatchPosition1Hist = R*(ImgInfo(1).Model.Constrain.RayMatche'.*repmat(ImgInfo(1).Model.Constrain.Depth_modified , 3, 1)) + repmat(T, 1, length(ImgInfo(1).Model.Constrain.RayMatche));
291  scatter3(ClosestMatchPosition1Hist(1,:)', ClosestMatchPosition1Hist(3,:)', ClosestMatchPosition1Hist(2,:)', 40, 'y');
292end
293if ~isempty(ImgInfo(2).Model.Constrain.RayMatche)
294  ClosestMatchPosition2Hist = ImgInfo(2).Model.Constrain.RayMatche'.*repmat(ImgInfo(2).Model.Constrain.Depth_modified , 3, 1);
295  scatter3(ClosestMatchPosition2Hist(1,:)', ClosestMatchPosition2Hist(3,:)', ClosestMatchPosition2Hist(2,:)', 40, 'y');
296end
297
298figure(51); clf; title('Closest point Match Point'); hold on;
299RawReScaledPosi2 = All_Ray(4:6,:).*repmat( ImgInfo(2).Model.Depth.RawDepth(:)'*DepthScale2, 3,1);
300RawReScaledPosi1 = R*(All_Ray(1:3,:).*repmat( ImgInfo(1).Model.Depth.RawDepth(:)'*DepthScale1, 3,1)) + repmat(T, 1, length(All_Ray));
301RawReScaledPosi2(:,IND2) = [];
302RawReScaledPosi1(:,IND1) = [];
303scatter3(RawReScaledPosi2(1,:)', RawReScaledPosi2(3,:)', RawReScaledPosi2(2,:)', 1*ones(1,size( RawReScaledPosi2,2)));
304scatter3(RawReScaledPosi1(1,:)', RawReScaledPosi1(3,:)', RawReScaledPosi1(2,:)', 0.5*ones(1,size( RawReScaledPosi1,2)));
305scatter3(ClosestMatchPosition2(1,:)', ClosestMatchPosition2(3,:)', ClosestMatchPosition2(2,:)', 40, 'g');
306scatter3(ClosestMatchPosition2(1,:)', ClosestMatchPosition2(3,:)', ClosestMatchPosition2(2,:)', 40, 'b');
307line( [ ClosestMatchPosition2(1,:); ClosestMatchPosition1(1,:)], ...
308      [ ClosestMatchPosition2(3,:); ClosestMatchPosition1(3,:)], ...
309      [ ClosestMatchPosition2(2,:); ClosestMatchPosition1(2,:)]);
310line( [ MonoStichPosition2(1,:); MonoStichPosition1(1,:)], ...
311      [ MonoStichPosition2(3,:); MonoStichPosition1(3,:)], ...
312      [ MonoStichPosition2(2,:); MonoStichPosition1(2,:)]);
313end 
314return;
315
Note: See TracBrowser for help on using the repository browser.