2014-04-21 118 views
0

這是我從視頻獲取幀的代碼。我想在循環和條件下在視頻中顯示2幀。使用opencv獲取幀視頻

int main(int argc, char** argv) 
    {  

    string fileName = "E:\\Tugas Akhir\\Video Master\\city_1.avi"; 
    Mat image1; 
    Mat image2; 
    Mat frame; 
    cv::Mat result; 
    VideoCapture cap(fileName); 
    if(!cap.isOpened()) 
     return -1; 

    Mat edges; 
    for(int loop=0;;loop++) 
    { 
     //std::cout<<loop<<endl; 
     cap >> frame; // get a new frame from camera 
     if(loop>0 && (loop%20)==0){    
      //std::cout<<"frame 2"<<endl; 
      image2=frame;        
      **imshow("image2",image2);** 
      break;  
     }else if(loop==0){   
      image1=frame; 
      **imshow("image1",image1);** 
      //std::cout<<"frame 1"<<endl; 

     } 
     //loop++; 


     if(waitKey(30) >= 0) break; 
    } 


waitKey(0); 
return 0; 
} 

而這裏的結果,2個窗口有2個不同的圖像

enter image description here

,但是當我改變imshow( 「圖像1」,此搜索)方式的位置...

  if(loop>0 && (loop%20)==0){    
      //std::cout<<"frame 2"<<endl; 
      image2=frame; 

      **imshow("image1",image1);** 
      **imshow("image2",image2);** 
      break;  
     }else if(loop==0){   
      image1=frame; 

      //std::cout<<"frame 1"<<endl; 

     } 

image1窗口顯示與圖片2相同的圖片, enter image description here

我不知道爲什麼它顯示奇怪的結果,請告訴我如何解決它,謝謝

+0

目前尚不清楚你將要做什麼。 – rmi

回答

3

的分配是這樣的:

image1 = frame; 

只做一個副本。 Mat結構被複制,像素是共享

所以,在你的第二個例子中,你用當前幀覆蓋image1。如果你想「緩存」墊,使用方法:

image1 = frame.clone(); // deep copy 
+1

另外,您可以使用Mat :: copyTo()方法深度複製Mat。另一種方法是在原始Mat上使用任何操作(例如A = 1.0 * B;或A = B + 0.0;將B中的數據複製到A)。 –

+0

感謝您的回答,我會嘗試:D –

0

你面對什麼本質上是缺乏的OpenCV墊的重載=運營商copy-on-write支持。這基本上意味着image1frame將分享他們的數據。

看到這個的一個便利方法是,當您編寫image1 = frame,稱爲「淺拷貝」時,您正在爲Mat frame創建參考image1。因此,經過20次迭代,當您顯示image1時,您實際上正在顯示frame本身。

如果你寫了類似image1 = frame.clone()的東西,情況就不是這樣,因爲在那種情況下,你實際上正在製作一個frame的單獨副本。

也檢查this了。