Jump to content
Compvision.ru
virt

Вывод видео на форму в visual studio 2008 - 2010

Recommended Posts

Привет всем.Помогите пожалуйста вывести на форму или какую-нибудь компоненту типа image или panel(не важно)-видео.На просторах форума я нашел функцию Создание API шного битмапа из интеловского RGB изображения.Но дело в том,что сий код предназначен был для Builder и visual у меня ругается на каждом шагу,сначала ругался на тип HBITMAP,проблему решил изменив в свойствах clr проекта.Может у кого завалялась программка на visual для вывода видео на форму?

Либо ,если не сложно,помогите разобраться с переводом кода для builder в visual.Например как в visual написать

Application->OnIdle = IdleLoop; // Поток обработки простоя

а также как написать обработчик

void __fastcall TForm1::IdleLoop(TObject*, bool& done)

и куда его поместить?

Share this post


Link to post
Share on other sites

Привет. В общем вот выкладываю перевод с БИЛДЕРА на ВИЖУАЛ (кстати недавно совсем переводил), "Создание APIшного битмапа из интеловского RGB изображения" присутствует. Смотри, разбирайся. Если, что не пойдет пиши - разберемся.

[Прикрепленный файл был потерян при откате форума]

  • Like 3

Share this post


Link to post
Share on other sites

Не подскажите где можно найти документацию по Qt?

Вот здесь можно скачать последнюю версию библиотеки QT - http://doc.crossplatform.ru/qt/. Документация там же. Устанавливается легко и просто. После установки можно и нужно запустить QT Examples and Demos - хорошая интерактивная обучалка с примерами, листингом и местами даже с русскими комментариями. Вот.

И еще пожалуй выложу старые лекции из универа. Все пригодится людям :)

[Прикрепленный файл был потерян при откате форума]

Share this post


Link to post
Share on other sites

Решил отписаться про свои успехи. в общем на .NET и EmguCV забил - раньше не сталкивался, с ходу не пошло, разбираться некогда.

Решил попробовать MFC, хоть с ним тоже раньше не сталкивался, но начал получать хоть какие-то результаты, потому решил на нем остановиться.

Для таких начинающих как я расскажу что и как я делал:

1) создал MFC проект в Visual Studio 2010

2) на dialog (главную форму) бросил компонент Picture Control

3) в свойствах Picture Control в поле "Тип" установил "Точечный рисунок", в поле "ИД" стоит IDC_STATIC - его нужно изменить, НЕ выбрать из выпадающего списка, а вбить ручками. я, например, вбил IDC_CAP_STATIC.

я еще ставил "Изображение по центру" в true, иначе у меня не получалось растянуть Picture Control по форме...

4) потом нужно добавить переменную для Picture Control, для того чтоб можно было с ним работать. для этого клацаем правой кн. по Picture Control и жмем "Добавить переменную". потом указываем имя, например m_cap, и тип переменной CStatic

5) теперь нужно прикрутить OpenCV к проекту. я делал как сказано тут. там же и простой примерчик.

6) в OpenCV изображения представлены типом IplImage, а компонент Picture Control понимает Bitmap.

для преобразования типов я воспользовался кодом, который нашел в сети (спасибо автору :thumbsu: ):


HBITMAP CreateRGBBitmap(IplImage* _Grab)

{

	char *App;

    LPBITMAPINFO lpbi = new BITMAPINFO;

    lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

    lpbi->bmiHeader.biWidth = _Grab->width;

    lpbi->bmiHeader.biHeight =_Grab->height;

    lpbi->bmiHeader.biPlanes = 1;

    lpbi->bmiHeader.biBitCount = 24;

    lpbi->bmiHeader.biCompression = BI_RGB;

    lpbi->bmiHeader.biSizeImage = WIDTHBYTES((DWORD)_Grab->width * 8) * _Grab->height;

    lpbi->bmiHeader.biXPelsPerMeter = 0;

    lpbi->bmiHeader.biYPelsPerMeter = 0;

    lpbi->bmiHeader.biClrUsed = 0;

    lpbi->bmiHeader.biClrImportant = 0;

    void* pBits;

    HBITMAP hBitmap = CreateDIBSection( NULL,lpbi,DIB_RGB_COLORS,(void **)&pBits,NULL,0 );

    delete lpbi;

    if ( hBitmap ) App=(char*)pBits;

	long int length=0;

	if(_Grab->nChannels==1) // Серое или бинарное

	{

		length = _Grab->width*(_Grab->height);

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

		{

			for (int j=0;j<_Grab->width;j++)

			{

				App[_Grab->width*3*(_Grab->height-i-1)+j*3]=_Grab->imageData[_Grab->width*(i)+j];

				App[_Grab->width*3*(_Grab->height-i-1)+j*3+1]=_Grab->imageData[_Grab->width*(i)+j];

				App[_Grab->width*3*(_Grab->height-i-1)+j*3+2]=_Grab->imageData[_Grab->width*(i)+j];

			}

		}

	}

	if(_Grab->nChannels==3) // Цветное

	{

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

		{

			// Копируем память

			memcpy(App+_Grab->width*3*(_Grab->height-i-1),_Grab->imageData+_Grab->width*3*i,_Grab->width*3);           

		}

	}

	return hBitmap;

}

7) теперь, уже имея картинку pBitmap с типом HBITMAP, можно отобразить ее на Picture Control (напомню, у нас есть переменная m_cap). для этого делаем следующее:

// Получить контекст устройства

CDC* dc = m_cap.GetDC();

// Создать контекст устройства в памяти

HDC hMemDC = CreateCompatibleDC(dc->m_hDC);

// Поместить растровое изображение в dc памяти и 

// сохранить старое изображение

HGDIOBJ hOldBm = SelectObject(hMemDC, pBitmap);


// Копировать содержимое dc памяти в dc экрана	

BitBlt(dc->m_hDC, 0, 0, width, height, // Приемник: dc экрана

	hMemDC, 0, 0, SRCCOPY);	  // Источник: dc памяти  

// Восстановить старое растровое изображение в dc памяти

SelectObject(hMemDC, hOldBm);

// Уничтожить dc памяти

DeleteDC(hMemDC);

// Освободить полученый контекст устройства

ReleaseDC(dc);

// Уничтожить растровое изображение

DeleteObject(pBitmap);

все... картинку показываем!!! отображать видео у меня сначала не получилось, точнее картинка сильно мерцала. выделял отображение в отдельный поток - не помогло. потом, в сети, я вычитал что в MFC и Windows все основывается на сообщениях (можно почитать тут) и для вывода видео можно использовать таймер. делается это так: 1) создаем таймер, захватчик камеры, и указатель на картинку:

UINT_PTR m_nTimer;

CvCapture* capture;

IplImage* frame;

а в методе OnInitDialog() дописываем:

// Инициализация таймера

// Таймер будет посылать WM_TIMER сообщение основному 

// рамочному окну каждые 30 миллисекунд

m_nTimer = SetTimer(1, 30, 0);


// получаем любую подключенную камеру

capture = cvCreateCameraCapture(CV_CAP_ANY);

assert( capture );

2) добавляем обработку сообщений от таймера. т.е. жмем Проект->Мастер классов, выбираем имя класса диалога (как правило заканчивается на ...Dlg), переходим на вкладку "Сообщения" и в левой части находим WM_TIMER и добавляем обработчик (в правой части появится OnTimer и т.д.). 3) в обработчике OnTimer() дописываем захват изображения с камеры и отображение в Picture Control:

frame = cvQueryFrame( capture );

DrawData(CreateRGBBitmap(frame));


void CtestDlg::DrawData(HBITMAP pBitmap)

{                        

	// Получить контекст устройства

	CDC* dc = m_cap.GetDC();

	// Создать контекст устройства в памяти

    HDC hMemDC = CreateCompatibleDC(dc->m_hDC);

	// Поместить растровое изображение в dc памяти и 

	// сохранить старое изображение

    HGDIOBJ hOldBm = SelectObject(hMemDC, pBitmap);


	// Копировать содержимое dc памяти в dc экрана	

	BitBlt(dc->m_hDC, 0, 0, width, height, // Приемник: dc экрана

			hMemDC, 0, 0, SRCCOPY);	  // Источник: dc памяти  

    // Восстановить старое растровое изображение в dc памяти

	SelectObject(hMemDC, hOldBm);

	// Уничтожить dc памяти

    DeleteDC(hMemDC);

	// Освободить полученый контекст устройства

	ReleaseDC(dc);

	// Уничтожить растровое изображение

    DeleteObject(pBitmap);


    UpdateData(FALSE);

}

4) ну и нужно при выходе из программы освободить ресурсы:

cvReleaseCapture( &capture );

cvReleaseImage(&frame);

KillTimer(1);

я это делаю в обработчике сообщения WM_CLOSE...

ну, вроде и все... надеюсь ничего не пропустил и кому-то это поможет :)

  • Like 1

Share this post


Link to post
Share on other sites

Привет всем!

Вот, попытался сделать пример вывода видео на форму. И, думаю, получилось :)

Для того, что-бы скопировать IplImage в объект .NET типа Image, достаточно всего лишь

одной строки:


#include <opencv/cv.h>

#include <opencv/highgui.h>


...


using namespace System;

using namespace System::Windows::Forms;

using namespace System::Drawing::Imaging;

using namespace System::Drawing;


...


IplImage *iplImg;


...


// Копирование IplImage в объект .NET типа Image

Image ^image = gcnew Bitmap(iplImg->width, iplImg->height, iplImg->widthStep,

	PixelFormat::Format24bppRgb, IntPtr(iplImg->imageData));


...

или, с использованием класса Mat:

cv::Mat imgMat;


// Копирование cv::Mat в объект .NET типа Image

Image ^img = gcnew Bitmap(imgMat.cols, imgMat.rows, imgMat.step,

	PixelFormat::Format24bppRgb, IntPtr(imgMat.data));

Чтобы вывести изображение на компоненту PictureBox, достаточно следующей строки в одном из методов вашей формы:
this->pictureBox1->Image = image;
Если вам нужен HBITMAP, то получить его можно следующим образом:

Bitmap ^image = gcnew Bitmap(iplImg->width, iplImg->height, iplImg->widthStep,

	PixelFormat::Format24bppRgb, IntPtr(iplImg->imageData));

HBITMAP hb = (HBITMAP)image->GetHbitmap().ToPointer();

У меня вышеприведенные примеры отлично работают с OpenCV 2.2 в Visual Studio 2008/2010.

К сообщению прилагаю проект простого видео плеера, написанного с помощью OpenCV 2.2

в Visual Studio 2008. Он может воспроизводить все типы видео, которые берет OpenCV и

видео, захваченное с видеокамеры. Не судите строго за возможные несовершенства в коде :unsure:

Просто, я старался, что бы были основные функции плеера.

Пояснения к проекту.

Компиляция:

Чтобы успешно скомпилировать проект, достаточно в опциях Visual Studio установить пути

на OpenCV в следующем виде:

%OPENCV_HOME%\include

и

%OPENCV_HOME%\lib

Например, так:

C:\OpenCV2.2\include

и

C:\OpenCV2.2\lib

Другое:

При создании проекта использовались следующие опции и установки.



  1. .NET Framework 3.5.
  2. General/Common Language Runtime Support: Common Language Runtime Support (/clr)
  3. C/C++/Advanced/Disable Specific Warnings: 4996;4793
  4. Linker/Input/Additional Dependencies:
    opencv_core220d.lib
    opencv_highgui220d.lib
    opencv_imgproc220d.lib
    opencv_objdetect220d.lib
    Для версии Release: без "d" после 220.
  5. В компоненте PictureBox свойство SizeMode имеет значение Zoom, что позволяет
    сохранить оригинальное соотношение сторон кадра.
  6. Для визуализации кадров используется Tick таймера.

При двойном щелчке по области отображения, происходит переход в полноэкранный режим и обратно.

Надеюсь, пример кому-нибудь пригодится :rolleyes:

VideoOnForm.zip

  • Like 4

Share this post


Link to post
Share on other sites

Подскажите пожалуйста как реализовать это все хозяйство на С++ именно в Builder(е) 6.....

Заранее благодарен!

Share this post


Link to post
Share on other sites

maximator - ское руководство вдохновило меня расковырять вывод на форму в VS2010. Очень ему благодарен. Нашел пару косяков, и по сему, вношу свою лепту в это дело в виде исходников. Захват видео идет в отдельном потоке без задержек. Оформляю статью (maximator естественно в соавторах :) ).

OpenCV_MFC.rar С-шный вариант (на основе того что было для билдера)

OpenCV_MFC(C++).rar С++ ый вариант (на основе исходников OpenCV, вроде в этом сарианте есть утечка памяти, сильно не разбирался, использую первый вариант)

Share this post


Link to post
Share on other sites

Здравствуйте! а нельзя ли похожую статейку для компиляции Windows form Application под Visual Studio 2008? я искал на форуме, но так и не смог понять что я не так делаю. ошибки компилятор выдает такие же как в посте 4: http://www.compvision.ru/forum/index.php?showtopic=413&st=0&p=3825&hl=form%20application&fromsearch=1&#entry3825

Я ковырялся с проектом под MFC, но все уперлось в банальную вещь... не могу понять как получать доступ к свойствам объектов непосредственно в коде программы (типа button1->text=...) или же нечто подобное для слайдера.

А в проекте Windows form Application все это делается без лишних манипуляций

Share this post


Link to post
Share on other sites

Сделал все настройки проекта как в посте 7, но компилятор выдает ошибки


UIM2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall cv::HOGDescriptor::setSVMDetector(class std::vector > const &)" (?setSVMDetector@HOGDescriptor@cv@@UAEXABV?$vector@MV?$allocator@M@std@@@std@@@Z)

UIM2.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall cv::HOGDescriptor::read(class cv::FileNode &)" (?read@HOGDescriptor@cv@@UAE_NAAVFileNode@2@@Z)

UIM2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall cv::HOGDescriptor::write(class cv::FileStorage &,class std::basic_string,class std::allocator > const &)const " (?write@HOGDescriptor@cv@@UBEXAAVFileStorage@2@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)

UIM2.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall cv::HOGDescriptor::load(class std::basic_string,class std::allocator > const &,class std::basic_string,class std::allocator > const &)" (?load@HOGDescriptor@cv@@UAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z)

UIM2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall cv::HOGDescriptor::save(class std::basic_string,class std::allocator > const &,class std::basic_string,class std::allocator > const &)const " (?save@HOGDescriptor@cv@@UBEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z)

UIM2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall cv::HOGDescriptor::copyTo(struct cv::HOGDescriptor &)const " (?copyTo@HOGDescriptor@cv@@UBEXAAU12@@Z)

UIM2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall cv::HOGDescriptor::compute(class cv::Mat const &,class std::vector > &,class cv::Size_,class cv::Size_,class std::vector,class std::allocator > > const &)const " (?compute@HOGDescriptor@cv@@UBEXABVMat@2@AAV?$vector@MV?$allocator@M@std@@@std@@V?$Size_@H@2@2ABV?$vector@V?$Point_@H@cv@@V?$allocator@V?$Point_@H@cv@@@std@@@5@@Z)

UIM2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall cv::HOGDescriptor::detect(class cv::Mat const &,class std::vector,class std::allocator > > &,double,class cv::Size_,class cv::Size_,class std::vector,class std::allocator > > const &)const " (?detect@HOGDescriptor@cv@@UBEXABVMat@2@AAV?$vector@V?$Point_@H@cv@@V?$allocator@V?$Point_@H@cv@@@std@@@std@@NV?$Size_@H@2@2ABV45@@Z)

UIM2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall cv::HOGDescriptor::detectMultiScale(class cv::Mat const &,class std::vector,class std::allocator > > &,double,class cv::Size_,class cv::Size_,double,int)const " (?detectMultiScale@HOGDescriptor@cv@@UBEXABVMat@2@AAV?$vector@V?$Rect_@H@cv@@V?$allocator@V?$Rect_@H@cv@@@std@@@std@@NV?$Size_@H@2@2NH@Z)

UIM2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall cv::HOGDescriptor::computeGradient(class cv::Mat const &,class cv::Mat &,class cv::Mat &,class cv::Size_,class cv::Size_)const " (?computeGradient@HOGDescriptor@cv@@UBEXABVMat@2@AAV32@1V?$Size_@H@2@2@Z)

C:\Documents and Settings\User\Мои документы\Visual Studio 2008\Projects\UIM2\Debug\UIM2.exe : fatal error LNK1120: 10 unresolved externals


Опытным путем я установил что ошибки возникают при подключении cv.h, а как все это исправить не пойму

Share this post


Link to post
Share on other sites

Расписываюсь в своей неграмотности)) нужно было подключить библиотеку opencv_objdetect220d.lib. В посте №7 все правильно!! Спасибо Nicola!!!

Share this post


Link to post
Share on other sites

Nicola, привет.

У меня вопрос насчет:

Linker/Input/Additional Dependencies:

opencv_core220d.lib

opencv_highgui220d.lib

opencv_imgproc220d.lib

opencv_objdetect220d.lib

Для версии Release: без "d" после 220.

а если OpenCV 2.1 то

opencv_core210d.lib

opencv_highgui210d.lib

opencv_imgproc210d.lib

opencv_objdetect210d.lib

?

Но где взять эти библиотеки ? У меня OpenCV 2.1

Share this post


Link to post
Share on other sites

В opencv-шной директории lib они лежат.

Если скачали только исходники, то нужно скомпилировать их, появятся dll и lib файлы.

Как компилировать было в теме "установка opencv в картинках".

Share this post


Link to post
Share on other sites

В том то и дело, что опенСВ 2.1 качал установиочник ( не исходники ), по мануалу устанавливал - все работает, но вот этих либов не нахожу никак.

чтоб скомпилировать нужен файл .sln на сколько я помню. Его там тоже нету. Компилировал так опенСВ 2.0 когда-то.

Share this post


Link to post
Share on other sites

Сначала тебе надо поставить CMake, им сгенерировать файлы проектов.

Share this post


Link to post
Share on other sites

Спасибо, вопрос решен )

Запускаю приложение. Не открывает видео файлы и камеру тоже не открывает, выдает ошибки. У кого видео открывалось ?

Share this post


Link to post
Share on other sites

Какие конкретно ошибки и когда выдает?

Share this post


Link to post
Share on other sites

Запускается приложение.

жму open Webcam ---- выдает ошибку Cannot open WebCam

жму open Video ---- выдает ошибку Cannot open "c:/video/......"

Хотя из семплов опенСВ приложение открывает webcam

Share this post


Link to post
Share on other sites

А какое приложение Вы запускаете?

Share this post


Link to post
Share on other sites

Компилирую

Прикрепленный файл VideoOnForm.zip
выложенный на предыдущей странице.

Share this post


Link to post
Share on other sites

Должно вообще то работать, а какая версия opencv у Вас? И что за камера?

Может заработает если указать другой номер камеры: -1,1,2.

Share this post


Link to post
Share on other sites
Должно вообще то работать, а какая версия opencv у Вас? И что за камера?

Может заработает если указать другой номер камеры: -1,1,2.

OpenCV 2.2

так приложение из samples работает с камерой. Надо попробовать оттуда код взять

Share this post


Link to post
Share on other sites

Уважаемые, как сделать чтобы не воспроизводилось видео, а брался один кадр и вставлялся в PictureBox, т.е. тупо фоткало при нажатии на кнопку на форме? Пробовал использовать приведенный пример от Nicolа работает на ура, вебкамера включается, видео воспроизводится, но мне не нужно всех этих сложных функций. Объясните пожалуйста что конкретно нужно для фото по его примеру. Пытался использовать участки кода, всё безуспешно.

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


  • Recently Browsing   0 members

    No registered users viewing this page.

×