4

SURF を使用してシーン内の参照画像を見つける場合、シーン内で見つかったオブジェクトをトリミングし、warpPerspective と逆ホモグラフィ マトリックスを使用してそれを「まっすぐ」に戻したいと思います。

つまり、この SURF の結果があるとしましょう:
ここに画像の説明を入力

今、シーンで見つかったオブジェクトをトリミングしたいと思います:
ここに画像の説明を入力

逆ホモグラフィ行列を使用して、warpPerspective でトリミングされた画像のみを「まっすぐ」にします。私が目指している結果は、大まかにオブジェクトのみと、元のシーンからのいくつかの歪んだ残り物を含む画像を取得することです (トリミングは 100% オブジェクトだけではないため)。

見つかったオブジェクトをトリミングし、ホモグラフィ行列を見つけて逆にするのは簡単です。問題は、warpPerspective の結果を理解できないようです。結果の画像には、トリミングされた画像のごく一部しか含まれておらず、非常に大きなサイズになっているようです。
warpPerspective を調査しているときに、プロセスの性質上、結果の画像が非常に大きいことがわかりましたが、これを適切に行う方法について頭を悩ませているようには見えません。プロセスをよく理解していないようです。元の(トリミングされていない)画像をワープパースペクティブにして、「まっすぐにした」オブジェクトをトリミングする必要がありますか?

何かアドバイス?

4

1 に答える 1

2

これを試して。

オブジェクトの接続されていない輪郭 (ボックスの輪郭の外側の角の点など) がある場合、それらを逆ホモグラフィで変換し、そのホモグラフィを調整して、その変換の結果を画像の左上の領域に配置できます。

  1. これらのオブジェクト ポイントがワープされる場所を計算します (逆ホモグラフィと輪郭ポイントを入力として使用します)。

    cv::Rect computeWarpedContourRegion(const std::vector<cv::Point> & points, const cv::Mat & homography)
    {
        std::vector<cv::Point2f> transformed_points(points.size());
    
        for(unsigned int i=0; i<points.size(); ++i)
        {
            // warp the points
            transformed_points[i].x = points[i].x * homography.at<double>(0,0) + points[i].y * homography.at<double>(0,1) + homography.at<double>(0,2) ;
            transformed_points[i].y = points[i].x * homography.at<double>(1,0) + points[i].y * homography.at<double>(1,1) + homography.at<double>(1,2) ;
        }
    
        // dehomogenization necessary?
        if(homography.rows == 3)
        {
            float homog_comp;
            for(unsigned int i=0; i<transformed_points.size(); ++i)
            {
                homog_comp = points[i].x * homography.at<double>(2,0) + points[i].y * homography.at<double>(2,1) + homography.at<double>(2,2) ;
                transformed_points[i].x /= homog_comp;
                transformed_points[i].y /= homog_comp;
            }
        }
    
        // now find the bounding box for these points:
        cv::Rect boundingBox = cv::boundingRect(transformed_points);
        return boundingBox;
    }
    
  2. 逆ホモグラフィを変更します (computeWarpedContourRegion および入力としての inverseHomography の結果)

    cv::Mat adjustHomography(const cv::Rect & transformedRegion, const cv::Mat & homography)
    {
        if(homography.rows == 2) throw("homography adjustement for affine matrix not implemented yet");
    
        // unit matrix
        cv::Mat correctionHomography = cv::Mat::eye(3,3,CV_64F);
        // correction translation
        correctionHomography.at<double>(0,2) = -transformedRegion.x;
        correctionHomography.at<double>(1,2) = -transformedRegion.y;
    
    
        return correctionHomography * homography;
    }
    
  3. あなたは次のようなものを呼び出します

cv::warpPerspective(objectWithBackground, output, adjustedInverseHomography, sizeOfComputeWarpedContourRegionResult);

これが役立つことを願っています=)

于 2014-06-26T08:27:19.403 に答える