Jump to content
Compvision.ru
Sign in to follow this  
tybik

IplImage to Bmp и обратно

Recommended Posts

У меня вопрос. Как мне преобразовать формат изображений OpenCV в bmp. В интернете я нашел функции mycvGetImage и mycvShowImage. Но они не работают при вызове вылезает ошибка типа "Scan line index out of range". Может кто то уже сталкивался с этой проблемой??.. и у кого нить есть работающий пример??... Заранее спасибо..

Share this post


Link to post
Share on other sites
У меня вопрос. Как мне преобразовать формат изображений OpenCV в bmp. В интернете я нашел функции mycvGetImage и mycvShowImage. Но они не работают при вызове вылезает ошибка типа "Scan line index out of range". Может кто то уже сталкивался с этой проблемой??.. и у кого нить есть работающий пример??... Заранее спасибо..

Большинство примеров с этого форума содержат преобразование IPL->BMP.

Можно посмотреть хотя бы здесь:

http://www.compvision.ru/forum/index.php?showtopic=2, функция CreateRGBBitmap, как обратно - несложно догадаться :)

Share this post


Link to post
Share on other sites

А как сделать преобразование обратное bmp to iplimage. Если не сложно напишите функцию преобразования если у кого есть

Share this post


Link to post
Share on other sites

Создай изображение через cvCreateImage и вызови GetDIBBits в буфер этого изображения (переменная imageData).

Share this post


Link to post
Share on other sites

Исходные данные приведи. Что у тебя есть: HDC, HBITMAP?

Share this post


Link to post
Share on other sites

у меня есть изображние в Image1. И нужно перевести его в IplImage* img_load;

можно если не сложно написать кусочек кода. Заранее спасибо!

Share this post


Link to post
Share on other sites
у меня есть изображние в Image1. И нужно перевести его в IplImage* img_load;

можно если не сложно написать кусочек кода. Заранее спасибо!

Вот такое нашел на просторах интернета:

IplImage* hBitmap2Ipl(HBITMAP hBmp)
{
BITMAP bmp;
::GetObject(hBmp,sizeof(BITMAP),&bmp);
int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel/8;
int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
IplImage* img = cvCreateImageHeader( cvSize(bmp.bmWidth, bmp.bmHeight)
, depth, nChannels );
img->imageData =
(char*)malloc(bmp.bmHeight*bmp.bmWidth*nChannels*sizeof(char));
memcpy(img->imageData,(char*)(bmp.bmBits),bmp.bmHeight*bmp.bmWidth*nChannels);
return img;
}[/code]

Правда не слышал, чтобы opencv поддерживала тип IPL_DEPTH_1U, у них по этому поводу с интелом некоторая несовместимость (поставьте там такое: int depth = IPL_DEPTH_8U вместо , int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U; должно работать), но в целом кусок вроде годится, правда сам не компилировал.

Share this post


Link to post
Share on other sites

При работе возникает ошибка:

First chance exception at $75B59617. Exception class EAccessViolation with message 'Access violation at address 3299E573 in module 'CC3290MT.DLL'. Write of address 04B38000'. Process Plan.exe (3348)

на строке:

memcpy(img->imageData,(char*)(bmp.bmBits),bmp.bmHeight*bmp.bmWidth*nChannels);

не могу понять в чем дело...(((

Share this post


Link to post
Share on other sites

Странный адрес. Может у тебя утечка памяти? Созданный IplImage потом удаляешь? Что показывает диспетчер задач по поводу использования памяти твоей программой?

Share this post


Link to post
Share on other sites
Странный адрес. Может у тебя утечка памяти? Созданный IplImage потом удаляешь? Что показывает диспетчер задач по поводу использования памяти твоей программой?

Было бы неплохо кусок кода привести. Интересует, как инициализируется Image1, как Вы достаете из него Bitmap и что происходит с Image1 дальше?

Windowsовский это битмап или из билдера?

Share this post


Link to post
Share on other sites

Использую так:

size=cvSize(96,112);

img_load = cvCreateImage(size,IPL_DEPTH_8U,1 );

img_load = hBitmap2Ipl(Image5->Picture->Bitmap);

А дальше происходит распознавания этого изображения методом главных компонент.

Share this post


Link to post
Share on other sites
Использую так:

size=cvSize(96,112);

img_load = cvCreateImage(size,IPL_DEPTH_8U,1 );

img_load = hBitmap2Ipl(Image5->Picture->Bitmap);

А дальше происходит распознавания этого изображения методом главных компонент.

Может проще использовать вывод на Panel? Зачем нужен Image?

Вот такой функцией, она есть во всех примерах и быстрее получится.

APIDrawIpl(0, 0, frame_resized_clone, Panel1->Handle);

Share this post


Link to post
Share on other sites

не проще. я изоюражение получаю в Image. Я не использульзую для захвата OpenCV. Кроме того мне надо отрезать изображение, повернуть его. просто мне надо lzk передачи для распознавания преобразовать его в IPLImage.

Share this post


Link to post
Share on other sites
не проще. я изоюражение получаю в Image. Я не использульзую для захвата OpenCV. Кроме того мне надо отрезать изображение, повернуть его. просто мне надо lzk передачи для распознавания преобразовать его в IPLImage.

Тогда так:

HBITMAP hbm = in_picture->Picture->Bitmap->Handle;

size=cvSize(96,112);

img_load = cvCreateImage(size,IPL_DEPTH_8U,1 );

img_load = hBitmap2Ipl(hbm);

или Вот:

void mycvGetImage(TImage *bimg, IplImage *iimg){
byte *ptr;
long int datastep=iimg->widthStep;
long int height=iimg->height;
char *rawdata=iimg->imageDataOrigin;
for(int y=0; y<height; y++){
ptr = (byte *) bimg->Picture->Bitmap->ScanLine[y];
long int adr=(height-1-y)*datastep;
memcpy(rawdata+adr,ptr,datastep);
};
};[/code]

Это отсюда:

http://roboforum.ru/wiki/%D0%9D%D0%B0%D1%8...C%2B%2B_Builder

ЗЫ: Преобразования типа вырезать, повернуть перевернуть, и т.д. opencv делает намного быстрее чем GDI.

Share this post


Link to post
Share on other sites

оба ваших варианта работают. НО.

1. вариант.

Изображение перевернуто и после того как я перобразую в IPLImage и вызову функцию cvEigenDecomposite. вызывается ошибка что типа плохое число каналов.

2. вариант

изображение перевернуто и в iplImage оказывается только часть изображение, копируется не все. и после вызова cvEigenDecomposite также возникает ошибка.

и еще вопрос:

test_img = cvCreateImage(size,IPL_DEPTH_8U,1 ); - мы создаем черно белое изображение?

просто после преобразования я вызываю APIDrawIpl и мне отрисовывается цветная каритнка.

Share this post


Link to post
Share on other sites
оба ваших варианта работают. НО.

1. вариант.

Изображение перевернуто и после того как я перобразую в IPLImage и вызову функцию cvEigenDecomposite. вызывается ошибка что типа плохое число каналов.

2. вариант

изображение перевернуто и в iplImage оказывается только часть изображение, копируется не все. и после вызова cvEigenDecomposite также возникает ошибка.

и еще вопрос:

test_img = cvCreateImage(size,IPL_DEPTH_8U,1 ); - мы создаем черно белое изображение?

просто после преобразования я вызываю APIDrawIpl и мне отрисовывается цветная каритнка.

Чтобы перевернуть изображение: cvFlip(img,img);

cvEigenDecomposite - работает с одноканальным серыи изображением (создаете gray = cvCreateImage(size,IPL_DEPTH_8U,1 ); и потом, то что получилось после его выемки из Image конверитруете в серое cvCvtColor(image, gray, CV_BGR2GRAY); )

test_img = cvCreateImage(size,IPL_DEPTH_8U,1 ); - мы создаем серое изображение.

Share this post


Link to post
Share on other sites

Я написал код:

	  HBITMAP hbm = Image5->Picture->Bitmap->Handle;

	  size=cvSize(96,112);

	  img_load = cvCreateImage(size,IPL_DEPTH_8U,1 );

	  img_load = hBitmap2Ipl(hbm);

	  cvFlip(img_load,img_load);

	 // APIDrawIpl(477,150,img_load,this->Handle);

	  test_img = cvCreateImage(size,IPL_DEPTH_8U,1 );

	  cvCvtColor( test_img,img_load, CV_BGR2GRAY);

на выходе после выполнения cvCvtColor возникает ошибка - размер входящих аргументов не вычислен в функции cvCvtColor.

Share this post


Link to post
Share on other sites
Все заработало !!!!!!!!!!!!

Вместо cvCvtColor написал cvSplit

Только cvSplit дал Вам один канал из трех, если на входе три канала: R,G и B то Вы, вероятно вытащили один из них, посмотрите что в других каналах лежит, может оно Вам подойдет больше.

Share this post


Link to post
Share on other sites
Подскажите пожалуйста как преобразовать Mat в IplImage ?

Попробуйте так:

IplImage stub, *dst_img;

dst_img = cvGetImage(src_mat, &stub);

Share this post


Link to post
Share on other sites

cv::Mat img;

IplImage img2;

img2= cvGetImage(img, &img2);

APIDrawIpl(0, 0, img2, Form1->Panel2->Handle);

ошибка [C++ Error] Unit1.cpp(100): E2034 Cannot convert 'Mat' to 'const void *'

Share this post


Link to post
Share on other sites

Надо не саму матрицу, а указатель на неё передавать.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×