Преобразуйте строку байтов в cv :: mat

Мне нужно реализовать функцию, которая получает строку, содержащую байты изображения (полученную через соединение с ускоренным сокетом), и преобразует информацию в OpenCV cv :: Мат.

Я также знаю ширину и высоту изображения и его размер в байтах. Моя функция выглядит так:

void createImageFromBytes(const std::string& name, std::pair<int,int> dimensions, const std::string& data)
{
   int width,height;
   width = dimensions.first;
   height = dimensions.second;
   //convert data to cv::Mat image

   std::string filepng = DATA_PATH"/" + name +".png";
   imwrite(filepng, image);
}

Как лучше всего это сделать? Есть ли в OpenCV конструктор для Mat из строки?


person Mar de Romos    schedule 04.12.2012    source источник
comment
Есть обновления по этому поводу?   -  person Sleeba Paul    schedule 13.03.2019


Ответы (4)


OpenCV Mat имеет конструктор из vector<byte>, но это не так интуитивно понятно. Сначала вам нужно преобразовать из строки в вектор следующим образом:

std::vector<byte> vectordata(data.begin(),data.end());

Затем вы можете создать cv :: Mat из вектора:

cv::Mat data_mat(vectordata,true);

Вам также необходимо декодировать изображение (проверьте документацию, какие типы разрешены, png, jpg, в зависимости от версии OpenCV)

cv::Mat image(cv::imdecode(data_mat,1)); //put 0 if you want greyscale

Теперь вы можете проверить, совпадает ли полученный размер изображения с тем, который вы отправили:

cout<<"Height: " << image.rows <<" Width: "<<image.cols<<endl;
person Jav_Rock    schedule 04.12.2012

Здесь легко споткнуться, так как изображение может иметь нулевые символы, и любая строка обработки функции c будет видеть null как конец строки

Прочтите изображение

cv::Mat image;
    image = cv::imread("../test/image.png", CV_LOAD_IMAGE_COLOR);

Преобразовать в байты (это просто рабочий код, не проверенный на утечки)

int dataSize = image.total() * image.elemSize();
//convert to bytes
std::vector<char> vec(dataSize);
memcpy(&vec[0], reinterpret_cast<char *>(image.data), dataSize);
std::string test2(vec.begin(), vec.end());

Протестируйте и посмотрите, работает ли преобразование

//test
cv::Mat data_mat(height,width,CV_8UC3,const_cast<char*>(test2.c_str()));
imwrite("out2.png", data_mat);
person Alex Punnen    schedule 30.07.2018

Если данные в строке представляют собой необработанные пиксели (а не Jpeg / png и т. Д.), Вы можете напрямую создать cv :: mat

// assuming an RGB image in bytes              
cv::Mat mat(height,width,CV_8UC3,string.data());   
person Martin Beckett    schedule 04.12.2012
comment
Не придираться, но разве высота и ряды не одно и то же? - person trianta2; 17.01.2014
comment
Я получаю ошибки при компиляции и жалуюсь на отсутствие подходящего конструктора для этого использования cv :: Mat. Возможно, обновления opencv после вашего сообщения нарушили ваше решение? - person Mike Lawrence; 02.07.2014

Вот мое улучшенное решение Jav_Rock, проблема в том, что неясно использовать вектор (тип байта не определен в С ++, я этого не нашел), вместо этого используйте вектор, вот пример кода

int func(char * pfile){
string strfile = pfile;
std::vector<unsigned char> vectordata(strfile.begin(),strfile.end());
Mat data_mat(vectordata, true);
Mat graySacleFrame = imdecode(data_mat, 0); //PGM image
...
}
person Juan Pablo Rojas Cala    schedule 24.07.2016