Преобразование 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 широко, поэтому обратитесь к документации, чтобы проверить, все ли правильно.