tybik 0 Report post Posted April 18, 2010 У меня вопрос. Как мне преобразовать формат изображений OpenCV в bmp. В интернете я нашел функции mycvGetImage и mycvShowImage. Но они не работают при вызове вылезает ошибка типа "Scan line index out of range". Может кто то уже сталкивался с этой проблемой??.. и у кого нить есть работающий пример??... Заранее спасибо.. Share this post Link to post Share on other sites
Smorodov 576 Report post Posted April 18, 2010 У меня вопрос. Как мне преобразовать формат изображений 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
tybik 0 Report post Posted May 9, 2010 А как сделать преобразование обратное bmp to iplimage. Если не сложно напишите функцию преобразования если у кого есть Share this post Link to post Share on other sites
tybik 0 Report post Posted May 13, 2010 Неужели никто с этим не сталкивался? Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted May 13, 2010 Создай изображение через cvCreateImage и вызови GetDIBBits в буфер этого изображения (переменная imageData). Share this post Link to post Share on other sites
tybik 0 Report post Posted May 13, 2010 А можно кусочек кода для понятности.. Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted May 13, 2010 Исходные данные приведи. Что у тебя есть: HDC, HBITMAP? Share this post Link to post Share on other sites
tybik 0 Report post Posted September 22, 2010 у меня есть изображние в Image1. И нужно перевести его в IplImage* img_load; можно если не сложно написать кусочек кода. Заранее спасибо! Share this post Link to post Share on other sites
Smorodov 576 Report post Posted September 22, 2010 у меня есть изображние в 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
tybik 0 Report post Posted September 23, 2010 При работе возникает ошибка: 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
Nuzhny 243 Report post Posted September 24, 2010 Странный адрес. Может у тебя утечка памяти? Созданный IplImage потом удаляешь? Что показывает диспетчер задач по поводу использования памяти твоей программой? Share this post Link to post Share on other sites
Smorodov 576 Report post Posted September 24, 2010 Странный адрес. Может у тебя утечка памяти? Созданный IplImage потом удаляешь? Что показывает диспетчер задач по поводу использования памяти твоей программой? Было бы неплохо кусок кода привести. Интересует, как инициализируется Image1, как Вы достаете из него Bitmap и что происходит с Image1 дальше? Windowsовский это битмап или из билдера? Share this post Link to post Share on other sites
tybik 0 Report post Posted September 24, 2010 Использую так: 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
Smorodov 576 Report post Posted September 24, 2010 Использую так: 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
tybik 0 Report post Posted September 25, 2010 не проще. я изоюражение получаю в Image. Я не использульзую для захвата OpenCV. Кроме того мне надо отрезать изображение, повернуть его. просто мне надо lzk передачи для распознавания преобразовать его в IPLImage. Share this post Link to post Share on other sites
Smorodov 576 Report post Posted September 25, 2010 не проще. я изоюражение получаю в 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
tybik 0 Report post Posted September 27, 2010 оба ваших варианта работают. НО. 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
Smorodov 576 Report post Posted September 27, 2010 оба ваших варианта работают. НО. 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
tybik 0 Report post Posted September 28, 2010 Я написал код: 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
tybik 0 Report post Posted September 28, 2010 Все заработало !!!!!!!!!!!! Вместо cvCvtColor написал cvSplit Share this post Link to post Share on other sites
Smorodov 576 Report post Posted September 28, 2010 Все заработало !!!!!!!!!!!! Вместо cvCvtColor написал cvSplit Только cvSplit дал Вам один канал из трех, если на входе три канала: R,G и B то Вы, вероятно вытащили один из них, посмотрите что в других каналах лежит, может оно Вам подойдет больше. Share this post Link to post Share on other sites
tybik 0 Report post Posted October 20, 2010 Подскажите пожалуйста как преобразовать Mat в IplImage ? Share this post Link to post Share on other sites
Smorodov 576 Report post Posted October 20, 2010 Подскажите пожалуйста как преобразовать Mat в IplImage ? Попробуйте так: IplImage stub, *dst_img; dst_img = cvGetImage(src_mat, &stub); Share this post Link to post Share on other sites
tybik 0 Report post Posted October 20, 2010 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
Nuzhny 243 Report post Posted October 21, 2010 Надо не саму матрицу, а указатель на неё передавать. Share this post Link to post Share on other sites