как преобразовать OpenCV-ую IplImage в изображение jpeg без промежуточного сохранения в файл с помощью cvSaveImage() ?
Есть две недокументированные функции в модуле highgui:
cvEncodeImage() и cvDecodeImage():
/* decode image stored in the buffer */ CVAPI(IplImage*) cvDecodeImage( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); CVAPI(CvMat*) cvDecodeImageM( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR));
— декодирует картинку из буфера
buf — буфер, содержащий закодированую/сжатую картинку
iscolor — флаг, определяющий картинка цветная или нет.
/* encode image and store the result as a byte vector (single-row 8uC1 matrix) */
CVAPI(CvMat*) cvEncodeImage( const char* ext, const CvArr* image,
const int* params CV_DEFAULT(0) );
— кодирует изображение и помещает результат в вектор байт (одноканальный массив типа 8uC1)
ext — строчка с расширением для кодирования/сжатия
image — указатель на изображения для сжатия
пример:
CvMat* mat = cvEncodeImage(".jpg", image);
//
// пример использования cvEncodeImage() и cvDecodeImage()
//
// robocraft.ru
//
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
IplImage *image=0, *dst=0;
// имя картинки задаётся первым параметром
char* filename = argc >= 2 ? argv[1] : "Image0.jpg";
// получаем картинку
image = cvLoadImage(filename, 1);
printf("[i] image: %s\n", filename);
assert( image != 0 );
// покажем изображение
cvNamedWindow( "original", 1 );
cvShowImage( "original", image );
// картинка для хранения изображения
//dst = cvCreateImage(cvGetSize(image), image->depth, image->nChannels);
// кодируем картинку и сохраняем результат в массив
CvMat* mat = cvEncodeImage(".jpg", image);
// декодируем массив в картинку
dst = cvDecodeImage(mat, 1);
// освобождаем массив
cvReleaseMat(&mat);
// покажем картинку
cvNamedWindow( "dst", 1 );
cvShowImage( "dst", dst );
// ждём нажатия клавиши
cvWaitKey(0);
// освобождаем ресурсы
cvReleaseImage(& image);
cvReleaseImage(&dst);
// удаляем окна
cvDestroyAllWindows();
return 0;
}


5 комментариев на «“Вопросы OpenCV — сжать IplImage в jpeg без промежуточного сохранения в файл”»
Здраствуйте, у меня вопрос. Как построить градиент изображения? А если конкретнее, то я понял что надо сделать 2 операции свертки, после которых у нас получится 2 матрицы. Каким образом из них получить необходимую матрицу?
Очень неплохой вопрос и пример кода.
Только как быть если надо прочитать/загрузить картинку
не из файла, а из памяти?
По идее над воспользоваться функцией cvDecodeImage.
Только перед этим надо создать cvMat и проинициализировать
его указателем на блок памяти, где находится картинка.
Проблема в том, что функция cvInitMatHeader требует в качестве
параметров int rows, int cols, которые неизвестны заранее, а так же
параметр type – Type of the matrix elements — не может быть определен заранее,
т.к. неизвестно, что за картинка будет загружаться.
Может быть существует пример работающего кода, демонстрирующий,
как загрузить картинку из памяти с помощью функций библиотеки OpenCV?
Ведь из файлов картинки загружаются прекрасно функцией cvLoadImage.
А не подскажите, как извлечь сырые данные из CvMat? Описание этой структуры я нашёл:
typedef struct CvMat { int type; int step; /* for internal use only */ int* refcount; int hdr_refcount; union { uchar* ptr; short* s; int* i; float* fl; double* db; } data; #ifdef __cplusplus union { int rows; int height; }; union { int cols; int width; }; #else int rows; int cols; #endif } CvMat;Но в ней куча указателей, и непонятно какой нужен.
Странное место для выбора вопроса 🙂 Логичнее было бы задать его в теме — там не только приведён данный код, но и показано как работать с элементами матрицы в том числе с прямым доступом к элементам.
Спасибо. Просто я искал, как сжать изображение и попал сюда. А там вроде есть то, что нужно.) Пойду попробую.