7

この質問に対する答えが得られなかった後、私はいくつかの興味深い解決策に出くわしました。

この投稿の Robust Matcher と、この投稿Canny Detectorです。

をセットアップし、Canny Edge Detectorそのドキュメントを参照して、リンクした最初のページに示されているものを実装した後Robust Matcher、いくつかのロゴ/衣服の画像を取得し、2 つを組み合わせてある程度の成功を収めました。

そのロゴが付いている衣料品の写真と一致するロゴの写真

しかし、他の非常によく似たケースでは、それはオフでした:

上記と「まったく」同じデザインの別のロゴ画像、同じ服の画像。

それで、与えられた画像の特定の領域を定義する画像上のいくつかの特定のポイントを一致させる方法はありますか?

したがって、画像を読み込んでからすべてのマッチングを行う代わりに、keypoints「悪い」keypointsなどを破棄します。ある画像が別の画像とどのように関連しているかをシステムに認識keypointさせ、ある画像で正しい一致を破棄することは可能ですか?隣り合っているのに、全く別の場所にいる?

(左の画像ではライトブルーとロイヤルブルーの「マッチ」が隣り合っていますが、右の画像では完全に別の部分でマッチしています)

編集

ミカのために

ここに画像の説明を入力

(ペイントで追加された)ホワイトボックスの中央に「長方形」が描かれています。

cv::Mat ransacTest(const std::vector<cv::DMatch>& matches, const std::vector<cv::KeyPoint>& trainKeypoints, const std::vector<cv::KeyPoint>& testKeypoints, std::vector<cv::DMatch>& outMatches){
// Convert keypoints into Point2f
std::vector<cv::Point2f> points1, points2;
cv::Mat fundemental;
for (std::vector<cv::DMatch>::const_iterator it= matches.begin(); it!= matches.end(); ++it){
    // Get the position of left keypoints
    float x= trainKeypoints[it->queryIdx].pt.x;
    float y= trainKeypoints[it->queryIdx].pt.y;
    points1.push_back(cv::Point2f(x,y));
    // Get the position of right keypoints
    x= testKeypoints[it->trainIdx].pt.x;
    y= testKeypoints[it->trainIdx].pt.y;
    points2.push_back(cv::Point2f(x,y));
}
// Compute F matrix using RANSAC
std::vector<uchar> inliers(points1.size(), 0);
if (points1.size() > 0 && points2.size() > 0){
    cv::Mat fundemental= cv::findFundamentalMat(
    cv::Mat(points1),cv::Mat(points2), inliers, CV_FM_RANSAC, distance, confidence);
    // matching points - match status (inlier or outlier) - RANSAC method - distance to epipolar line - confidence probability - extract the surviving (inliers) matches
    std::vector<uchar>::const_iterator itIn= inliers.begin();
    std::vector<cv::DMatch>::const_iterator itM= matches.begin();
    // for all matches
    for ( ;itIn!= inliers.end(); ++itIn, ++itM){
        if (*itIn) { // it is a valid match
            outMatches.push_back(*itM);
        }
    }
    if (refineF){
        // The F matrix will be recomputed with
        // all accepted matches
        // Convert keypoints into Point2f
        // for final F computation
        points1.clear();
        points2.clear();

        for(std::vector<cv::DMatch>::const_iterator it = outMatches.begin(); it!= outMatches.end(); ++it){
            // Get the position of left keypoints
            float x = trainKeypoints[it->queryIdx].pt.x;
            float y = trainKeypoints[it->queryIdx].pt.y;
            points1.push_back(cv::Point2f(x,y));
            // Get the position of right keypoints
            x = testKeypoints[it->trainIdx].pt.x;
            y = testKeypoints[it->trainIdx].pt.y;
            points2.push_back(cv::Point2f(x,y));
        }

        // Compute 8-point F from all accepted matches
        if (points1.size() > 0 && points2.size() > 0){
            fundemental= cv::findFundamentalMat(cv::Mat(points1),cv::Mat(points2), CV_FM_8POINT); // 8-point method
        }
    }
}

Mat imgMatchesMat;
drawMatches(trainCannyImg, trainKeypoints, testCannyImg, testKeypoints, outMatches, imgMatchesMat);//, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
Mat H = findHomography(points1, points2, CV_RANSAC, 3); // -- Little difference when CV_RANSAC is changed to CV_LMEDS or 0
//-- Get the corners from the image_1 (the object to be "detected")
std::vector<Point2f> obj_corners(4);
obj_corners[0] = cvPoint(0,0); obj_corners[1] = cvPoint(trainCannyImg.cols, 0);
obj_corners[2] = cvPoint(trainCannyImg.cols, trainCannyImg.rows); obj_corners[3] = cvPoint(0, trainCannyImg.rows);
std::vector<Point2f> scene_corners(4);
perspectiveTransform(obj_corners, scene_corners, H);
//-- Draw lines between the corners (the mapped object in the scene - image_2 )
line(imgMatchesMat, scene_corners[0] + Point2f(trainCannyImg.cols, 0), scene_corners[1] + Point2f(trainCannyImg.cols, 0), Scalar(0, 255, 0), 4);
line(imgMatchesMat, scene_corners[1] + Point2f(trainCannyImg.cols, 0), scene_corners[2] + Point2f(trainCannyImg.cols, 0), Scalar(0, 255, 0), 4);
line(imgMatchesMat, scene_corners[2] + Point2f(trainCannyImg.cols, 0), scene_corners[3] + Point2f(trainCannyImg.cols, 0), Scalar(0, 255, 0), 4);
line(imgMatchesMat, scene_corners[3] + Point2f(trainCannyImg.cols, 0), scene_corners[0] + Point2f(trainCannyImg.cols, 0), Scalar(0, 255, 0), 4);
//-- Show detected matches
imshow("Good Matches & Object detection", imgMatchesMat);
waitKey(0);

return fundemental;
}

ホモグラフィ出力

わずかに異なる入力シナリオ (絶えず変化するため、上記の画像を完全に繰り返すための正確な条件を把握するには時間がかかりすぎます) が、結果は同じです:

Object (52, 37)
Scene  (219, 151)
Object (49, 47)
Scene  (241,139)
Object (51, 50)
Scene  (242, 141)
Object (37, 53)
Scene  (228, 145)
Object (114, 37.2)
Scene  (281, 162)
Object (48.96, 46.08)
Scene  (216, 160.08)
Object (44.64, 54.72)
Scene  (211.68, 168.48)

問題の画像:

ここに画像の説明を入力

4

0 に答える 0