Invalid indexing operation- drawing epipolar lines

19 views (last 30 days)
Hello
I am creating Stereo images processing project modeled on Matlab's examples. A copy pasted code from one of them not works well.
I1 = rgb2gray(imread('viprectification_deskLeft.png'));
I2 = rgb2gray(imread('viprectification_deskRight.png'));
points1 = detectHarrisFeatures(I1);
points2 = detectHarrisFeatures(I2);
[features1, valid_points1] = extractFeatures(I1, points1);
[features2, valid_points2] = extractFeatures(I2, points2);
indexPairs = matchFeatures(features1, features2);
matchedPoints1 = valid_points1(indexPairs(:, 1),:);
matchedPoints2 = valid_points2(indexPairs(:, 2),:);
figure; showMatchedFeatures(I1, I2, matchedPoints1, matchedPoints2);
load stereoPointPairs
[fLMedS, inliers] = estimateFundamentalMatrix(matchedPoints1,matchedPoints2,'NumTrials',4000);
figure;
subplot(121); imshow(I1);
title('Inliers and Epipolar Lines in First Image'); hold on;
plot(matchedPoints1(inliers,1), matchedPoints1(inliers,2), 'go');
An error:
Error using epilineTest (line 23) Invalid indexing operation.
Best regards
EDIT:// I deleted if/end, this was unnecessary
  4 Comments
Geoff Hayes
Geoff Hayes on 7 Jun 2014
If it is the last line, plot(matchedPoints1(inliers,1), matchedPoints1(inliers,2), 'go');, put a breakpoint here and re-run the function. When the code pauses at this line, run the following commands in the Command Window
>> size(matchedPoints1)
>> size(matchedPoints2)
>> size(inliers)
>> size(matchedPoints1(inliers,1))
>> size(matchedPoints1(inliers,2))
What are the results returned for each of the above commands? Unfortunately, I can't run your code since I don't have the Computer Vision System Toolbox..
Jan
Jan on 7 Jun 2014
Edited: Jan on 7 Jun 2014
Result:
K>> size(matchedPoints1)
ans =
89 1
K>> size(matchedPoints2)
ans =
89 1
K>> size(inliers)
ans =
89 1
K>> size(matchedPoints1(inliers,1))
Invalid indexing operation.
K>> size(matchedPoints1(inliers,2))
Index exceeds matrix dimensions.

Sign in to comment.

Accepted Answer

Jan
Jan on 9 Jun 2014
IT WORKS! So a conversion to arrays of double is done. Thank you for help! My full-working code:
I1 = rgb2gray(imread('viprectification_deskLeft.png'));
I2 = rgb2gray(imread('viprectification_deskRight.png'));
points1 = detectHarrisFeatures(I1);
points2 = detectHarrisFeatures(I2);
[features1, valid_points1] = extractFeatures(I1, points1);
[features2, valid_points2] = extractFeatures(I2, points2);
%Use the sum of absolute differences (SAD) metric to determine indices of matching features.
indexPairs = matchFeatures(features1, features2);
%Retrieve locations of matched points for each image
matched_points1 = valid_points1(indexPairs(:, 1), :);
matched_points2 = valid_points2(indexPairs(:, 2), :);
[fLMedS, inliers] = estimateFundamentalMatrix(matched_points1, matched_points2, 'NumTrials', 4000);
%%%%conversion of matched_points1 to matrix
sS = 13;
xm1 = matched_points1.selectStrongest(sS);
m1 = zeros(sS,2,'double');
newInliners = logical(sS);
wielCP = size(matched_points1);
wielCP = wielCP(1,1);
for y = 1:sS
am1 = xm1(y);
m1(y,1) = am1.Location(1,1);
m1(y,2) = am1.Location(1,2);
for z = 1 : wielCP
b = matched_points1(z);
temp_a1 = am1.Location(1,1);
temp_a2 = am1.Location(1,2);
temp_b1 = b.Location(1,1);
temp_b2 = b.Location(1,2);
if temp_a1 == temp_b1 && temp_a2 == temp_b2
newInliners(y) = inliers(z);
end
end
end
newInliners = newInliners';
%%%%conversion of matched_points2 to matrix
xm2 = matched_points2.selectStrongest(sS);
m2 = zeros(sS,2,'double');
for y = 1:sS
am2 = xm2(y);
m2(y,1) = am2.Location(1,1);
m2(y,2) = am2.Location(1,2);
end
%%%%%%%%
figure;
subplot(121); imshow(I1);
title('Inliers and Epipolar Lines in First Image'); hold on;
plot(m1(newInliners,1), m1(newInliners,2), 'go')
% Compute the epipolar lines in the first image.
epiLines = epipolarLine(fLMedS', m2(newInliners, :));
% Compute the intersection points of the lines and the image border.
pts = lineToBorderPoints(epiLines, size(I1));
% Show the epipolar lines in the first image
line(pts(:, [1,3])', pts(:, [2,4])');
% Show the inliers in the second image.
subplot(122); imshow(I2); title('Inliers and Epipole Lines in Second Image'); hold on;
plot(m2(newInliners,1), m2(newInliners,2), 'ro')
% Compute and show the epipolar lines in the second image.
epiLines = epipolarLine(fLMedS, m1(newInliners, :));
pts = lineToBorderPoints(epiLines, size(I2));
line(pts(:, [1,3])', pts(:, [2,4])');
truesize;

More Answers (3)

Geoff Hayes
Geoff Hayes on 7 Jun 2014
The second error is obvious: the matchedPoints1 matrix is only 89x1 but the matchedPoints1(inliers,2) is trying to access the second column which doesn't exist. Hence the Index exceeds matrix dimensions. Strange since the extractFeatures function sates that it does return an mx2 matrix (valid_points1/2) and you are getting an mx1 (after the extraction from valid_points into matchedPoints).
Looking at http://www.mathworks.com/help/vision/ref/extractfeatures.html, the second return value, valid_points from extractFeatures, is not necessarily an mx2 matrix of coordinates but will/should match the input data type. In your case, that is cornerPoints (I think?) based on the return value of the * detectHarrisFeatures* function (see http://www.mathworks.com/help/vision/ref/detectharrisfeatures.html ). So I suspect that your valid_points1/2 and so matchedPoints1/2 are cornerPoints objects. To verify this, re-run the code with the breakpoint and when the code pauses, in the command window type
>> class(matchedPoints1)
>> class(valid_points1)
>> class(matchedPoints2)
>> class(valid_points2)
If that is the case, then even though the size of this object is 89x1, it may only be a single object with 89 points so you cannot treat it like an array (see http://www.mathworks.com/help/vision/ref/cornerpoints-class.html). This class does provide its own plotting method so that may be of some use i.e. plot(matchedPoints1).
  1 Comment
Jan
Jan on 7 Jun 2014
Thank you for answer! I will consider that. Results soon.
Result of
>> class(matchedPoints1)
>> class(valid_points1)
>> class(matchedPoints2)
>> class(valid_points2)
is always:
ans =
cornerPoints

Sign in to comment.


Jan
Jan on 8 Jun 2014
Edited: Jan on 8 Jun 2014
Ok i got it. So matlab examples include errors(!). There isn't possibile to execute
plot(matchedPoints1(inliers,1), matchedPoints1(inliers,2), 'go');
beacuse matchedPoints1/2 use cornerPoints class and they has one column. So why this unworking examples are in documentation? I believe that will be fixed. Maybe conversion of cornerPoints objects to matrices is possible. So the line responsible for plotting points looks like:
plot(matchedPoints1.selectStrongest(13));
or
matchedPoints1.plot;
Next thing is another example which draws epipolar lines, but second input variable is again cornerPoint object.
% Compute the epipolar lines in the first image.
epiLines = epipolarLine(fLMedS', matchedPoints2(inliers, :));
% Compute the intersection points of the lines and the image border.
pts = lineToBorderPoints(epiLines, size(I1));
% Show the epipolar lines in the first image
line(pts(:, [1,3])', pts(:, [2,4])');
Error:
Error using epipolarLine Expected Pts to be one of these types:
single, double, int8, int16, int32, int64, uint8, uint16, uint32, uint64
Instead its type was cornerPoints.
As we can see, I can't use matchedPoints2, beacuse it is cornerPionts object. So there is another mistake in Matlab's documentation (I think). Is it possibile to plot epipolar lines with i.e. converted to matrix matchedPoints2? Any ideas?
  4 Comments
Geoff Hayes
Geoff Hayes on 9 Jun 2014
I think that the problem may be that you are trying to merge the two examples. The first was looks fine - it doesn't try to use the plot function against the matchedPoints1/2 sets of data (cornerPoints) that are computed using the detectHarrisFeatures function. The "mistake" with the other is that it doesn't discuss how it generates the matchedPoints1/2 sets of data. But seeing how the example later uses them to plot data, then we have to assume that they have been pre-calculated using some algorithm that returns mx2 arrays of coordinates.
Jan
Jan on 9 Jun 2014
You have right, propably merging of two examples is reason. So is it possible to convert matchedPoints1/2 to array or vector? Please, look at my new post.

Sign in to comment.


Jan
Jan on 9 Jun 2014
I got something new! This not working:
load stereoPointPairs
[fLMedS, inliers] = estimateFundamentalMatrix(matchedPoints1, matchedPoints2, 'NumTrials', 4000);
I1 = imread('viprectification_deskLeft.png');
figure;
subplot(121); imshow(I1);
title('Title'); hold on;
plot(matchedPoints1(inliers,1), matchedPoints1(inliers,2), 'go')
This works:
load stereoPointPairs
[fLMedS, inliers] = estimateFundamentalMatrix(matchedPoints1, matchedPoints2, 'NumTrials', 4000);
I1 = imread('viprectification_deskLeft.png');
figure;
subplot(121); imshow(I1);
title('Title'); hold on;
plot(matched_points1(knownInliers,1), matched_points1(knownInliers,2), 'go')
I saw those variables (matrices) in workspace, I replace them and example code works fine. This variables (I mean matched_points1/2 and knowInliers ) are loaded by
load stereoPointPairs
Now I want to renew my question: Is possible to conver SURFPoints ' or cornerPoints ' objects to double arrays? And how can I get knownInliers ?
  1 Comment
Geoff Hayes
Geoff Hayes on 9 Jun 2014
Take a look at the documentation for cornerPoints http://www.mathworks.com/help/vision/ref/cornerpoints-class.html. If matchedPoints1 is a cornerPoints object, then matchedPoints1.Location may return something that will give you an idea of the [x y] coordinates.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!