Перейти к содержимому
Compvision.ru
mrgloom

из RAW data в IPlImage*

Recommended Posts

какие поля необходимо\заполнить инициализировать в структуре IPlImage* для нормальной работы?

т.е. достаточно ли сделать так

IplImage* img=cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,3); 

а потом заполнить структуру imageData из масссива своих значений?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, достаточно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

хмм, а если в функцию передать уже заполненное IplImage* почему то не пашет

IplImage* Fun(IplImage* img)

{

	/* retrieve properties */

	int width     = img->width;

	int height    = img->height;

	int nchannels = img->nChannels;

	int step      = img->widthStep;


	for( int y=0; y<img->height; y++ )

	{

		uchar* ptr = (uchar*) (img->imageData + y * img->widthStep);

		for( int x=0; x<img->width; x++ )

		{

			//BGR

			ptr[nchannels*x+0] = 255; 

			ptr[nchannels*x+1] = 0; 

			ptr[nchannels*x+2] = 0;

		}

	}

	return img;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

можно сделать просто:

memcpy(cv_image->imageData, raw_buf, raw_buf_size);
или же чуть сложнее:
// помещаем данные в матрицу

CvMat image_mat =  cvMat(raw_height, raw_width, CV_8UC3, raw_buf);

IplImage cv_image;

// преобразуем матрицу в изображение

cvGetImage(&image_mat, &cv_image);

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

в Fun() была ошибка, не проверялось количество каналов, т.е. для 3-х она работала, а для 1-го нет.

вообщем задача стоит так у меня есть структура

struct RGBPIX

{

    BYTE blue;

    BYTE green;

    BYTE red;

    BYTE reserved;

}
мне надо IplImagetoRGBPIX и RGBPIXtoIplImage одну я написал но не знаю, безопастна ли она и как по производительности, может можно быстрее?
IplImage* RGBPIXtoIplImage(RGBPIX* pd, int width, int height)

{

        IplImage* img= cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,3);

        int nchannels= img->nChannels;

	if(nchannels==3)

	{

		for( int y=0; y <height ; ++y ) 

		{           

			uchar* ptr = (uchar*) (img->imageData + y * img->widthStep);

			for( int x=0; x <width; ++x ) 

			{  

				 ptr[nchannels*x+0]= pd[x].blue;

				 ptr[nchannels*x+1]= pd[x].green;

				 ptr[nchannels*x+2]= pd[x].red;

			}

			pd += width;

		}

	}

	return img;

}
обратная чо то не работает
RGBPIXEL* IplImagetoRGBPIXEL(IplImage* img)

{

        int nchannels= img->nChannels;

	RGBPIX* pd= (RGBPIX*)img->imageData; //в этом преобразовании сомневаюсь

	//RGBPIX* pd= new RGBPIX; //может так,выделить новую память?

	RGBPIXEL* ps=pd;

	int width= img->width;

	int height= img->height;

	if(nchannels==3)

	{

		for( int y=0; y <height ; ++y ) 

		{           

			uchar* ptr = (uchar*) (img->imageData + y * img->widthStep);

			for( int x=0; x <width; ++x ) 

			{  

				 pd[x].blue= ptr[nchannels*x+0];

				 pd[x].green= ptr[nchannels*x+1];

				 pd[x].red= ptr[nchannels*x+2];

				 pd[x].reserved= 0;

			}

			pd += width;

		}

	}

        return ps;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
можно сделать просто:

memcpy(cv_image->imageData, raw_buf, raw_buf_size);

я так понимаю это будет работать только если у нас порядок того как уложены данные совпадает.

или же чуть сложнее:

// помещаем данные в матрицу

CvMat image_mat = cvMat(raw_height, raw_width, CV_8UC3, raw_buf);

IplImage cv_image;

// преобразуем матрицу в изображение

cvGetImage(&image_mat, &cv_image);

cvMat(raw_height, raw_width, CV_8UC3, raw_buf); cvMat тут как конструктор? и матрица типа raw_buf?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
я так понимаю это будет работать только если у нас порядок того как уложены данные совпадает.

разумеется :)

cvMat(raw_height, raw_width, CV_8UC3, raw_buf); cvMat тут как конструктор? и матрица типа raw_buf?

да. raw_buf - это массив ваших данных (из примера про memcpy()) (опять-таки в правильной укладке)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

так не очень понятно как использовать memcopy, когда структуры не одинаковые.

получается что одна BGR, а вторая BGR+reserved

т.е. BGR->BGR то можно скопировать, но потом как то надо сместится на один BYTE, а в случае IplImage to RGBPIX надо reserved заполнить нулями.

+ еще вопрос если например я имею функцию

pointer* fun()

{

  new struct_array; //псевдокод массив всех значений RGBPIX

  pointer=struct_array; //ставим указатель на массив

  return pointer;

}

почему то если возвращать указатель не работает, а если возвращать массив то все ок.

(почему нельзя возвращать просто указатель? т.е. выделенная память под struct_array может очищается при выходе из функции?)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если размер картинки без остатка делится на 8 (width%8==0 && height%8==0), то width будет равен widthStep и reserved не будет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Если размер картинки без остатка делится на 8 (width%8==0 && height%8==0), то width будет равен widthStep и reserved не будет.

не понял о чем вы. reserved всегда присутствует в структуре RGBPIX, которая кстати совпадает с RGBQUAD виндовой.

typedef struct tagRGBQUAD {

  BYTE rgbBlue;

  BYTE rgbGreen;

  BYTE rgbRed;

  BYTE rgbReserved;

} RGBQUAD;

rgbReserved

This member is reserved and must be zero.

не очень правда понял для каких целей, может используется как альфа канал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вот тут

http://www.compvision.ru/forum/index.php?showtopic=495&st=0

копирование данных в Bitmap c 24 битным цветом. Никаких проблем с выводом картинки.

Единственный нюанс, это выравнивание данных об этом и писал выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

HBITMAP to IplImage* и обратно я и так нашел в интернете.

но это не совсем то же самое, что я спрашивал,

/* Копируем данные */

        //  cvConvertImage

        if(_Grab3)

        {

                for(int i = 0; i < _Grab->height; i++)

                {

                        memcpy(App + _Grab3->widthStep * (_Grab3->height - i - 1), data + _Grab3->widthStep * i, _Grab3->width * 3);

                }

        }

тут опять же как я понимаю, просто копируются данные, которые идут в одинаковом порядке только задом наперед.

т.е. не понятно как использовать memcopy в случае разных структур.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если структуры разные, то memcpy не подходит.

Надо делать перестановки поэлементно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

все таки не все проблемы решил.

изображение лежит по указателю dst имеет какой то размер w,h я хочу, удалить его и записать туда img который имеет другой размер.

void IplImagetoRGBPIXEL(IplImage* img, RGBPIXEL* dst)

{

	int width= img->width;

	int height= img->height;

	int nchannels= img->nChannels;


        if (dst!=NULL)

	delete [] dst; //выдает ошибку 


	dst= new RGBPIXEL[width * height];


	RGBPIXEL* pd=dst;

	RGBPIXEL* ps=dst;


	if(nchannels==3)

	{

		for( int y=0; y <height ; ++y ) 

		{           

			uchar* ptr = (uchar*) (img->imageData + y * img->widthStep);

			for( int x=0; x <width; ++x ) 

			{  

				 pd[x].blue= ptr[nchannels*x+0];

				 pd[x].green= ptr[nchannels*x+1];

				 pd[x].red= ptr[nchannels*x+2];

				 pd[x].reserved= 0;

			}

			pd += width;

		}

	}

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

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

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×