Imran
Imran

Reputation: 875

converting data from matrix to array from opencv matrix frame

I want to extract the data from a frame of opencv matrix in 420 video format. 420 Format means read the first channel as it is i.e. full first channel. For the second and third channel in frame read in such a way that read alternate rows and columns i.e. for the second channel we will read pixel (0,0) then (0,2) then (0,4) ....... (2,0) then (2,2) and so on ...

I have written the code but I am getting reading and writing violation are random. I am not able to figure out why

array size is rows x cols x 1.5 ...... 1.5 because for the second and third channel size is reduced to quarter.

Code is

    VideoCapture cap(readFile);
    if (!cap.isOpened()) {
            
            cout << "Error opening video stream or file" << endl;
            
            return -1;
            
    }
    
    int arraySize = 640 * 824 * 1.5;
    uchar * arr = new uchar(arraySize);
    int frame_width = cap.get(CAP_PROP_FRAME_WIDTH);
    int frame_height = cap.get(CAP_PROP_FRAME_HEIGHT);
    int fps = cap.get(CAP_PROP_FPS);
    Size S = Size(frame_width, frame_height); // Declare Size structure
    int fourcc = VideoWriter::fourcc('H', '2', '6', '5');
    //int fourcc = VideoWriter::fourcc(*"hvc1");
    outputVideo.open(saveFile, fourcc, fps, S);
    while (1)
    {
        Mat framergb;
        Mat frame = framergb.clone();
        cap >> framergb;

        
        cvtColor(framergb, frame, 83);
        std::cout << "Channels = " << frame.channels() << endl;



        std::vector<uchar> array(framergb.rows*framergb.cols*framergb.channels());

        
        if (type == "420")
        {
            Mat rgbchannel[3];
            cv::split(frame, rgbchannel);
            //arr = new uchar(int(frame.rows*frame.cols*1.5));
//          int size = *(&arr + 1) - arr;
            cout << "Array Size = " << sizeof(arr);// << " and " << size << endl;
            int arrInd = 0;
            uchar chr = 0;
            for (int ch = 0; ch < 3; ch++)
            {
                if (ch == 0)
                {
                    for (int r = 0; r < frame.rows; r++)
                    {
                        for (int c = 0; c < frame.cols; c++)
                        {
                            chr  = rgbchannel[ch].at<uchar>(r, c);
                            arr[arrInd++] = chr;
                            cout << "cg = " << ch << ", r = " << r << ", c= " << c <<"ch = " << chr<< endl;
                            //if (c == 638)
                                //cout << "Stop";
                        }
                        //cout << "cg = " << ch << ", r = " << r <<endl;
                    }
                    cout << "cg = " << ch << endl;
                }                       
                else
                {
                    for (int r = 0; r < frame.rows; r+=2)
                    {
                        for (int c = 0; r < frame.cols; c+=2)
                        {
                            arr[arrInd++] = rgbchannel[ch].at<uchar>(r, c);
                        }
                    }
                }
            }
        }
    }

Upvotes: 0

Views: 165

Answers (1)

rafix07
rafix07

Reputation: 20918

Crash is caused by reading out of bounds

arr[arrInd++] = chr;

because by the line

uchar * arr = new uchar(arraySize);

you allocate only one byte. It should be: uchar * arr = new uchar[arraySize]; - the way of creating dynamic array.

Upvotes: 1

Related Questions