Opencv Feature Matching 不能正确匹配不同尺寸的裁剪图像和从各种来源获取的图像?
Opencv Feature Matching is not matching correctly for cropped images of different sizes and images taken from various sources?
我正在尝试匹配两个图像,一个是手机屏幕的屏幕截图,模板图像是任何应用程序 icon.If 我匹配从相同图像裁剪的源和模板,它匹配 perfectly.But 当我使用从不同的移动屏幕裁剪的应用程序图标未正确匹配。
对于图像匹配,我正在处理以下代码:
int main( int argc, char** argv )
{
Mat objectImg = imread("source.jpg", cv::IMREAD_GRAYSCALE);
Mat sceneImg = imread("note4-3.jpg", cv::IMREAD_GRAYSCALE);
//cv::resize(sceneImg,sceneImg,objectImg.size(),0,0,CV_INTER_CUBIC);
if( !objectImg.data || !sceneImg.data )
{
printf( " No image data \n " );
return -1337;
}
std::vector<cv::KeyPoint> objectKeypoints;
std::vector<cv::KeyPoint> sceneKeypoints;
cv::Mat objectDescriptors;
cv::Mat sceneDescriptors;
Ptr<FeatureDetector> detector;
detector = cv::MSER::create();
detector->detect(objectImg, objectKeypoints);
detector->detect(sceneImg, sceneKeypoints);
Ptr<DescriptorExtractor> extractor = cv::ORB::create();
extractor->compute( objectImg, objectKeypoints, objectDescriptors );
extractor->compute( sceneImg, sceneKeypoints, sceneDescriptors );
if(objectDescriptors.type()!=CV_32F) {
objectDescriptors.convertTo(objectDescriptors, CV_32F);
}
if(sceneDescriptors.type()!=CV_32F) {
sceneDescriptors.convertTo(sceneDescriptors, CV_32F);
}
vector< vector<DMatch> > matches;
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce");
matcher->knnMatch( objectDescriptors, sceneDescriptors, matches, 8 );
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < objectDescriptors.rows; i++ )
{
double dist = matches[i][0].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
std::vector<cv::DMatch> good_matches;
for( int i = 0; i < objectDescriptors.rows; i++ )
{
if( matches[i][0].distance <= max(2*min_dist, 0.02) ) {
good_matches.push_back( matches[i][0]);
}
}
//look whether the match is inside a defined area of the image
//only 25% of maximum of possible distance
/*double tresholdDist = 0.50 * sqrt(double(sceneImg.size().height*sceneImg.size().height + sceneImg.size().width*sceneImg.size().width));
vector< DMatch > good_matches2;
good_matches2.reserve(matches.size());
for (size_t i = 0; i < matches.size(); ++i)
{
for (int j = 0; j < matches[i].size(); j++)
{
Point2f from = objectKeypoints[matches[i][j].queryIdx].pt;
Point2f to = sceneKeypoints[matches[i][j].trainIdx].pt;
//calculate local distance for each possible match
double dist = sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y));
//save as best match if local distance is in specified area and on same height
if (dist < tresholdDist && abs(from.y-to.y)<5)
{
good_matches2.push_back(matches[i][j]);
j = matches[i].size();
}
}
}*/
Mat allmatchs;
drawMatches(objectImg,objectKeypoints,sceneImg,sceneKeypoints,good_matches,allmatchs,Scalar::all(-1), Scalar::all(-1),vector<char>(),0);
namedWindow("Matchs" , CV_WINDOW_NORMAL);
imshow( "Matchs",allmatchs);
waitKey(0);
}
[从不同来源裁剪时匹配错误][1]
以上结果是将来自一个手机屏幕截图的源与来自不同屏幕截图的模板进行匹配时得到的。
我用的是opencv3.0
请帮助我是否更改了代码,或者我是否必须使用模板匹配或其他一些technique.I 不能使用 SUR 检测器,因为由于许可证冲突我无法使用付费版本??
示例图片:
查看您提供的图片,我可以提出一些更改建议,以帮助您解决问题。
- 删除 select 良好的匹配项,这会在存在尖锐特征时产生问题。与其他良好匹配相比,锐化特征的汉明距离非常小。当您 select 2*min_dist 时,您间接地忽略了可能的良好匹配。
- 确保目标图像中具有合理数量的特征点。
- 如果此特征检测器和描述符组合无法解决问题,select 其他特征检测器和描述符,如 STAR-BRIEF、SURF,它们比 MSER-ORB 好得多。
- 在你的情况下,detector-matcher不需要旋转不变,它应该是尺度不变的。所以试试 re-sizing object image
希望我的建议对您有所帮助
我通过以下组合得到了更好的匹配:
风探测器
风提取器
BruteForce-L1 匹配器
结合以下link
中给出的交叉检查匹配
我正在尝试匹配两个图像,一个是手机屏幕的屏幕截图,模板图像是任何应用程序 icon.If 我匹配从相同图像裁剪的源和模板,它匹配 perfectly.But 当我使用从不同的移动屏幕裁剪的应用程序图标未正确匹配。
对于图像匹配,我正在处理以下代码:
int main( int argc, char** argv )
{
Mat objectImg = imread("source.jpg", cv::IMREAD_GRAYSCALE);
Mat sceneImg = imread("note4-3.jpg", cv::IMREAD_GRAYSCALE);
//cv::resize(sceneImg,sceneImg,objectImg.size(),0,0,CV_INTER_CUBIC);
if( !objectImg.data || !sceneImg.data )
{
printf( " No image data \n " );
return -1337;
}
std::vector<cv::KeyPoint> objectKeypoints;
std::vector<cv::KeyPoint> sceneKeypoints;
cv::Mat objectDescriptors;
cv::Mat sceneDescriptors;
Ptr<FeatureDetector> detector;
detector = cv::MSER::create();
detector->detect(objectImg, objectKeypoints);
detector->detect(sceneImg, sceneKeypoints);
Ptr<DescriptorExtractor> extractor = cv::ORB::create();
extractor->compute( objectImg, objectKeypoints, objectDescriptors );
extractor->compute( sceneImg, sceneKeypoints, sceneDescriptors );
if(objectDescriptors.type()!=CV_32F) {
objectDescriptors.convertTo(objectDescriptors, CV_32F);
}
if(sceneDescriptors.type()!=CV_32F) {
sceneDescriptors.convertTo(sceneDescriptors, CV_32F);
}
vector< vector<DMatch> > matches;
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce");
matcher->knnMatch( objectDescriptors, sceneDescriptors, matches, 8 );
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < objectDescriptors.rows; i++ )
{
double dist = matches[i][0].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
std::vector<cv::DMatch> good_matches;
for( int i = 0; i < objectDescriptors.rows; i++ )
{
if( matches[i][0].distance <= max(2*min_dist, 0.02) ) {
good_matches.push_back( matches[i][0]);
}
}
//look whether the match is inside a defined area of the image
//only 25% of maximum of possible distance
/*double tresholdDist = 0.50 * sqrt(double(sceneImg.size().height*sceneImg.size().height + sceneImg.size().width*sceneImg.size().width));
vector< DMatch > good_matches2;
good_matches2.reserve(matches.size());
for (size_t i = 0; i < matches.size(); ++i)
{
for (int j = 0; j < matches[i].size(); j++)
{
Point2f from = objectKeypoints[matches[i][j].queryIdx].pt;
Point2f to = sceneKeypoints[matches[i][j].trainIdx].pt;
//calculate local distance for each possible match
double dist = sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y));
//save as best match if local distance is in specified area and on same height
if (dist < tresholdDist && abs(from.y-to.y)<5)
{
good_matches2.push_back(matches[i][j]);
j = matches[i].size();
}
}
}*/
Mat allmatchs;
drawMatches(objectImg,objectKeypoints,sceneImg,sceneKeypoints,good_matches,allmatchs,Scalar::all(-1), Scalar::all(-1),vector<char>(),0);
namedWindow("Matchs" , CV_WINDOW_NORMAL);
imshow( "Matchs",allmatchs);
waitKey(0);
}
[从不同来源裁剪时匹配错误][1]
以上结果是将来自一个手机屏幕截图的源与来自不同屏幕截图的模板进行匹配时得到的。
我用的是opencv3.0
请帮助我是否更改了代码,或者我是否必须使用模板匹配或其他一些technique.I 不能使用 SUR 检测器,因为由于许可证冲突我无法使用付费版本??
示例图片:
查看您提供的图片,我可以提出一些更改建议,以帮助您解决问题。
- 删除 select 良好的匹配项,这会在存在尖锐特征时产生问题。与其他良好匹配相比,锐化特征的汉明距离非常小。当您 select 2*min_dist 时,您间接地忽略了可能的良好匹配。
- 确保目标图像中具有合理数量的特征点。
- 如果此特征检测器和描述符组合无法解决问题,select 其他特征检测器和描述符,如 STAR-BRIEF、SURF,它们比 MSER-ORB 好得多。
- 在你的情况下,detector-matcher不需要旋转不变,它应该是尺度不变的。所以试试 re-sizing object image
希望我的建议对您有所帮助
我通过以下组合得到了更好的匹配: 风探测器 风提取器 BruteForce-L1 匹配器 结合以下link
中给出的交叉检查匹配