Фильтры ProxyTrans и SyncFilter - работа с 2-мя камерами

Фильтры ProxyTrans и SyncFilter - работа с 2-мя камерами

Сообщение Пётр » 06 янв 2008, 20:32

Как известно в OpenCV при работе с 2-мя одинаковыми камерами возникают проблемы с определением камер, частотой кадров и сменой разрешения кадра. Всё дело в том что стандартные функции OpenCV исползуют устаревшую библиотеку Video For Windows (VFW), которая давно не обновляется и не поддерживается новыми драйверами. Я хочу предложить более сложный вариант работы с камерами, но лишённый старых недостатков. В составе OpenCV идёт DirectShow фильтр ProxyTrans, который осуществляет захват изображения формата IplImage. Для этого необходимо составить граф примерно следующего вида:

УСТРОЙСТВО ЗАХВАТА(ваша камера)--ProxyTransFilter(захватывает кадры)--NullRenderer(заглушка вывода)

Фильтру ProxyTrans необходимо передать указатель на процедуру, которая будет получать кадры. Я прикрепил к посту файл с исходником на С++, в котором происходит работа с двумя одинаковыми камерами, устанавливается разрешение и частота кадров, а также посредством OpenGL изображения накладываются друг на друга. Служит эта небольшая программка для геометрического выравнивания стереопары камер друг относительно друга(настройки на бесконечность). Просьба ногами сильно не бить, я не профессиональный программист, но мнения и конструктивные замечания приветствуются.
Вложения
camera.cpp
С++ код работы фильтра ProxyTrans в DirectShow
(14.6 КиБ) Скачиваний: 368
Последний раз редактировалось Пётр 11 янв 2008, 04:40, всего редактировалось 2 раз(а).
Пётр
 
Сообщения: 5
Зарегистрирован: 06 янв 2008, 19:44

Re: Фильтр ProxyTrans и работа с 2-мя камерами

Сообщение =DeaD= » 06 янв 2008, 23:14

Тема интересная, и, хотя непосредственно сейчас времени нет кинуться в эксперименты - в ближайшее время попробую провести попытку использовать код, а под какую среду разработки он?
Проект [[Open Robotics]] - Универсальные модули для построения роботов
Аватара пользователя
=DeaD=
 
Сообщения: 24218
Зарегистрирован: 06 окт 2004, 18:01
Откуда: Ебург
прог. языки: C++ / PHP / 1C
ФИО: Антон Ботов

Re: Фильтр ProxyTrans и работа с 2-мя камерами

Сообщение Пётр » 07 янв 2008, 10:29

Программу писал под MS Visual Studio 2005, думаю без проблем пойдёт и на предыдущих/последующих версиях. Код не полный - не хватает заголовочника standart.h в котором описано создание окна OpenGL и оконная процедура. Могу выложить и его, хотя для понимания сути работы он не нужен.
Пётр
 
Сообщения: 5
Зарегистрирован: 06 янв 2008, 19:44

Re: Фильтр ProxyTrans и работа с 2-мя камерами

Сообщение =DeaD= » 07 янв 2008, 11:32

Пётр писал(а):Программу писал под MS Visual Studio 2005, думаю без проблем пойдёт и на предыдущих/последующих версиях. Код не полный - не хватает заголовочника standart.h в котором описано создание окна OpenGL и оконная процедура. Могу выложить и его, хотя для понимания сути работы он не нужен.

А можете выложить полный проект? Я просто пишу под C++ Builder и нет особого желания ради 1 фишки осваивать новую среду разработки, изучая что и как там делается, чтобы проект запустился :)
Проект [[Open Robotics]] - Универсальные модули для построения роботов
Аватара пользователя
=DeaD=
 
Сообщения: 24218
Зарегистрирован: 06 окт 2004, 18:01
Откуда: Ебург
прог. языки: C++ / PHP / 1C
ФИО: Антон Ботов

Re: Фильтр ProxyTrans и работа с 2-мя камерами

Сообщение Пётр » 08 янв 2008, 09:40

Легко :)
Осваивать ничего и не надо. Я, например, разбирался с DirectShow большей частью на примерах из Дельфи и C#, не зная ни того ни другого. Важно понять принцип построения графа.
Я прикрепил проект, в котором экспериментировал с фильтром ProxyTrans. Кстати есть ещё фильтры CalibFilter, для настройки(калибровки) камеры по "шахматной доске", и SyncFilter для синхронизации 2х камер, что тоже должно представлять немалый интерес для нелёгкого дела роботостроения ;) Только с ними я ещё не разбирался.

Добавлено спустя 20 часов 24 минуты 53 секунды:
Фильтр ProxyTrans и работа с 2-мя камерами
Я разобрался, что вместо того, чтобы получать массив фильтров видеозахвата в функции FindMyCaptureDevice для нескольких одинаковых камер, можно получить конкретный фильтр для конкретной камеры. Но для этого необходимо величать каждую камеру по полному имени-отчеству(DisplayName), вместо прозвища (FriendlyName). Например в моём случае для 2х камер FriendlyName="Logitech QuickCam for Notebooks Deluxe", т.е. одинаковое. А вот DisplayName для 1-ой = "@device:pnp:\\\\?\\usb#vid_046d&pid_08a9&mi_00#6&196e7674&1&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global", для 2-ой = "@device:pnp:\\\\?\\usb#vid_046d&pid_08a9&mi_00#7&2c141bb7&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global". Как говорится, найдите 10 отличий :)
Посмотреть эти названия можно в Диспетчере Устройств, а лучше в утилите GraphEdit, откуда я их и скопировал.
После изменения имён, правда, придётся переделать и процедуру FindMyCaptureDevice, например так:

Код: Выделить всё
HRESULT FindMyCaptureDevice(IBaseFilter **pF, char *szFilterName)
{
   ICreateDevEnum               *pSysDevEnum;
   IMoniker                  *pMoniker;
   IPropertyBag               *pProp;
   IEnumMoniker               *pEnumMoniker;
   IBaseFilter                  *pFilter;


   ULONG                     cFetched;
   LPOLESTR                  lpostrDisplayName=NULL;
   LPSTR                     szDisplayName;

   HRESULT                     hResult = S_OK;   

USES_CONVERSION;

   hResult = CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, ( void ** )&pSysDevEnum );
   if( FAILED(hResult) )
   {
      MessageBox(NULL, "Создание экземпляра перечислителя устройств не удалось.", "Error",   MB_ICONERROR | MB_OK);
      return hResult;
   }

   hResult = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0);
   if( FAILED(hResult) )
   {
      MessageBox(NULL, "Получение интерфейса перечислителя видеустройств не удалось.", "Error",   MB_ICONERROR | MB_OK);
      return hResult;
   }

   while(  pEnumMoniker->Next(1, &pMoniker, &cFetched) == S_OK )
   {
      //получение интерфйса хранилища
      hResult = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pProp);
      //получаем системное имя устройства
      pMoniker->GetDisplayName(NULL, NULL, &lpostrDisplayName);
      szDisplayName = OLE2A(lpostrDisplayName);
      
      if (SUCCEEDED(hResult) && (lstrcmp(szDisplayName, szFilterName) == 0))
      {
         //получение интерфейса нужного устройства
         hResult = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pFilter);
         *pF = pFilter;
         (*pF)->AddRef();
         break;
      }
      pMoniker = NULL;
      hResult = S_FALSE;
   }

   pEnumMoniker->Release();
   pSysDevEnum->Release();
   
   return hResult;
}
Вложения
Camera.zip
Весь проект для работы с ProxyTrans
(24.4 КиБ) Скачиваний: 50
Пётр
 
Сообщения: 5
Зарегистрирован: 06 янв 2008, 19:44

Фильтры ProxyTrans и SyncFilter-работа с 2-мя камерами

Сообщение Пётр » 10 янв 2008, 06:20

Разбирался намедни с работой SyncFilter, смотрел исходники OpenCV и выяснил, что CVCAM использует для своей работы не VFW, а DirectShow и те самые фильтры ProxyTrans - для одной камеры, SyncFilter - для 2-х, 3-х, 4-х камер. Казалось бы - всё хорошо, бери используй, да не тут то было. Есть один маленький нюанс, камеры инициируются только в диалоговом окне, вываливающимся при вызове cvcamSelectCamera, никакой автоматической инициализации не предусматривается.
Именно поэтому я решил идти до конца и по аналогии ProxyTrans задействовал фильтр SyncFilter. Он предназначен для синхронизации от 2-х до 4-х камер. Так-же как и с ProxyTrans ему необходимо передать указатель на callback процедуру, получающую кадры формата IplImage. Как обычно, пришлось несколько переделать программу, потому как я не смог присоединить фильтр с помощью метода CaptureGraphBuilder->RenderStream(). Необходимо помнить, что SyncFilter работает только с 2-мя и более камерами, в случае одной следует использовать ProxyTrans.
Вложения
Camera.zip
Вариант кода для работы с SyncFilter
(27.14 КиБ) Скачиваний: 47
Пётр
 
Сообщения: 5
Зарегистрирован: 06 янв 2008, 19:44


Вернуться в Алгоритмы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4