Peyman Kheiri
Peyman Kheiri

Reputation: 427

Why does the function cv::subtract() returns the error "size of input arguments do not match"?

I want to subtract the two successive images taken from the webcam. as you can see I am doing this inside a while loop. In the last line of the while loop I am setting frame2 = frame and so I can subtract them from the next iteration. But the function cv::subtract returns the above error in the terminal.

what am I doing wrong?

#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;

}

Upvotes: 1

Views: 391

Answers (2)

Nicu Stiurca
Nicu Stiurca

Reputation: 8707

You need to declare frame2 outside the scope of the while loop like you did with counter. Right now, you get a fresh, empty frame2 with each iteration of the loop.

You might as well move all the Mats outside the while loop so that memory doesn't have to be de-allocated at the end of each iteration and re-allocated the next, although this isn't an error and you likely won't see the performance penalty in this case.

Also, @rhcpfan is right in that you need to be careful about shallow vs deep copies. Use cv::swap(frame, fram2).

Upvotes: 2

NathanOliver
NathanOliver

Reputation: 181068

Every time you execute the while loop frame2 is created and default initialized. When you call

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

You are trying to subtract a default constructed Mat from a Mat that has an image in it. These two Mats will not be the same size so you get the error.

You need to move the declaration of frame and frame2 outside of the while loop if you want them to retain their values after each execution of the while loop. You also need to initialize frame2 to the same size or capture a second image into it so you can use subtract the first time through.

Upvotes: 2

Related Questions