Вопросы OpenCV - сжать IplImage в jpeg без промежуточного сохранения в файл



как преобразовать 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;
}
  • +1
  • 8 декабря 2010, 10:23
  • noonv

Комментарии (5)

RSS свернуть / развернуть
+
0
А не подскажите, как извлечь сырые данные из 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;

Но в ней куча указателей, и непонятно какой нужен.
avatar

_KoT_

  • 17 февраля 2011, 08:51
+
0
Странное место для выбора вопроса :) Логичнее было бы задать его в теме про матрицу — там не только приведён данный код, но и показано как работать с элементами матрицы в том числе с прямым доступом к элементам.
avatar

noonv

  • 17 февраля 2011, 09:24
+
0
Спасибо. Просто я искал, как сжать изображение и попал сюда. А там вроде есть то, что нужно.) Пойду попробую.
avatar

_KoT_

  • 17 февраля 2011, 10:25
комментарий был удален

+
0
Очень неплохой вопрос и пример кода.
Только как быть если надо прочитать/загрузить картинку
не из файла, а из памяти?
По идее над воспользоваться функцией cvDecodeImage.
Только перед этим надо создать cvMat и проинициализировать
его указателем на блок памяти, где находится картинка.
Проблема в том, что функция cvInitMatHeader требует в качестве
параметров int rows, int cols, которые неизвестны заранее, а так же
параметр type – Type of the matrix elements — не может быть определен заранее,
т.к. неизвестно, что за картинка будет загружаться.
Может быть существует пример работающего кода, демонстрирующий,
как загрузить картинку из памяти с помощью функций библиотеки OpenCV?
Ведь из файлов картинки загружаются прекрасно функцией cvLoadImage.
avatar

mail20071129

  • 16 августа 2011, 22:16

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.