【问题标题】:converting data from matrix to array from opencv matrix frame从opencv矩阵框架将数据从矩阵转换为数组
【发布时间】:2021-02-09 09:53:35
【问题描述】:

我想从 420 视频格式的 opencv 矩阵帧中提取数据。 420 格式意味着读取第一个通道,即完整的第一个通道。对于帧中的第二个和第三个通道,以读取交替行和列的方式读取,即对于第二个通道,我们将读取像素 (0,0) 然后 (0,2) 然后 (0,4) ..... .. (2,0) 然后 (2,2) 等等 ...

我已经编写了代码,但我发现读写违规是随机的。我不知道为什么

数组大小为 rows x cols x 1.5 ...... 1.5,因为第二个和第三个通道的大小减少到四分之一。

代码是

    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);
                        }
                    }
                }
            }
        }
    }

【问题讨论】:

  • 你在这里有一个错字int c = 0; r &lt; frame.cols; c+=2。此外,您应该将ch 转换为 int,或者如果您想查看范围 (0,255) 内的整数值而不是由该 ASCII 代码编码的字符,则应转换为 short。
  • 是的,这是错字,但它不会进入第二个频道。它在随机位置的第一个通道中给出读取冲突错误
  • 这个uchar * arr = new uchar(arraySize);分配了一个字节,你要创建数组,所以应该是:uchar * arr = new uchar[arraySize];,现在你在这里读到了arr[arrInd++] = chr;的边界。
  • @rafix07 非常感谢。这是我的愚蠢错误。请将此写为答案,以便我可以接受答案并对其进行投票。

标签: c++ arrays image opencv matrix


【解决方案1】:

读取越界导致崩溃

arr[arrInd++] = chr;

因为线

uchar * arr = new uchar(arraySize);

你只分配一个字节。应该是:uchar * arr = new uchar[arraySize];——动态数组的创建方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多