Reputation: 489
Suppose I found keypoints and their descriptors in 2 images.
def create_SIFT_points(filename):
img = cv.imread(filename)
sift = cv.xfeatures2d.SIFT_create()
return sift.detectAndCompute(img,None)
img1_file = 'image_1.png'
img2_file = 'image_2.png'
kp1, des1 = create_SIFT_points(img1_file)
kp2, des2 = create_SIFT_points(img2_file)
And suppose that I used a custom algorithm to found the matches. Then I want to see these matches on kp1 and kp2 visually. For example, if I matched the 7th keypoint on kp1 and 3th keypoint on kp2 I want to see it in a picture. NOTE THAT I am using my own algorithm to find these and holding them in a list.
How can I achieve this? in the documentation there is a drawMatches() method. https://docs.opencv.org/3.4/d4/d5d/group__features2d__draw.html
But how to fill this?
const std::vector< DMatch > & matches1to2,
https://docs.opencv.org/3.4/d4/de0/classcv_1_1DMatch.html
How can I fill this attributes?
float distance
int imgIdx
int queryIdx
int trainIdx
Upvotes: 1
Views: 695
Reputation: 941
I already did this in C++ but it is easily transferable to Python.
I am using files (matches.txt) which hold the feature point coordinates (x1, y1, x2, y2) such as trainIdx and queryIdx are similar:
x1 y1 x2 y2 (row 1 - trainIdx 0, queryIdx 0)
x1 y1 x2 y2 (row 2 - trainIdx 1, queryIdx 1)
...
In your example you would have to assing the correct trainIdx
and queryIdx
to the std::vector<cv::DMatch>
.
Then I read the file and the images and fill the overloaded std::vector<cv::DMatch>
with queryIdx
, trainIdx
and distance
(which is irrelevant for drawing, so I set it to 1).
Here is the relevant piece of code in C++:
// Read images
cv::Mat img_1 = cv::imread(name_img1);
cv::Mat img_2 = cv::imread(name_img2);
// Create match_file and output_file
std::vector<cv::DMatch> matches_12;
cv::Mat output_image;
// Read keypoints
std::vector<cv::KeyPoint> kp1, kp2;
int counter = 0;
// Read matches file
std::ifstream matches_files;
matches_files.open("matches.txt")
std::string line_of_matches;
while (std::getline(matches_files, line_of_matches))
{
std::istringstream iss_matches(line_of_matches);
float x1, y1, x2, y2;
if (!(iss_matches >> x1 >> y1 >> x2 >> y2)) {break; }
// Store keypoints in appropriate format
kp1.push_back(cv::KeyPoint(cv::Point2f(x1, y1), 1));
kp2.push_back(cv::KeyPoint(cv::Point2f(x2, y2), 1));
// Store matches in appropriate format
matches_12.push_back(cv::DMatch(counter, counter, 1));
counter++;
}
// Draw matches and save the file
cv::drawMatches(img_1, kp1, img_2, kp2, matches_12, output_image, cv::Scalar::all(-1),
cv::Scalar::all(-1));
cv::imwrite("My_own_matching_method.bmp", output_image);
Upvotes: 1