Ask Your Question

Revision history [back]

How to make one image from a vector containing multiple images as a Mat object

My program takes a video from webcam and then splits it into frames and then stores those frames in a vector.

Now I want to split each frame in that vector into 100 equal pieces.

Then those small frames (or sub frames) are again stored in another vector of Mat objects. I have managed to do all that.

Now what I further want to do is to convert that vector of sub frames into a single image of 10x10 sub frames. Can someone please tell me how i can do that using a function that takes my vector as an argument and then pops the images from it and convert them into one single image. Following is my code which i am using to do so:

    #include "opencv2/opencv.hpp"
    #include <iostream>
    #include <vector>
    using namespace std;
    using namespace cv;

    int subdivide(const Mat &img, const int rowDivisor, const int colDivisor, vector<Mat> &blocks)
    {
        /* Checking if the image was passed correctly */
        if (!img.data || img.empty())
            cerr << "Problem Loading Image" << endl;
        /* Cloning the image to another for visualization later, if you do not want to visualize the result just comment every line related to visualization */
        cv::Mat maskImg = img.clone();
        /* Checking if the clone image was cloned correctly */
        if (!maskImg.data || maskImg.empty())
            std::cerr << "Problem Loading Image" << std::endl;
        // check if divisors fit to image dimensions
        if (img.cols % colDivisor == 0 && img.rows % rowDivisor == 0)
        {
            for (int y = 0; y < img.cols; y += img.cols / colDivisor)
            {
                for (int x = 0; x < img.rows; x += img.rows / rowDivisor)
                {
                    blocks.push_back(img(cv::Rect(y, x, (img.cols / colDivisor), (img.rows / rowDivisor))).clone());
                    rectangle(maskImg, Point(y, x), Point(y + (maskImg.cols / colDivisor) - 1, x + (maskImg.rows / rowDivisor) - 1), CV_RGB(255, 0, 0), 1); // visualization
                    imshow("Image", maskImg); // visualization
                    waitKey(0); // visualization
                }
            }
        }
        else if (img.cols % colDivisor != 0)
        {
            cerr << "Error: Please use another divisor for the column split." << endl;
            exit(1);
        }
        else if (img.rows % rowDivisor != 0)
        {
            cerr << "Error: Please use another divisor for the row split." << endl;
            exit(1);
        }
        return EXIT_SUCCESS;
    }

    int main() {
        vector<Mat> frames;//for all saperated frames
        vector <Mat> divided;//for small boxes of a single frame;
        VideoCapture vcap(0);
        //vcap.set(CAP_PROP_SETTINGS, 1);
        if (!vcap.isOpened()) {
            cout << "Error opening video stream or file" << endl;
            return -1;
        }
        int frame_width = vcap.get(CV_CAP_PROP_FRAME_WIDTH);
        int frame_height = vcap.get(CV_CAP_PROP_FRAME_HEIGHT);
        VideoWriter video("out.avi", CV_FOURCC('M', 'J', 'P', 'G'), 20, Size(frame_width, frame_height), true);
        for (;;) {
            Mat frame;
            vcap >> frame;
            frames.push_back(frame);
            video.write(frame);
            imshow("Frame", frame);
            char c = (char)waitKey(33);
            if (c == 27) break;
        }
        subdivide(frames[0], 10, 10, divided);

        return 0;
}