#c #arrays #image #opencv #matrix
#c #массивы #изображение #opencv #матрица
Вопрос:
Я хочу извлечь данные из кадра матрицы opencv в формате видео 420. Формат 420 означает чтение первого канала таким, какой он есть, т.Е. Полный первый канал. Для второго и третьего канала в кадре считывается таким образом, чтобы считывать альтернативные строки и столбцы, т.Е. Для второго канала мы будем считывать пиксель (0,0), затем (0,2), затем (0,4) ……. (2,0) затем (2,2) и так далее…
Я написал код, но я получаю случайные нарушения чтения и записи. Я не могу понять, почему
размер массива равен строкам 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 = *(amp;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);
}
}
}
}
}
}
Комментарии:
1. Здесь у вас опечатка
int c = 0; r < frame.cols; c =2
. Кроме того, вы должны преобразоватьch
в int или short, если хотите увидеть целочисленное значение в диапазоне (0,255) вместо символов, закодированных этим ASCII-кодом.2. Да, это была опечатка, но она не передается по второму каналу. Это выдает ошибку нарушения чтения в первом канале в случайном месте
3. Это
uchar * arr = new uchar(arraySize);
выделяет один байт, вы хотите создать массив, поэтому он должен быть:uchar * arr = new uchar[arraySize];
, теперь вы читаете здесь out of boundsarr[arrInd ] = chr;
.4. @rafix07 Большое спасибо. Это была моя глупая ошибка. Пожалуйста, напишите это как ответ, чтобы я мог принять ответ, а также проголосовать за него.
Ответ №1:
Сбой вызван чтением за пределы
arr[arrInd ] = chr;
потому что по строке
uchar * arr = new uchar(arraySize);
вы выделяете только один байт. Это должно быть: uchar * arr = new uchar[arraySize];
— способ создания динамического массива.