Ask Your Question
0

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

asked 2017-03-02 15:03:57 -0600

reaper gravatar image

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;
}
edit retag flag offensive close merge delete

Comments

Do you want to split image like in this post? Your code is similar to @Theodore's code

LBerger gravatar imageLBerger ( 2017-03-02 15:08:54 -0600 )edit

@LBerger I have already broken the image into the parts as you have shown in your code and the broken parts have been saved in the vector frames. Now i want to take out those broken parts from the vector and rejoin them.

reaper gravatar imagereaper ( 2017-03-02 15:25:10 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2017-03-02 15:36:28 -0600

LBerger gravatar image

updated 2017-03-03 01:41:56 -0600

May be something like this for you puzzle (it is not really image processing but it is funny):

        Mat paste(frame_height, frame_width,CV_8UC3);
        Rect r(0,0,0,0);
        vector<int> pos(100);
        for (int i=0;i<100;i++)
            pos[i]=i;
        RNG rg;
        for (int i = 0; i < 1000; i++)
        {
            int k=rg.uniform(0,100);
            swap(pos[0],pos[k]);
        }
        for (int i = 0,k=0; i < 10; i++)
        {
            for (int j = 0; j < 10; j++,k++)
            {
                r.width = divided[i].cols;
                r.height = divided[i].rows;
                divided[pos[k]].copyTo(paste(r));
                r.y+= r.height;
            }
            r.y=0;
            r.x+= r.width;
        }
edit flag offensive delete link more

Comments

@LBerger it works perfectly fine and thanks a lot just one thing more can you please tweak this code so that the pics are attached together in a total random manner. The code runs perfectly.

reaper gravatar imagereaper ( 2017-03-02 16:00:39 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-03-02 15:03:57 -0600

Seen: 447 times

Last updated: Mar 03 '17