0

私の問題を正しく説明するタイトルがわかりませんでした。これが紛らわしくないことを願っています。

私は数日前に OpenCV の冒険を始めました。今日まで、インターネット カメラからのライブ ストリームでチェス盤を見つけて、サイズを変更した画像を表示することができました。次の目標は、チェス盤を回転させているときに、プログラムに画像を回転させることです。残念ながら、それを行う方法がわかりません。多くのコード、多くの例を見ましたが、どれも役に立ちませんでした。私の最後の目標は、次のようなことをすることです: http://www.youtube.com/watch?v=APxgPYZOd0I (彼のコードからは何も得られません。彼は Qt を使用しています。それに興味があります-まだ)。

これが私のコードです:

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <string>

using namespace cv;
using namespace std;

vector<Point3f> Create3DChessboardCorners(Size boardSize, float squareSize);

int main(int argc, char* argv[])
{
Size boardSize(6,9);
float squareSize=1.f;
namedWindow("Viewer");
namedWindow("zdjecie");
namedWindow("changed");

Mat zdjecie=imread("D:\\Studia\\Programy\\cvTest\\Debug\\przyklad.JPG");
resize(zdjecie, zdjecie, Size(200,150));
Mat changed=Mat(zdjecie);
imshow("zdjecie", changed);

vector<Point2f> corners;

VideoCapture video(0);
cout<<"video height: "<<video.get(CV_CAP_PROP_FRAME_HEIGHT)<<endl;
cout<<"video width: "<<video.get(CV_CAP_PROP_FRAME_WIDTH)<<endl;
Mat frame;
bool found;
Point2f src[4];
Point2f dst[4];
Mat perspMat;

while(1)
{
    video>>frame;
    found=findChessboardCorners(frame, boardSize, corners, CALIB_CB_FAST_CHECK);
    changed=Mat(zdjecie);
//      drawChessboardCorners(frame, boardSize, Mat(corners), found);

    if(found)
    {
        line(frame, corners[0], corners[5], Scalar(0,0,255));
        line(frame, corners[0], corners[48], Scalar(0,0,255));
        src[0].x=0;
        src[0].y=0;
        src[1].x=zdjecie.cols;
        src[1].y=0;

        src[2].x=zdjecie.cols;
        src[2].y=zdjecie.rows;
        src[3].x=0;
        src[3].y=zdjecie.rows;

        dst[0].x=corners[0].x;
        dst[0].y=corners[0].y;
        dst[1].x=corners[boardSize.width-1].x;
        dst[1].y=corners[boardSize.width-1].y;

        dst[2].x=corners[boardSize.width*boardSize.height-1].x;
        dst[2].x=corners[boardSize.width*boardSize.height-1].y;
        dst[3].x=corners[boardSize.width*(boardSize.height-1)].x;
        dst[3].y=corners[boardSize.width*(boardSize.height-1)].y;

        perspMat=getPerspectiveTransform(src, dst);
        warpPerspective(zdjecie, changed, perspMat, frame.size());
}
imshow("changed", changed);
            imshow("Viewer", frame);
            if(waitKey(20)!=-1)
            break;
}
return 0;
}

私はこのコードを理解しようとしていました: http://dsynflo.blogspot.com/2010/06/simplar-augmented-reality-for-opencv.html しかし、何も役に立ちませんでした。私のウェブカメラからの画像が反転し、フレームが数秒ごとに変化し、何も表示されませんでした。

したがって、私が求めているのは完全な解決策ではありません。誰かがそれを行う方法を説明してくれたら、うれしいです。基礎から理解したいのですが、今どこに行けばいいのかわかりません。私はそれを解決するために多くの時間を費やしました.もしそうしなければ,私の問題であなたを悩ませません.

私はあなたの答えを楽しみにしています!

こんにちは、ダニエル

編集: コードを変更しました。これで、画像の遠近法を歪めようとしている様子がわかります。まず、warpPerspective 関数を呼び出した後、画像のマットが変更された理由 (Mat krzywe です。混乱しないように名前を変更しました) は、基本的な写真から毎回パースペクティブをワープし始めていないためだと考えました。 . だから私は行 changed=Mat(zdjecie) を追加しました

私の問題は解決するのがかなり簡単だと思いますが、今は本当にわかりません。

4

1 に答える 1

0

私が見る限り、2つの問題があります。まず、ワープ元とワープ先の座標が間違っています。ソース座標は、単純にソース イメージの角です。

    src[0].x=0;
    src[0].y=0;
    src[1].x=zdjecie.cols;
    src[1].y=0;

    src[2].x=zdjecie.cols;
    src[2].y=zdjecie.rows;
    src[3].x=0;
    src[3].y=zdjecie.rows;

宛先座標は、見つかったチェス盤の点の角の点でなければなりません。どの点が角になるかは、チェス盤の大きさによって変わります。私のチェス盤は異なる寸法を持っていたので、ボードのサイズを考慮して適応させようとしました:

    dst[0].x=corners[0].x;
    dst[0].y=corners[0].y;
    dst[1].x=corners[ boardSize.width-1 ].x;
    dst[1].y=corners[ boardSize.width-1 ].y;

    dst[2].x=corners[ boardSize.width * boardSize.height - 1 ].x;
    dst[2].y=corners[ boardSize.width * boardSize.height - 1 ].y;
    dst[3].x=corners[ boardSize.width * (boardSize.height-1) ].x;
    dst[3].y=corners[ boardSize.width * (boardSize.height-1) ].y;

2 つ目の問題は、ソース イメージのサイズしかないイメージにワープすることです。ただし、ターゲット イメージのサイズが必要です。

    warpPerspective(zdjecie, changed, perspMat, frame.size());

もう 1 つ変わったことは、imshow("Viewer", frame);呼び出しが if 句の中にあることです。つまり、チェス盤が見つかった場合にのみ画像が更新されます。それが意図されていたかどうかはわかりません。

ビデオを表示する 1 つのウィンドウと、変換されたソース画像を表示する別のウィンドウが表示されます。次のステップは、両方の画像をブレンドすることです。

アップデート:

2つの画像をマージする方法は次のとおりです。

Mat mask = changed > 0;
Mat merged = frame.clone();
changed.copyTo(merged,mask);

mask行列はtrue、ワープされた画像でゼロではないすべてのピクセル用です。次に、ワープされた画像のゼロ以外のすべてのピクセルがフレームにコピーされます。

于 2013-09-13T22:13:51.933 に答える