Как создать 4D-матрицу из вектора матриц в OpenCV С++

Предположим, что я собираю изображения/матрицы одинакового размера, глубины и канала в файл vector. Итак, этих изображений r*c*d каждое, и у меня есть m из них в моем векторе следующим образом.

vector<string> imgs; --> there are m image paths in these, all are r*c*d resolution
vector<Mat> vec;
for (auto img: imgs ){
    vec.push_back(cv::imread(img, COLOR_BGR)); //or gray. doesn't really matter
}

Теперь я хочу создать 4D-матрицу. Например, в python np.array(vec) дал бы мне это (при условии, что vec - это список). Я хотел бы то же самое в OpenCV С++, но я не мог найти для этого решения.

Я не хочу создавать 4D-матрицу с Mat m(dims, size, type);, затем перебирать все пиксели и копировать значение, так как это очень неэффективно. Я хотел бы иметь метод, который будет просто рассматривать vec<Mat> как 4D Mat, чтобы он был очень быстрым. Обратите внимание, что у меня может быть 100 изображений с полным разрешением.

Я использую Opencv4.2 и С++ на Mac.

заранее спасибо


person smttsp    schedule 20.03.2020    source источник


Ответы (1)


Сегодня после многих часов я случайно нашел ответ на свой вопрос. Я оставлю ответ здесь, чтобы иметь ссылку для тех, кто борется с документацией OpenCV, чтобы найти правильный ответ.

vector<int> dims = {m, r, c}; //dimensions
cv::Mat m (3, &dims[0], imgs[0].type(), &imgs[0]);

Это создает 4D-матрицу из вектора imgs, где тип является одним из CV_8UC1, CV_8UC3 или CV_8UC4 в зависимости от количества каналов. Хорошо, что он не копирует вектор.

Хотя это не является частью вопроса, чтобы получить доступ к пикселю в матрице 4D, вы можете сделать следующее:

int x = v1, i = v2, j = v3, c = v4; //v1-4 are some random values within their ranges
cout << (int)m.at<Mat>(x).at<Vec3b>(i,j)[c] << " " 
     << (int)imgs[x].at<Vec3b> (i,j)[c] << endl;

Оба будут печатать c-й канал i,j-го индекса x-го изображения.

person smttsp    schedule 20.03.2020