Мне нужно прочитать изображение с помощью 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));
}
}
Прямой доступ — хорошая идея, так как он самый быстрый для 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));
}
}
Улучшение ответа 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);
}
Пока вы получили отличные ответы, но это не ваша главная проблема. Что вы, вероятно, хотите сделать до отправка изображения на сервер компресс Это.
Итак, взгляните на cv::imencode()
о том, как сжать его, и cv::imdecode()
преобразовать его обратно в матрицу OpenCV на сервере. просто вставьте выход imencode в розетку, и все готово.
Я не совсем понимаю, почему вам нужно использовать вектор, но если это действительно необходимо, я рекомендую вам сделать простой 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));