OpenCV Q&A Forum - RSS feedhttp://answers.opencv.org/questions/OpenCV answersenCopyright <a href="http://www.opencv.org">OpenCV foundation</a>, 2012-2018.Mon, 26 Nov 2018 11:04:12 -0600Wrong rank in Fundamental Matrixhttp://answers.opencv.org/question/204100/wrong-rank-in-fundamental-matrix/Hi guys,
I'm using the OpenCV for Python3 and, based on the Mastering OpenCV Book, try to compute the epipoles from many images (Structure from Motion algorithm).
In many books, they say which Fundamental Matrix has rank 2. But, the OpenCV function returns a rank 3 matrix.
How can I make this right?
orb = cv2.ORB_create()
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)
# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)
# Match descriptors.
matches = bf.match(des1,des2)
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
pts1 = []
pts2 = []
for m in matches:
pts2.append(kp2[m.trainIdx].pt)
pts1.append(kp1[m.queryIdx].pt)
F, mask = cv2.findFundamentalMat(pts1, pt2,cv2.FM_RANSAC)
pts1 = match['leftPts'][mask.ravel()==1]
pts2 = match['rightPts'][mask.ravel()==1]
# F is the Fundamental Matrix
From that code, the output are like
Processing image 0 and image 1
rank of F: 3
Processing image 0 and image 2
rank of F: 3
Processing image 0 and image 3
rank of F: 3
Processing image 0 and image 4
rank of F: 2
[...]
Someone could help me? Someone have any functional code for SfM using OpenCV?
Thanks in advance.
Lucas Amparo BarbosaMon, 26 Nov 2018 11:04:12 -0600http://answers.opencv.org/question/204100/Why findFundamentalMat gives different results for same but different orientation of points?http://answers.opencv.org/question/113067/why-findfundamentalmat-gives-different-results-for-same-but-different-orientation-of-points/Sorry if the title is kind of weird. It is quite hard to express the question of my problem.
So, I am in the middle of a 3D reconstruction project. The pipeline is more or less the same with the standard pipeline where
1. Undistort image
2. Detect points with keypoint detector
3. Track the points across frames (optical flow)
4. Calculate the fundamental matrix
and so on. The only different part is at step 2 where I use a Line Segment Detector and track it across frames.
So, if I am using a keypoint detector, giving two frame of images, I will get two set of keypoints (each set corresponds to each frame). But as for my situation, I have four set of keypoints (each two set correspond to each frame since a line has a start point and an end point).
In order to calculate the Fundamental matrix, I need to concatenate the two sets of point of each frame.
One way is by just vertically concatenate it: `np.vstack([start_point, end_point])`.
The other way is by :`np.hstack([start_point, end_point]).reshape(-1, 2)`. Means, it is concatenated 'alternately', i.e.
[[start_point[0],
end_point[0],
start_point[1],
end_point[1],
...]]
Both will end up with a same shape. But fair enough, they produce a quite different results. From my observation, the `vstack` produced a more '3D-like' result while the `hstack` produced a more 'planar-like' result for the reconstruction.
The question is why is this? And which one supposed to be better?
Below is sample code to give a view of this question:
import numpy as np
import cv2
np.random.seed(0)
def prepare_points(pts_frame1, pts_frame2):
# Prepare the four sets of points
(p1_f1, p2_f1) = pts_frame1
(p1_f2, p2_f2) = pts_frame2
v_stacked_f1f2 = (np.vstack([p1_f1, p2_f1]), np.vstack([p1_f2, p2_f2]))
h_stacked_f1f2 = (np.hstack([p1_f1, p2_f1]).reshape(-1, 2),
np.hstack([p1_f2, p2_f2]).reshape(-1, 2))
return (v_stacked_f1f2, h_stacked_f1f2)
pts_frame1 = np.random.random_sample((60, 2)).astype("float32")
pts_frame2 = np.random.random_sample((60, 2)).astype("float32")
# Emulate the two sets of points for each frame where
# the first set is the start point, while
# the second set is the end point of a line
pts_frame1 = (pts_frame1[::2], pts_frame1[1::2])
pts_frame2 = (pts_frame2[::2], pts_frame2[1::2])
(v_stacked_f1f2, h_stacked_f1f2) = prepare_points(pts_frame1, pts_frame2)
F_vstacked = cv2.findFundamentalMat(v_stacked_f1f2[0], v_stacked_f1f2[1],
cv2.FM_RANSAC, 3, 0.99)[0]
F_hstacked = cv2.findFundamentalMat(h_stacked_f1f2[0], h_stacked_f1f2[1],
cv2.FM_RANSAC, 3, 0.99)[0]
print("F_vstacked:\n", F_vstacked, "\n")
print("F_hstacked:\n", F_hstacked, "\n")
# The output:
# F_vstacked:
# [[ 3.31788127 -2.24336615 -0.77866782]
# [ 0.83418839 -1.4066019 -0.92088302]
# [-2.75413748 2.27311637 1. ]]
# F_hstacked:
# [[ 7.70558741 25.29966782 -16.20835082]
# [-12.95357284 -0.54474384 14.95490469]
# [ 1.79050172 -10.40077071 1. ]]
HilmanMon, 14 Nov 2016 22:59:48 -0600http://answers.opencv.org/question/113067/Pose estimation produces wrong translation vectorhttp://answers.opencv.org/question/18565/pose-estimation-produces-wrong-translation-vector/Hi,<br>
I'm trying to extract camera poses from a set of two images using features I extracted with BRISK. The feature points match quite brilliantly when I display them and the rotation matrix I get seems to be reasonable. The translation vector, however, is not.
I'm using the simple method of computing the fundamental matrix, essential matrix computing the SVD as presented in e.g. H&Z:
Mat fundamental_matrix =
findFundamentalMat(poi1, poi2, FM_RANSAC, deviation, 0.9, mask);
Mat essentialMatrix = calibrationMatrix.t() * fundamental_matrix * calibrationMatrix;
SVD decomp (essentialMatrix, SVD::FULL_UV);
Mat W = Mat::zeros(3, 3, CV_64F);
W.at<double>(0,1) = -1;
W.at<double>(1,0) = 1;
W.at<double>(2,2) = 1;
Mat R1= decomp.u * W * decomp.vt;
Mat R2= decomp.u * W.t() * decomp.vt;
if(determinant(R1) < 0)
R1 = -1 * R1;
if(determinant(R2) < 0)
R2 = -1 * R2;
Mat trans = decomp.u.col(2);
However, the resulting translation vector is horrible, especially the z coordinate: Usually it is near (0,0,1) regardless of the camera movement I performed while recording these images. Sometimes it seems that the first two coordinates might be kind of right, but they're far to small in comparison to the z coordinate (e.g. I moved the camera mainly in +x and the resulting vector is something like (0.2, 0, 0.98).
Any help would be appreciated.FiredragonwebSat, 10 Aug 2013 08:37:43 -0500http://answers.opencv.org/question/18565/How to use GenericDescriptorMatcher?http://answers.opencv.org/question/11610/how-to-use-genericdescriptormatcher/Hi
I'm trying to use the Common Interfaces of Generic Descriptor Matchers but I have not discovered how to start yet. My problem is the following: I have two images with their respective keypoints sets, also I know before hand the Fundamental matrix that relates them, I want to match the keypoints using the epipolar constrain (p1'\*Fundamental\*p2 = 0), in other words, generate a vector< DMatch > that relates the points that satisfy the epipolar constrain. At this point I would like to use the interfaces that OpenCV provides in order to have my code as generic as possible. However there are not examples of how to use these tools. Can someone point me to the right direction? or maybe I don't need these interfaces?
Thanks in advance.
PD Sorry for my bad english.RaulPLSun, 14 Apr 2013 20:53:49 -0500http://answers.opencv.org/question/11610/