我只想获得高质量的功能点

I want to get high quality feature points only

本文关键字:功能 高质量 只想      更新时间:2023-10-16

我目前正在使用 QT 创建器中的 OpenCV3.4.0、c++ 进行实时特征匹配。

我的代码匹配了通过网络摄像头获得的第一帧和从网络摄像头获得的当前帧输入之间的功能。

Mat frame1, frame2, img1, img2, img1_gray, img2_gray;
int n = 0;
VideoCapture cap1(0);
namedWindow("Video Capture1", WINDOW_NORMAL);
namedWindow("Reference img", WINDOW_NORMAL);
namedWindow("matches1", WINDOW_NORMAL);
moveWindow("Video Capture1",50, 0);
moveWindow("Reference img",50, 100);
moveWindow("matches1",100,100);

while((char)waitKey(1)!='q'){
//raw image saved in frame
cap1>>frame1;
n=n+1;
if (n ==1){
imwrite("frame1.jpg",  frame1);
cout<<"First frame saved as 'frame1'!!"<<endl;
}
if(frame1.empty())
break;

imshow("Video Capture1",frame1);
img1 = imread("frame1.jpg");
img2 = frame1;
cvtColor(img1, img1_gray, cv::COLOR_BGR2GRAY);
cvtColor(img2, img2_gray, cv::COLOR_BGR2GRAY);
imshow("Reference img",img1);
// detecting keypoints
int minHessian = 400;
Ptr<Feature2D> detector = xfeatures2d::SurfFeatureDetector::create();
vector<KeyPoint> keypoints1, keypoints2;
detector->detect(img1_gray,keypoints1);
detector->detect(img2_gray,keypoints2);
// computing descriptors
Ptr<DescriptorExtractor> extractor = xfeatures2d::SurfFeatureDetector::create();
Mat descriptors1, descriptors2;
extractor->compute(img1_gray,keypoints1,descriptors1);
extractor->compute(img2_gray,keypoints2,descriptors2);
// matching descriptors
BFMatcher matcher(NORM_L2);
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
// drawing the results
Mat img_matches;
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
imshow("matches1", img_matches);

但是代码返回的匹配点太多,以至于我无法区分哪个匹配哪个。

那么,有没有办法只获得高质量的匹配点呢?

如何像 MATLAB 一样在 QT 创建器中获取每个匹配点的像素坐标?

那么,有什么方法可以只获得高质量的匹配点吗?

我敢打赌有很多不同的方法。我正在使用例如对称性测试。因此,从 img2 到 img1 的匹配也必须存在从 img1 到 img2 的匹配。我正在使用改进特征点与OpenCV匹配的测试。那里显示了多个其他测试。

void symmetryTest(const std::vector<cv::DMatch> &matches1,const std::vector<cv::DMatch> &matches2,std::vector<cv::DMatch>& symMatches)
{
symMatches.clear();
for (vector<DMatch>::const_iterator matchIterator1= matches1.begin();matchIterator1!= matches1.end(); ++matchIterator1)
{
for (vector<DMatch>::const_iterator matchIterator2= matches2.begin();matchIterator2!= matches2.end();++matchIterator2)
{
if ((*matchIterator1).queryIdx ==(*matchIterator2).trainIdx &&(*matchIterator2).queryIdx ==(*matchIterator1).trainIdx)
{
symMatches.push_back(DMatch((*matchIterator1).queryIdx,(*matchIterator1).trainIdx,(*matchIterator1).distance));
break;
}
}
}
}

就像安德拉斯·科瓦奇在相关答案中所说的那样,您还可以使用 RANSAC 计算基本矩阵以使用cv::findFundamentalMat消除异常值。

如何像 MATLAB 一样在 QT 创建器中获取每个匹配点的像素坐标?

我希望我理解正确,您希望拥有匹配的同系物点的点坐标。我正在提取对称测试后点的坐标。 坐标位于关键点内。

for (size_t rows = 0; rows < sym_matches.size(); rows++) {
float x1 = keypoints_1[sym_matches[rows].queryIdx].pt.x;
float y1 = keypoints_1[sym_matches[rows].queryIdx].pt.y;        
float x2 = keypoints_2[sym_matches[rows].trainIdx].pt.x;
float y2 = keypoints_2[sym_matches[rows].trainIdx].pt.y;
// Push the coordinates in a vector e.g. std:vector<cv::Point2f>>
}

您可以对matcheskeypoints1keypoint2执行相同的操作。