2012-07-04 89 views
1

我將Mat對象推入std :: vector。將OpenCv Mat插入到C++ 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(); 
} 

回答

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()); 
+0

非常感謝您解釋Mat如何工作。我一直都有錯誤的理解!順便說一句,我通過將「transposedFrame」和「rotatedFrame」的聲明轉換爲「for」循環來解決這個問題。 – seveleven

+0

很高興知道它有幫助,而且我的想法並沒有隨着時間而消失。:) – SuperSaiyan