#include <vector>
#include <iostream>
int main(
int args,
char** argv) {
std::string img_name1, img_name2;
if (args < 3) {
"Path to two images \nFor example: "
"./epipolar_lines img1.jpg img2.jpg");
} else {
img_name1 = argv[1];
img_name2 = argv[2];
}
Mat image1 = imread(img_name1);
Mat image2 = imread(img_name2);
Mat descriptors1, descriptors2;
std::vector<KeyPoint> keypoints1, keypoints2;
detector->detect(image1, keypoints1);
detector->detect(image2, keypoints2);
detector->compute(image1, keypoints1, descriptors1);
detector->compute(image2, keypoints2, descriptors2);
FlannBasedMatcher matcher(makePtr<flann::KDTreeIndexParams>(5), makePtr<flann::SearchParams>(32));
std::vector<std::vector<DMatch>> matches_vector;
matcher.
knnMatch(descriptors1, descriptors2, matches_vector, 2);
std::vector<Point2d> pts1, pts2;
pts1.reserve(matches_vector.size()); pts2.reserve(matches_vector.size());
for (const auto &m : matches_vector) {
if (m[0].distance / m[1].distance < 0.75) {
pts1.emplace_back(keypoints1[m[0].queryIdx].pt);
pts2.emplace_back(keypoints2[m[0].trainIdx].pt);
}
}
std::cout << "Number of points " << pts1.size() << '\n';
const auto begin_time = std::chrono::steady_clock::now();
const Mat F = findFundamentalMat(pts1, pts2, RANSAC, 1., 0.99, 2000, inliers);
std::cout << "RANSAC fundamental matrix time " << static_cast<int>(std::chrono::duration_cast<std::chrono::microseconds>
(std::chrono::steady_clock::now() - begin_time).count()) << "\n";
Mat points1 =
Mat((
int)pts1.size(), 2,
CV_64F, pts1.data());
Mat points2 =
Mat((
int)pts2.size(), 2,
CV_64F, pts2.data());
vconcat(points1.t(), Mat::ones(1, points1.rows, points1.type()), points1);
vconcat(points2.
t(), Mat::ones(1, points2.
rows, points2.
type()), points2);
const int circle_sz = 3, line_sz = 1, max_lines = 300;
std::vector<int> pts_shuffle (points1.cols);
for (int i = 0; i < points1.cols; i++)
pts_shuffle[i] = i;
randShuffle(pts_shuffle);
int plot_lines = 0, num_inliers = 0;
double mean_err = 0;
for (int pt : pts_shuffle) {
const Mat l2 = F * points1.
col(pt);
const Mat l1 = F.
t() * points2.
col(pt);
double a1 = l1.
at<
double>(0), b1 = l1.
at<
double>(1), c1 = l1.
at<
double>(2);
double a2 = l2.
at<
double>(0), b2 = l2.
at<
double>(1), c2 = l2.
at<
double>(2);
const double mag1 = sqrt(a1*a1 + b1*b1), mag2 = (a2*a2 + b2*b2);
a1 /= mag1; b1 /= mag1; c1 /= mag1; a2 /= mag2; b2 /= mag2; c2 /= mag2;
if (plot_lines++ < max_lines) {
}
circle (image1, pts1[pt], circle_sz, col, -1);
circle (image2, pts2[pt], circle_sz, col, -1);
mean_err += (fabs(points1.col(pt).dot(l2)) / mag2 + fabs(points2.
col(pt).
dot(l1) / mag1)) / 2;
num_inliers++;
}
}
std::cout << "Mean distance from tentative inliers to epipolar lines " << mean_err/num_inliers
<< " number of inliers " << num_inliers << "\n";
hconcat(image1, image2, image1);
const int new_img_size = 1200 * 800;
resize(image1, image1,
Size((
int) sqrt ((
double) image1.
cols * new_img_size / image1.
rows),
(
int)sqrt ((
double) image1.
rows * new_img_size / image1.
cols)));
imshow("epipolar lines, image 1, 2", image1);
imwrite("epipolar_lines.png", image1);
waitKey(0);
}
void knnMatch(InputArray queryDescriptors, InputArray trainDescriptors, std::vector< std::vector< DMatch > > &matches, int k, InputArray mask=noArray(), bool compactResult=false) const
Finds the k best matches for each descriptor from a query set.
Flann-based descriptor matcher.
Definition features.hpp:1042
n-dimensional dense array class
Definition mat.hpp:951
double dot(InputArray m) const
Computes a dot-product of two vectors.
Mat col(int x) const
Creates a matrix header for the specified matrix column.
_Tp & at(int i0=0)
Returns a reference to the specified array element.
int cols
Definition mat.hpp:2425
MatExpr t() const
Transposes a matrix.
int rows
the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
Definition mat.hpp:2425
int type() const
Returns the type of a matrix element.
Random Number Generator.
Definition core.hpp:2805
int uniform(int a, int b)
returns uniformly distributed integer random number from [a,b) range
Template class for specifying the size of an image or rectangle.
Definition types.hpp:338
std::shared_ptr< _Tp > Ptr
Definition cvstd_wrapper.hpp:23
#define CV_64F
Definition interface.h:82
unsigned char uchar
Definition interface.h:51
#define CV_Error(code, msg)
Call the error handler.
Definition exception.hpp:174
int main(int argc, char *argv[])
Definition highgui_qt.cpp:3