1

Matオブジェクトをstd::vectorにプッシュしています。

しかし、その後要素(Mat)にアクセスしようとすると、frameOrientationによっては、以前にプッシュされた画像が表示されませんでした。

たとえば、以下の場合、「after_push_rotated2.jpg」は「before_push_rotated3.jpg」と同じになりますが、そうではありません。

frameOrientationをすべて「2s」または「4s」に設定すると、「after_push_rotated1 / 2 / 3.jpg」はすべて同一で、「before_push_rotated3.jpg」と等しくなります。

ここで何が問題になっていますか?

#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

vector<Mat> checkOrientationAndRotate()
{
    Mat frame1 = imread("1.jpg" );
    Mat frame2 = imread("2.jpg" );
    Mat frame3 = imread("3.jpg" );



    vector<Mat> frameList;
    vector<Mat> frameList_rotated;

    frameList.push_back(frame1);
    frameList.push_back(frame2);
    frameList.push_back(frame3);

    Mat transposedFrame;
    Mat rotatedFrame;

    int i=0;
    for (vector<Mat>::iterator iter = frameList.begin(); iter != frameList.end(); iter++)
    {
        //Check for orientation of that frame
        int frameOrientation;
        if (i==0) frameOrientation = 1;
        if (i==1) frameOrientation = 2;
        if (i==2) frameOrientation = 4;

        switch (frameOrientation)
        {
        case 1: //1 - no rotate
            rotatedFrame = *iter;
            break;

        case 2: //2 - rotate it ACW 90 deg
            transpose(*iter, transposedFrame);
            flip(transposedFrame, rotatedFrame, 0);
            break;

        case 3: //3 - rotate it 180deg
            flip(*iter, rotatedFrame, -1);
            break;

        case 4: //4 - rotate it CW 90 deg
            transpose(*iter, transposedFrame);
            flip(transposedFrame, rotatedFrame, 1);
            break;
        default:
            break;
        }

        //Check frame before pushing into vector
        if (i==0) imwrite("before_push_rotated1.jpg",rotatedFrame);
        if (i==1) imwrite("before_push_rotated2.jpg",rotatedFrame);
        if (i==2) imwrite("before_push_rotated3.jpg",rotatedFrame);

        frameList_rotated.push_back(rotatedFrame);


        //Check frame after pushing into vector.
        //Depending on the frameorientation, the frames are not the frames pushed in earlier!
        int n=0;
        for (vector<Mat>::iterator iter = frameList_rotated.begin(); iter != frameList_rotated.end(); iter++)
        {
            Mat frame = *iter;
            if (n==0) imwrite("after_push_rotated1.jpg",frame);
            if (n==1) imwrite("after_push_rotated2.jpg",frame);
            if (n==2) imwrite("after_push_rotated3.jpg",frame);
            n++;
        }

        i++;
        } //for

        return frameList_rotated;

}

void main()
{
    vector<Mat> frameList_rotated = checkOrientationAndRotate();
}
4

1 に答える 1

7

[私は最近OpenCVを使用していなかったので、間違っている可能性があります。私がそうであるかどうか教えてください:)]

Mat画像データではなく、画像ヘッダー(の一種)を表します。OpenCVは、内部で参照カウントメカニズムを維持して、さまざまな領域に大量の画像-ピクセル-データがコピーされるのを防ぎます。あなたが言うときそれを言うことを意味する:

Mat a = b; // Only headers are copied, both a and b refer to the same image.

上記の場合、を変更するbと、その変更も反映さaれます。その場合に使用する必要があるのは次のとおりです。

Mat a = b.clone();

あなたのケースについては、次の行で問題が解決するはずだと思います(そうでない場合は、制御フローに他の問題がある可能性があります)。

交換してみてください:

Mat transposedFrame;
Mat rotatedFrame;

と:

 //create a new image, not just the headers..
Mat transposedFrame(Size(image_width, image_height), image.type());
Mat rotatedFrame(Size(image_width, image_height), image.type());
于 2012-07-04T16:53:16.030 に答える