我有一个用于输入图片的程序,谁的目标是确定该图片中是否包含某个对象(本质上是一个图像)。如果是这样,它将尝试估计其位置。当对象在图片中时,这确实非常有效。但是,当我在图片中放置足够复杂的内容时,我会得到很多误报。
我想知道是否有什么好的方法可以滤除这些误报。希望有些东西在计算上不会太昂贵。
我的程序基于the tutorial found here。除非我使用BRISK
而不是SURF
,所以我不需要contrib的东西。
我如何获得比赛
descriptorMatcher->match(descImg1, descImg2, matches, Mat());
良好比赛
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descImg1.rows; i++ )
{ double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
std::vector< DMatch > good_matches;
for( int i = 0; i < descImg1.rows; i++ )
{ if( matches[i].distance < 4*min_dist )
{ good_matches.push_back( matches[i]); }
}
HOMOGRAPHY
std::vector<Point2f> obj;
std::vector<Point2f> scene;
for( int i = 0; i < good_matches.size(); i++ )
{
//-- Get the keypoints from the good matches
obj.push_back( keyImg1[ good_matches[i].queryIdx ].pt );
scene.push_back( keyImg2[ good_matches[i].trainIdx ].pt );
}
Mat H = findHomography( obj, scene, FM_RANSAC );
对象角
std::vector<Point2f> obj_corners(4);
obj_corners[0] = cvPoint(0,0); obj_corners[1] = cvPoint( img1.cols, 0 );
obj_corners[2] = cvPoint( img1.cols, img1.rows ); obj_corners[3] = cvPoint( 0, img1.rows );
std::vector<Point2f> scene_corners(4);
perspectiveTransform( obj_corners, scene_corners, H);
最佳答案
您无法完全消除误报。这就是为什么使用RANSCAC算法查找单应性的原因。但是,您可以检查估计的单应性是否为“良好”。有关详细信息,请参见this question。如果估计的单应性是错误的,则可以将其丢弃,并假设未发现任何物体。由于至少需要4个相应的点来估计单应性,因此可以拒绝使用比预定阈值(例如6)少的点来估计的单应性。这可能会过滤掉所有错误估计的单应性:
int minInliers = 6; //can be any value > 4
double reprojectionError = 3; // default value, you can change it to some lower to get more reliable estimation.
Mat mask;
Mat H = findHomography( obj, scene, FM_RANSAC, reprojectionError, mask );
int inliers = 0;
for (int i=0; i< mask.rows; ++i)
{
if(mask[i] == 1) inliers++;
}
if(inliers > minInliers)
{
//homography is good
}
您也可以测试原始SIFT论文中提出的方法以获得更好的匹配。您需要找到每个查询点最接近的两个描述符,然后检查它们之间的距离之比是否小于阈值(David Lowe建议0.8)。有关详细信息,请检查this link:
descriptorMatcher->knnMatch( descImg1, descImg2, knn_matches, 2 );
//-- Filter matches using the Lowe's ratio test
const float ratio_thresh = 0.8f;
std::vector<DMatch> good_matches;
for (size_t i = 0; i < knn_matches.size(); i++)
{
if (knn_matches[i][0].distance < ratio_thresh * knn_matches[i][1].distance)
{
good_matches.push_back(knn_matches[i][0]);
}
}
关于c++ - 从特征匹配/单应性中滤除误报– OpenCV,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57075719/