Сохраните cv :: Mat в байтовом массиве для передачи данных на сервер

Мне нужно прочитать изображение с помощью OpenCV, получить его размер и отправить его на сервер, чтобы оно обработало изображение и вернуло мне извлеченные функции.

Я думал об использовании vector<byte>, но я не понимаю, как скопировать данные в cv :: Mat. Я не хочу, чтобы это было быстро, поэтому я пытаюсь получить доступ к данным с указателем, но у меня есть исключение во время выполнения. У меня есть что-то вроде этого.

Mat image = imread((path + "name.jpg"), 0);
vector<byte> v_char;
for(int i = 0; i < image.rows; i++)
{
for(int j = 0; j < image.cols; j++)
{
v_char.push_back(*(uchar*)(image.data+ i + j));

}
}
  • Какой подход лучше всего подходит для этой задачи?

7

Решение

Прямой доступ — хорошая идея, так как он самый быстрый для OpenCV, но вам не хватает шаг и это, вероятно, причина, почему ваша программа ломается. Следующая строка неверна:

v_char.push_back(*(uchar*)(image.data+ i + j));

Вам не нужно увеличивать я, Вы должны увеличить я + image.step. Это будет так:

Mat image = imread((path + "name.jpg"), 0);
vector<byte> v_char;
for(int i = 0; i < image.rows; i++)
{
for(int j = 0; j < image.cols; j++)
{
v_char.push_back(*(uchar*)(image.data+ i*image.step + j));

}
}
8

Другие решения

Улучшение ответа Jav_Rock, вот как я это сделаю.

Mat image = ...;
vector<byte> v_char(image.rows * image.cols);

for (int i = 0; i < image.rows; i++)
memcpy(&v_char[i * image.cols], image.data + i * image.step, image.cols);

РЕДАКТИРОВАТЬ: Инициализация с помощью конструктора выделит достаточно места, чтобы избежать дополнительного перераспределения, но он также установит все элементы в векторе на значение по умолчанию (0). Следующий код избегает этой дополнительной инициализации.

Mat image = ...;
vector<byte> v_char;
v_char.reserve(image.rows * image.cols);

for (int i = 0; i < image.rows; i++)
{
int segment_start = image.data + i * image.step;
v_char.insert(v_char.end(), segment_start, segment_start + image.cols);
}
6

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

Итак, взгляните на cv::imencode() о том, как сжать его, и cv::imdecode() преобразовать его обратно в матрицу OpenCV на сервере. просто вставьте выход imencode в розетку, и все готово.

5

Я не совсем понимаю, почему вам нужно использовать вектор, но если это действительно необходимо, я рекомендую вам сделать простой memcpy:

vector<byte> v_char(image.width * image.height); //Allocating the vector with the same size of the matrix
memcpy(v_char.data(), image.data, v_char.size() * sizeof(byte));
1