-
Notifications
You must be signed in to change notification settings - Fork 0
/
reducePointObs.m
193 lines (159 loc) · 7.68 KB
/
reducePointObs.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
function I = reducePointObs(Images, points)
% for each image observation, add an observation to the point. If that
% number is less than two, eliminate both that point from the list of
% points, and from the image observations (if it exists)
I = Images;
c = I(1).camera.principleDistance;
for i = 1:length(points)
% save the current points' ID for quicker access later on
currentPointID = points(i).pointName;
if points(i).numObs < 2
currentPointID = points(i).pointName;
for ii = 1:length(I)
for j = 1:length(I(ii).imageData)
if strcmp(currentPointID, I(ii).imageData(j).point.pointName)
I(ii).imageData(j) = [];
break;
end
end
end
% For each element in the poinst array, check if it has more than two
% observations. If it does, procede.
elseif points(i).numObs >= 2
% Pre-allocate memory for the cost and indexes of the image pairs
listOfImagePairs = zeros(round((points(i).numObs * (points(i).numObs-1))/2),3);
% Since the index of the next point can be hard to predict, save
% the index here and increment it later, once the next image pair
% has been assigned.
nextIndex = 1;
% For each image ID in the list of image IDs, except for the last
% one, for the current element in the points array:
for j = 1:size(points(i).imgNames,1)-1
% Check to find the index of the image which has the ID that
% matches the the current imageID in the current point' list of
% image IDs
flag = 0;
for n = 1:length(I)
if strcmp(I(n).ImageID, points(i).imgNames(j,:))
imgIdx1 = n;
flag = 1;
break;
end
end
% Throw a warning if that image was not found
if flag == 0
warning(['No element in points(',num2str(i),').imgNames'...
,' matches I.ImageID,first set']);
end
% Starting at the element after, find the index of the second
% image ID
for k = j+1:size(points(i).imgNames,1)
% Find the indexs of the second image of the listed image
% pair
flag = 0;
for m = 1:length(I)
if strcmp(I(m).ImageID, points(i).imgNames(k,:))
imgIdx2 = m;
flag = 1;
break;
end
end
% again, throw a warning if it is not found
if flag == 0
warning(['No element in points(',num2str(i),').imgNames'...
,' matches I.ImageID, second set']);
end
% Once both images have been identified, begin calculating
% the cost of this configuration.
% calulate the angle between the image point observation
% and the principle point. Ideally, it is close to zero, so
% the cost associated with larger angles here corresponds
% to the sin of the angle
alpha = 2;
for x = 1:length(I(imgIdx1).imageData)
if strcmp(I(imgIdx1).imageData(x).point.pointName, currentPointID)
alpha = acos( norm(I(imgIdx1).imageData(x).coords) / c );
break;
end
end
% display a warning if the point was not found in the image
% list of points
if alpha == 2
warning([currentPointID,' not found in the list of point in Image ',imgIdx1]);
end
% same as before, using the second image
beta = 2;
for x = 1:length(I(imgIdx2).imageData)
if strcmp(I(imgIdx2).imageData(x).point.pointName, currentPointID)
beta = acos( norm(I(imgIdx2).imageData(x).coords) / c );
break;
end
end
if beta == 2
warning([currentPointID,' not found in the list of point in Image ',imgIdx2]);
end
% The final cost value corresponds to the cosine of the
% angle of intesection of the two image centers and the
% object point in question(i.e. the closer to 90 the
% better). Since the dot product of the two vectors already
% corresponds to the cosine of that angle, it is not
% necessary to calculate the angle.
vec1 = I(imgIdx1).location - points(i).xyz;
vec1 = vec1/norm(vec1);
vec2 = I(imgIdx2).location - points(i).xyz;
vec2 = vec2/norm(vec2);
imgSeparation = I(imgIdx2).location - I(imgIdx1).location;
a_1 = imgSeparation * dot((points(i).xyz - I(imgIdx1).location ),(imgSeparation));
b_1 = (points(i).xyz - I(imgIdx1).location) - a_1;
c_1 = imgSeparation - a_1;
alpha = atan2(norm(a_1),norm(b_1));
beta = atan2(norm(c_1),norm(b_1));
cost = dot(vec1,vec2)^2 + sin(alpha-beta)^2;
% cost = dot(vec1,vec2);
% save the cost
listOfImagePairs(nextIndex,:) = [ cost, imgIdx1, imgIdx2];
nextIndex = nextIndex + 1;
end
end
for j = 1:size(listOfImagePairs,1)
if listOfImagePairs(j,:) == [0,0,0];
listOfImagePairs(j,:) = [4,-1,-1];
end
end
sortedImagePairs = sortrows(listOfImagePairs);
indexesToPreserve = sort(sortedImagePairs(1,2:3));
for z = 1:length(I)
if z ~= indexesToPreserve(1) && z ~= indexesToPreserve(2)
correctIndex = -1;
for f = 1:length(I(z).imageData)
if strcmp(I(z).imageData(f).point.pointName, currentPointID)
correctIndex = f;
break;
end
end
if correctIndex > 0
I(z).imageData(correctIndex) = [];
else
% If we get to this point, it means that this image
% hasn't taken an image of this point. To verify, we
% can compare the ID of the current image to the list
% of image IDs for this point. We only need to worry if
% there is a match.
flag = 1;
for k = 1:size(points(i).imgNames,1)
if strcmp(I(z).ImageID, points(i).imgNames(k,:))
flag = 0;
break;
end
end
if flag == 0
error(001,'Mis-match between ImageID list of point observations')
end
end
end
end
points(i).imgNames = [I(indexesToPreserve(1)).ImageID;...
I(indexesToPreserve(2)).ImageID;];
points(i).numObs = size(points(i).imgNames,1);
end
end