В этом ответе указано, как скопировать строку матрицы в другую строку: Как скопировать строку мата в столбец другого мата в OpenCv? Однако, если я попытаюсь скопировать строку матрицы в вектор-столбец, программа внезапно завершится. Пример:

Mat A(640,480,CV_64F);
Mat B(480,1,CV_64F);
A.row(0).copyTo(B.col(0));

Возможный обходной путь:

Mat A(640,480,CV_64F);
Mat B;
A.row(0).copyTo(B);
B = B.t();

Но как я могу получить тип CV_64F в B, если A другого типа? Тип данных тоже копируется? И - самое главное - зачем мне это обходное решение?

3
GiCo 12 Май 2014 в 20:05

2 ответа

Лучший ответ

Функция copyTo () может копировать данные только между матрицами одного размера (ширины и высоты) и одного типа. По этой причине вы не можете использовать его напрямую для копирования строки матрицы в столбец матрицы. Обычно OpenCV перераспределяет целевую матрицу, чтобы ее размер и тип соответствовали исходному изображению, но вызов функции col () возвращает постоянный временный объект, который нельзя перераспределить. В результате ваша программа потерпела крах.

Собственно эту проблему можно решить. Вы можете копировать строку в столбец (если они имеют одинаковое количество элементов), и вы можете копировать данные между матрицами разных типов. Mat предоставляет итератор для своих данных, а это означает, что вы можете использовать все функции C ++, которые работают с итераторами. copy (), например.

Mat A(640, 480, CV_64F);
Mat B(480, 1, CV_32S); // note that the type don't have to be the same
Mat tmp = A.row(0); // no data is copied here. it is needed only because taking iterator to temporary object is really bad idea
copy(tmp.begin<double>(), tmp.end<double>(), B.begin<int>());
4
Michael Burdinov 13 Май 2014 в 10:05

Поскольку следующий код (только транспонирование строки) не поддерживается API:

A.row(0).t().copyTo( B.col(0) );

Обходной путь - либо создать временную матрицу из строки, транспонировать ее, а затем скопировать в целевую матрицу.

Mat temp = A.row(0);
temp = temp.t();
temp.copyTo( B.col(0) );

Я бы предпочел сделать что-то вроде этого:

Mat A( 640, 480,CV_64F );
Mat B( 1, 480, CV_64F );  /* rather than 480 x 1, make a 1 x 480 first */
A.row(0).copyTo( B.row(0) );
B = B.t(); /* transpose it afterwards */

Я предполагаю, что это все только потому, что API еще не поддерживает это.

4
sub_o 12 Май 2014 в 16:53