Преобразовать вектор в OpenCV Matd1d на c

#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:

Я не уверен, что я вполне понимаю, что вам нужно. Здесь вы делаете две вещи,

  1. работа с преобразованием типов между целочисленными и типами с плавающей запятой
  2. изменение формы массивов между вектором строк и столбцов

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. Я изменю ответ.