Преобразование std::string обратно в cv::Mat, который был сгенерирован с помощью std::stringstream << cv::Mat

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

Из-за этого я использую небольшой хак для преобразования cv:: Mat в std:: string:

cv::Mat mat;
// some code
std::stringstream sstrMat;
sstrMat << mat;
saveFoo(sstrMat.str()); // something like this to save the matrix

в качестве выхода я делаю из sstrMat.str() все данные которые мне нужны:

[2316.74172937253, 0, 418.0432610206069;
  0, 2316.74172937253, 253.5597342849773;
  0, 0, 1]

Моя проблема заключается в обратной операции: преобразование этой std:: string обратно в cv:: Mat.

Я пробовал такой код:

cv::Mat mat;
std::stringstream sstrStr;
sstrStr << getFoo() // something like this to get the saved matrix

sstrStr >> mat;  // idea-1: generate compile error
mat << sstrStr;  // idea-2: does also generate compile error

все мои попытки не увенчались успехом, поэтому я спросил бы вас, знаете ли вы метод opencv для преобразования этой строки обратно или я пишу свой собственный метод для этого.

1 ответ

Вы реализовали operator<<(std::ostream&, const Mat&) сам? Если это так, то вам, очевидно, придется самостоятельно выполнять обратную операцию, если вы этого хотите.

Из вашего вывода, я думаю, тип матрицы был CV_64F с 3 каналами. Обязательно запомните размер вашей матрицы и ознакомьтесь с документацией.

Вы можете создать свою матрицу с этими спецификациями и заполнить ее значениями во время чтения вашего потока. Есть несколько примеров потокового чтения в Интернете, но в вашем случае это довольно просто. Игнорировать символы, которые вам не нужны ([ ] , ;) с std::istream::read в фиктивный буфер, и используйте operator>>(std::istream&, double) чтобы вернуть ваши ценности.

Что здорово в этом то, что вы можете перебирать cv::MatЭто как в стандартном контейнере библиотеки. Так что если вы используете C++11, это может выглядеть так (не проверено):

int size[2] = {x, y}; // matrix cols and rows
cv::Mat mat(3, size, CV_F64); // 3-dimensional matrix

for(auto& elem : mat)
{
    cv::Vec3d new_elem; // a 3D vector with double values
    // read your 3 doubles into new_elem
    // ...

    elem = new_elem; // assign the new value to the matrix element
}

Опять же, я не использовал OpenCV широко, поэтому обратитесь к документации, чтобы проверить, все ли правильно.

Другие вопросы по тегам