gpt4 book ai didi

c++ - 只保留好关键点全景图像拼接opencv

转载 作者:行者123 更新时间:2023-12-02 10:15:49 30 4
gpt4 key购买 nike

我正在从事有关匹配连续图像以找到全景图像的项目。

我使用BFTatcher找到了带有SIFT的关键点以及两张图像之间的匹配项,但是在删除不良匹配项后,我无法保留相应的关键点,甚至无法使用cv::drawMatches显示匹配项,因为程序崩溃了。

该代码的初始部分如下所示,并且可以正常工作。

(“图像”是包含所有图像的 vector )

cv::Mat descriptors;
std::vector<cv::KeyPoint> keypoints;

std::vector<cv::Mat> descriptors_array;
std::vector<std::vector<cv::KeyPoint>> keypoints_array, reduced_keypoints_array;

cv::Ptr<cv::Feature2D> sift = cv::xfeatures2d::SIFT::create();
for(int i=0; i<N_images; i++){
sift->detectAndCompute(image.at(i), cv::Mat(), keypoints, descriptors);
keypoints_array.push_back(keypoints);
descriptors_array.push_back(descriptors);
}

std::vector<std::vector<cv::DMatch>> matches_array,
std::vector<cv::DMatch> matches, good_matches;
cv::Ptr<cv::BFMatcher> matcher = cv::BFMatcher::create(cv::NORM_L2, true);

for(int i=0; i<N_images-1; i++){
matcher->match(descriptors_array.at(i), descriptors_array.at(i+1), matches, cv::Mat());
for(int j=0; j<matches.size(); j++){
if (min_distance > matches.at(j).distance){
min_distance = matches.at(j).distance;
}
}
for( int k = 0; k <descriptors_array.at(i).rows; k++) {
if( matches[k].distance < 3*min_distance) {
good_matches.push_back(matches[k]);
}
}
matches_array.push_back(good_matches);
}

当我只想保留与matchs_array对应的良好关键点时,我在这段代码上遇到问题。
for(int i=0; i<keypoints_array.size()-1; i++){
reduced_keypoints_array.push_back(std::vector<cv::KeyPoint>());
for(int j=0; j<matches_array.at(i).size(); j++){
reduced_keypoints_array.at(i).push_back(cv::KeyPoint());

reduced_keypoints_array.at(i).at(j) = keypoints_array.at(i).at(matches_array.at(i).at(j).queryIdx);
}
}

在这里,我想显示匹配项,但由于我的匹配项超出了关键点,因此也崩溃了,因为我无法减少关键点的数量。
cv::Mat out;
for(int i=0; i<keypoints_array.size()-1; i++){
cv::drawMatches(image.at(i), keypoints_array.at(i), image.at(i+1), keypoints_array.at(i+1),matches_array.at(i), out2, cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector< char >(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

cv::imshow("matches", out);
cv::waitKey(0);
}

如何仅保留相应的关键点?或者只是在不删除关键点的情况下进行比赛?

最佳答案

我编辑了一些要在代码中标记的部分。我不建议您使用的数据结构,因为很难读取它们。当您有多个 vector vector 时,请考虑创建typedefsstructs。我使用了ORB,因为目前没有安装SIFT。这是三个图像的示例:

int main(int argc, char** argv)
{
// Reading my images and insert them into a vector
std::vector<cv::Mat> image;
cv::Mat img1 = cv::imread("1.png", cv::IMREAD_GRAYSCALE);
cv::Mat img2 = cv::imread("2.png", cv::IMREAD_GRAYSCALE);
cv::Mat img3 = cv::imread("3.png", cv::IMREAD_GRAYSCALE);

image.push_back(img1);
image.push_back(img2);
image.push_back(img3);

int N_images = (int)image.size();

cv::Mat descriptors;
std::vector<cv::KeyPoint> keypoints;

std::vector<cv::Mat> descriptors_array;
std::vector<std::vector<cv::KeyPoint>> keypoints_array, reduced_keypoints_array;

// Here I used ORB
cv::Ptr<cv::ORB> orb = cv::ORB::create();
for (int i = 0; i < N_images; i++) {
orb->detectAndCompute(image.at(i), cv::Mat(), keypoints, descriptors);
keypoints_array.push_back(keypoints);
descriptors_array.push_back(descriptors);
}

std::vector<std::vector<cv::DMatch>> matches_array;
std::vector<cv::DMatch> matches, good_matches;
cv::Ptr<cv::BFMatcher> matcher = cv::BFMatcher::create(cv::NORM_L2, true);

// I created a vector of pairs of keypoints to push them into an array similar to the good matches
std::vector<std::pair<cv::KeyPoint, cv::KeyPoint>> good_keypoint_pairs_array;
std::vector<std::vector<std::pair<cv::KeyPoint, cv::KeyPoint>>> keypoint_pairs_array;

float min_distance = 1000;

for (int i = 0; i < N_images-1 ; i++) {
matcher->match(descriptors_array[i], descriptors_array.at(i + 1), matches, cv::Mat());
// I left that part out since I got always a number of 0 matches, no matter which min_distance I used
/*for (int j = 0; j < matches.size(); j++) {
if (min_distance > matches.at(j).distance) {
min_distance = matches.at(j).distance;
}
}*/
for (int k = 0; k < descriptors_array.at(i).rows; k++) {
if (matches[k].distance < 3 * min_distance) {
good_keypoint_pairs_array.push_back(std::make_pair(keypoints_array.at(i).at(k), keypoints_array.at(i + 1).at(k)));
good_matches.push_back(matches[k]);
}
}
keypoint_pairs_array.push_back(good_keypoint_pairs_array);
matches_array.push_back(good_matches);
}

cv::Mat out;

// I create my keypoint vectors to use them for the cv::drawMatches function
std::vector<cv::KeyPoint> kp_1, kp_2;
for (int i = 0; i < keypoint_pairs_array.size(); ++i) {
for (int j = 0; j < keypoint_pairs_array[i].size(); ++j) {
kp_1.push_back(keypoint_pairs_array[i][j].first);
kp_2.push_back(keypoint_pairs_array[i][j].second);

}
cv::drawMatches(image.at(i), kp_1, image.at(i + 1), kp_2, matches_array.at(i), out, cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector< char >(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

cv::imshow("matches", out);
cv::waitKey(0);
kp_1.clear();
kp_2.clear();
}


}

I am having problem with this code, when i want to just keep the good keypoints, which corresponds to the matches_array.



正如您已经提到的, std::vector<cv::DMatch>的大小始终与 std::vector<cv::KeyPoint>的大小相似非常重要,因此必须将关键点保存在使用匹配数的同一循环中,如图所示。

关于c++ - 只保留好关键点全景图像拼接opencv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61993198/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com