#c #opencv #matrix #vector
#c #opencv #матрица #вектор
Вопрос:
У меня есть переменная M
, которая является cv::Mat1d
матрицей. Это сделано следующим образом:
cv::Mat1d<double> M;
Он заполнен множеством значений в каком-то другом коде, который, вероятно, не нужен, и он выглядит так, когда я его печатаю:
[-0.9344576352096885;
-0.9344576352096885;
-0.5766199600499906;
0.2846686026510846;
0.9589011777015718;
0.9285453673591227;
0.3137239980297359;
-0.2302718892981206;
-0.2921750731112262;
-0.2206633656711884;
-0.2175072323850435;
-0.1725991485554647;
-0.2140556050785325;
-0.4148403958730175;
-0.4036417215304363;
-0.06016889338878993;
0.3028103268622913;
0.4454375499811856;
0.3803583582813156;
0.3188387192279333;
0.3914868895364941;
0.4488724871465618;
0.2694705005556897;
-0.05248136866304744;
-0.2971598882254832;
-0.3545797186279719;
-0.2294426230118397;
-0.1673776410980104;
-0.2768386357175945;
-0.3276029287776189;
-0.2361695287135101;
-0.06139424097086685;
0.1621769468562924;
0.3275221571852822;
0.3153071221383847;
0.1341365194415481;
-0.04596232030582767;
-0.08961855126383761;
-0.02999823421387905;
-0.03225119207066054]
Это размер [1 x 40]
.
Мне пришлось преобразовать M
в вектор X
, чтобы выполнить некоторые вычисления над ним. Я преобразовал его следующим образом:
vector<ld> X;
X.push_back(M.at<double>(0, 0));
for (int i = 1; i < M.rows; i ) {
X.push_back(M.at<double>(i, 0));
}
Теперь, когда я печатаю его (после выполненных мной вычислений, которые не имеют значения), это выглядит так:
[0 0 0 0 0 -1 -1 0 1 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 1 0 0]
и является размером 40
.
Как мне преобразовать X
обратно в [1×40] cv::Mat1d
, чтобы он был того же типа, M
что и ?
Примечание: Если мой вопрос / синтаксис / что-то еще ужасает, мои извинения. Я только сейчас оставляю относительную безопасность python для c …
Редактировать
Я думаю, что я решил это. На случай, если кому-то интересно или если мое решение нуждается в исправлении, вот оно:
Mat1d test;
for (int i = 0; i < X.size(); i ) {
double new_val = (double) X[i];
test.push_back(new_val);
}
Ответ №1:
Я не уверен, что я вполне понимаю, что вам нужно. Здесь вы делаете две вещи,
- работа с преобразованием типов между целочисленными и типами с плавающей запятой
- изменение формы массивов между вектором строк и столбцов
cv::Mat::reshape
немного отличается от numpy reshape, но делает то же самое. у вас может быть два мата, совместно использующих одни и те же данные, и вы используете один для представления строк, а другой для представления столбцов.
cv::Mat m1_column, m2_row;
m2_row = m1_column.reshape(0, 1);
// first arg: number of channels. 0 means same.
// second arg: number of rows. make it a row vector.
cv::Mat::convertTo
примерно эквивалентно numpy ndarray.astype
. он копирует значения, преобразованные в нужный тип, в другой cv::Mat
.
cv::Mat m1_floats, m2_ints, m3_floats;
m1_floats.convertTo(m2_ints, CV_8U);
m2_ints.convertTo(m3_floats, CV_32F);
объедините оба по мере необходимости.
вам даже не нужно переходить от формата столбца к формату строки. просто используйте один индекс в Mat::at<>()
. он будет проходить через матрицу, как если бы она была сплющена.
вы можете создать a Mat
из a std::vector
, чтобы он разделял память вектора:
std::vector<int> X; // contains values from somewhere, ints should be 32 bit
cv::Mat X_as_a_Mat(1, X.size(), CV_32S, X.data()); // a single-row Mat sharing the std::vector's data
cv::Mat X_as_doubles;
X_as_a_Mat.convertTo(X_as_doubles, CV_64F); // converts data type
этот код предполагает, что int
это 32-разрядный подписанный тип ( CV_32S
). Я не знаю, какой тип элемента у вас vector<ld>
должен быть.
Комментарии:
1. Большое спасибо. Немного запутался.
m1_column
Предполагается, что он должен быть моимM
иm2_row
должен быть моимX
?2. Кроме того, я не понимаю, где
X
здесь вступает в игру мой. Похоже, что ваше предложение касается только типов cv::Mat, а не векторов. Возможно, я неправильно понимаю…3. ах, я вижу, вам нужно разобраться с std::vector. Я изменю ответ.