C++ 使用BruteForceMatcher或FlannBasedMatcher的KnnMatch进行的人脸/图像匹配不正确
Iam试图使用ORB检测器/描述符和Flann或暴力匹配器在较大的目标图像(allimg.jpg-包含3个面)中识别源图像(c1.jpg-面)。c1.jpg是从allimg.jpg中裁剪/复制而成的。 ORB检测器/描述符按预期工作,正确返回检测器/描述符,但Flann或暴力匹配器为目标提供了不正确的匹配结果。因此,当我进一步尝试使用FindHomeography()时,它显示了不正确的结果,将源映射到目标上的其他位置,而不是目标中的正确面(ALIMG)。 虽然下面没有显示代码,但在Knnmatch之后,我在c1.jpg和allimag.jpg上绘制了一个边界矩形,并在匹配后显示了图像。我发现源边界矩形是正确的,但allimag的边界矩形非常大,包括源面。它应该在目标中找到源面。 Iam使用opencv 3.0。 有人面临过这样的问题吗?是否有其他匹配器可以准确地在目标中找到源图像(人脸或任何东西) 我已经给出了下面的代码和图片(通过链接给出):C++ 使用BruteForceMatcher或FlannBasedMatcher的KnnMatch进行的人脸/图像匹配不正确,c++,C++,Iam试图使用ORB检测器/描述符和Flann或暴力匹配器在较大的目标图像(allimg.jpg-包含3个面)中识别源图像(c1.jpg-面)。c1.jpg是从allimg.jpg中裁剪/复制而成的。 ORB检测器/描述符按预期工作,正确返回检测器/描述符,但Flann或暴力匹配器为目标提供了不正确的匹配结果。因此,当我进一步尝试使用FindHomeography()时,它显示了不正确的结果,将源映射到目标上的其他位置,而不是目标中的正确面(ALIMG)。 虽然下面没有显示代码,但在Knnmat
#包括
#包括
#包括
使用名称空间std;
使用名称空间cv;
常数双nn_匹配比=0.80f;//最近邻匹配比
常数双ransac_thresh=2.5f;//朗萨克内里阈值
const int bb_min_inliers=100;//要绘制BBox的最小内联线数
Mat-img1;
Mat-img2;
布尔使用单应(常量向量和查询点)细化匹配,
常量向量和列车关键点,
浮动重投影保留,
向量与匹配,
Mat(单应性)
{
常量int minNumberMatchesAllowed=4;
if(matches.size()谢谢EdChum。我使用了链接(ratiotest/symmetrytest)中给出的代码,并且只有当源映像是目标的一部分时,它才提供了一些ok映像匹配,尽管它不够精确。请注意,我注释掉了上一次Transactest,因为它不必要地删除了很多正片。
我附上了两张图片(source.jpg/destination.jpg),通过突出显示destination中匹配的部分来显示Iam所说的内容。
是否有更准确/正确(>90%)识别目的地来源的算法
另外,如果源是一个类似的图像(和目的地的图像不一样),我发现目的地的图像匹配是不正确的,没有用的。我说的对吗?
请分享你的观点。
=source,=destination谢谢EdChum。我使用了链接中给出的代码(ratiotest/symmetrytest),并且只有当sourceimage是目的地的一部分时,它才提供了一些ok的图像匹配,尽管它不够准确。注意,我确实注释掉了上一次Transactest,因为它不必要地删除了很多正片。
我附上了两张图片(source.jpg/destination.jpg),通过突出显示destination中匹配的部分来显示Iam所说的内容。
是否有更准确/正确(>90%)识别目的地来源的算法
另外,如果源是一个类似的图像(和目的地的图像不一样),我发现目的地的图像匹配是不正确的,没有用的。我说的对吗?
请分享你的观点。
=source,=destination我建议使用比率测试和对称匹配来删除异常值和可能的ransac尽管在我的情况下删除了太多的特征,请参见:我建议使用比率测试和对称匹配来删除异常值和可能的ransac尽管在我的情况下删除了太多的特征,请参见:imag没有附加E,因此我在此处执行:[1]=源,[2]=目标[1]:[2]:图像未附加,因此我在此处执行:[1]=源,[2]=目标[1]:[2]:
#include <opencv2/core/core.hpp>
#include <opencv2\opencv.hpp>
#include <opencv2/features2d/features2d.hpp>
using namespace std;
using namespace cv;
const double nn_match_ratio = 0.80f; // Nearest-neighbour matching ratio
const double ransac_thresh = 2.5f; // RANSAC inlier threshold
const int bb_min_inliers = 100; // Minimal number of inliers to draw BBox
Mat img1;
Mat img2;
bool refineMatchesWithHomography(const vector<cv::KeyPoint>& queryKeypoints,
const vector<cv::KeyPoint>& trainKeypoints,
float reprojectionThreshold,
vector<cv::DMatch>& matches,
Mat& homography )
{
const int minNumberMatchesAllowed = 4;
if (matches.size() <minNumberMatchesAllowed)
return false;
// Prepare data for cv::findHomography
vector<cv::Point2f> queryPoints(matches.size());
std::vector<cv::Point2f> trainPoints(matches.size());
for (size_t i = 0; i <matches.size(); i++)
{
queryPoints[i] = queryKeypoints[matches[i].queryIdx].pt;
trainPoints[i] = trainKeypoints[matches[i].trainIdx].pt;
}
// Find homography matrix and get inliers mask
std::vector<unsigned char> inliersMask(matches.size());
homography = findHomography(queryPoints,
trainPoints,
CV_FM_RANSAC,
reprojectionThreshold,
inliersMask);
vector<cv::DMatch> inliers;
for (size_t i=0; i<inliersMask.size(); i++)
{
if (inliersMask[i])
inliers.push_back(matches[i]);
}
matches.swap(inliers);
Mat homoShow;
drawMatches (img1,queryKeypoints,img2,trainKeypoints,matches,homoShow,
Scalar::all(-1),CV_RGB(255,255,255), Mat(), 2);
imshow("homoShow",homoShow);
waitKey(100000);
return matches.size() > minNumberMatchesAllowed;
}
int main()
{
//Stats stats;
vector<String> fileName;
fileName.push_back("D:\\pmn\\c1.jpg");
fileName.push_back("D:\\pmn\\allimg.jpg");
img1 = imread(fileName[0], CV_LOAD_IMAGE_COLOR);
img2 = imread(fileName[1], CV_LOAD_IMAGE_COLOR);
if (img1.rows*img1.cols <= 0)
{
cout << "Image " << fileName[0] << " is empty or cannot be found\n";
return(0);
}
if (img2.rows*img2.cols <= 0)
{
cout << "Image " << fileName[1] << " is empty or cannot be found\n";
return(0);
}
// keypoint for img1 and img2
vector<KeyPoint> keyImg1, keyImg2;
// Descriptor for img1 and img2
Mat descImg1, descImg2;
Ptr<Feature2D> porb = ORB::create(500,1.2f,8,0,0,2,0,14);
porb->detect(img2, keyImg2, Mat());
// and compute their descriptors with method compute
porb->compute(img2, keyImg2, descImg2);
// We can detect keypoint with detect method
porb->detect(img1, keyImg1,Mat());
// and compute their descriptors with method compute
porb->compute(img1, keyImg1, descImg1);
//FLANN parameters
// Ptr<flann::IndexParams> indexParams =
makePtr<flann::LshIndexParams> (6, 12, 1);
// Ptr<flann::SearchParams> searchParams = makePtr<flann::SearchParams>
(50);
String itMatcher = "BruteForce-L1";
Ptr<DescriptorMatcher>
matdescriptorMatchercher(newcv::BFMatcher(cv::NORM_HAMMING, false));
vector<vector<DMatch> > matches,bestMatches;
vector<DMatch> m;
matdescriptorMatchercher->knnMatch(descImg1, descImg2, matches,2);
const float minRatio = 0.95f;//1.f / 1.5f;
for (int i = 0; i<matches.size(); i++)
{
if(matches[i].size()>1)
{
DMatch& bestMatch = matches[i][0];
DMatch& betterMatch = matches[i][1];
float distanceRatio = bestMatch.distance / betterMatch.distance;
if (distanceRatio <minRatio)
{
bestMatches.push_back(matches[i]);
m.push_back(bestMatch);
}
}
}
Mat homo;
float homographyReprojectionThreshold = 1.0;
bool homographyFound = refineMatchesWithHomography(
keyImg1,keyImg2,homographyReprojectionThreshold,m,homo);
return 0;
}
[c1.jpg][1]
[allimg.jpg][2]
[1]: http://i.stack.imgur.com/Uuy3o.jpg
[2]: http://i.stack.imgur.com/Kwne7.jpg