2016-04-25 7 views
1

Я хочу вычесть два последовательных изображения, взятых с веб-камеры. , как вы можете видеть, я делаю это внутри цикла while. В последней строке цикла while я устанавливаю frame2 = frame и поэтому могу вычесть их из следующей итерации. Но функция cv :: subtract возвращает вышеуказанную ошибку в терминале.Почему функция cv :: subtract() возвращает ошибку «размер входных аргументов не соответствует»?

что я делаю неправильно?

#include <iostream> 
#include "core.hpp" 
#include "highgui.hpp" 
#include "imgcodecs.hpp" 
#include "cv.h" 

using namespace std; 
using namespace cv; 


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

    VideoCapture cap(0); ///open the video camera no. 0 (laptop's default camera) 

    ///make a writer object: 
    cv::VideoWriter writer; 

    if (!cap.isOpened()) /// if not success, exit program 
    { 
     cout << "ERROR INITIALIZING VIDEO CAPTURE" << endl; 
     return -1; 
    } 

    char* windowName = "Webcam Feed(diff image)"; 
    namedWindow(windowName,WINDOW_NORMAL); ///create a window to display our webcam feed 


    ///we need to define 4 arguments for initializing the writer object: 
    //filename string: 
    string filename = "C:\\Users\\PEYMAN\\Desktop\\ForegroundExtraction\\openCV_tutorial\\2.writing from video to file\\Payman.avi"; 

    //fourcc integer: 
    int fcc = CV_FOURCC('D','I','V','3'); 

    //frame per sec integer: 
    int fps = 10; 

    //frame size: 
    cv::Size framesize(cap.get(CV_CAP_PROP_FRAME_WIDTH),cap.get(CV_CAP_PROP_FRAME_HEIGHT)); 


    ///initialize the writet object: 
    writer = VideoWriter(filename,fcc,fps,framesize); 

    if(!writer.isOpened()){ 

     cout << "Error opening the file" << endl; 
     getchar(); 
     return -1; 
    } 

    int counter = 0; 
    while (1) { 

     Mat frame,frame2,diff_frame; 


     ///read a new frame from camera feed and save it to the variable frame: 
     bool bSuccess = cap.read(frame); 



     if (!bSuccess) ///test if frame successfully read 
     { 
      cout << "ERROR READING FRAME FROM CAMERA FEED" << endl; 
      break; 
     } 

     /// now the last read frame is stored in the variable frame and here it is written to the file: 
     writer.write(frame); 

     if (counter > 0){ 

      cv::subtract(frame2,frame,diff_frame); 
      imshow(windowName, diff_frame); ///show the frame in "MyVideo" window 

     } 

     ///wait for 10ms for a key to be pressed 
     switch(waitKey(1)){ 

     ///the writing from webcam feed will go on until the user presses "esc": 
     case 27: 
      ///'esc' has been pressed (ASCII value for 'esc' is 27) 
      ///exit program. 
      return 0; 

     } 

    frame2 = frame; 
    counter++; 
    } 

    return 0; 

} 
+0

попробуйте использовать frame2 = frame.clone() при копировании кадра. Вы можете использовать 'frame2 = frame2 - frame' или' frame2 - = frame' вместо 'cv :: subtract (не нужно) – rhcpfan

+1

@rhcpfan еще лучше, используйте' cv: swap (frame, frame2); ' –

ответ

2

Каждый раз, когда вы выполняете время цикла frame2 создается и по умолчанию инициализируется. Когда вы звоните

cv::subtract(frame2,frame,diff_frame); 

Вы пытаетесь вычитать по умолчанию строится Mat из Mat, который имеет изображение в нем. Эти два Mat s не будут иметь одинаковый размер, чтобы вы получили ошибку.

Вам нужно переместить объявление frame и frame2 за пределы цикла while, если вы хотите, чтобы они сохраняли свои значения после каждого выполнения цикла while. Вам также необходимо инициализировать frame2 на тот же размер или сделать второй снимок, чтобы вы могли использовать subtract в первый раз.

2

Вам необходимо объявить frame2 за пределами рамки while, как вы делали с counter. Прямо сейчас вы получаете свежий пустой frame2 с каждой итерацией цикла.

Вы можете также перемещать все Mat за пределами цикла while, чтобы память не должна была быть выделена в конце каждой итерации и перераспределена следующая, хотя это не ошибка и в этом случае вы, скорее всего, не увидите штраф за производительность.

Кроме того, @rhcpfan является правильным в том, что вам нужно быть осторожным относительно мелкой и глубокой копии. Используйте cv::swap(frame, fram2).