Веб-камера

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Веб-камера

Сообщение Debugger » 12.01.2011 (Ср) 23:32

Сначала я создаю окно захвата (capCreateCaptureWindowA, возвращается имя драйвера), затем присоединяюсь к драйверу (capDriverConnect) и работаю с камерой по своему усмотрению.

1. Я посылаю окну сообщение WM_CAP_DLG_VIDEOFORMAT, выводится окошко со списком имён источников изображений. Как можно получить имя камеры, с которой сейчас происходит захват изображения?

2. Я ещё раз сделаю capCreateCaptureWindowA, подключусь к тому же драйверу (и попрошу пользователя выбрать другой источник изображения). Будет ли происходить одновременный захват изображений с двух камер для одного приложения через один драйвер?

3. Как можно быстро конвертировать YUV2-изображение (полученное как массив данных) в RGB? Ручками по формуле получается не очень быстро. Выводить на форму и делать GetDIBit не предлагайте.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 13.01.2011 (Чт) 16:24

Ап.
Debugger писал(а):Выводить на форму и делать GetDIBit не предлагайте.

Предлагайте, если можно вывести на скрытый PictureBox. У меня не получилось.

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Веб-камера

Сообщение pronto » 14.01.2011 (Пт) 8:37

А драйвер устройства предоставляет диалог «Формат видео»? В котором обычно можно изменить кодировку и глубину цвета?
capDlgVideoFormat = SendMessage(lwnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0)
O, sancta simplicitas!

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 14.01.2011 (Пт) 17:16

pronto писал(а):А драйвер устройства предоставляет диалог «Формат видео»? В котором обычно можно изменить кодировку и глубину цвета?
capDlgVideoFormat = SendMessage(lwnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0)

Предоставляет; но кодировка одна - YUV2. Суровая камера от A4Tech. Есть предложения?

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 15.01.2011 (Сб) 22:02

Ап.
Ни у кого нет идей? 3 вопрос не очень важен; фиг с ней, со скоростью. Очень сильно волнует
Debugger писал(а):2. Я ещё раз сделаю capCreateCaptureWindowA, подключусь к тому же драйверу (и попрошу пользователя выбрать другой источник изображения). Будет ли происходить одновременный захват изображений с двух камер для одного приложения через один драйвер?

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 16.01.2011 (Вс) 23:48

Вопрос об имени и параметрах камеры почти отпал: мне помог WIA (которого, похоже, к этой задаче никак не привязать) и WM_CAP_GET_MCI_DEVICE (который не хочет давать имя активной камеры, хотя возвращает не-ноль).

С быстрым преобразованием YUV2->RGB я вот придумал какой изврат.
Нарисовать содержимое камеры в невидимый буфер и сделать GetDIBits из него. В скрытом PictureBox'е камера не хотела отрисовываться (AutoRedraw не помог). Вроде бы всё, но можно попробовать заставить содержимое CaptureWindow отрисоваться в другом месте.:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
For some common controls, the default WM_PAINT message processing checks the wParam parameter. If wParam is non-NULL, the control assumes that the value is an HDC and paints using that device context.

Теперь осталось выяснить, является ли CaptureWindow "some common control". Почему-то
Код: Выделить всё
Debug.Print SendMessage(lwndC, WM_PAINT, 0, 0)

Всегда возвращает 0. Почему?

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 17.01.2011 (Пн) 0:01

Потому что он рисуется по таймеру, а не по моему велению. Чееееееерт.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 17.01.2011 (Пн) 0:34

В общем то слать WM_PAINT — дурной тон. Хочешь перерисовать — инвалидируй/обновляй.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 17.01.2011 (Пн) 15:09

Я хочу заставить окно отрисовать себя в другое место. WM_PAINT, где wparam - хендл места, куда я хочу отрисовать, не прокатил.
Это вообще как-то можно сделать?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 17.01.2011 (Пн) 15:13

Debugger писал(а):Это вообще как-то можно сделать?

Правильно?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 17.01.2011 (Пн) 21:04

Хоть правильно, хоть хитрым способом.
Задача в том, чтобы получить RGB-изображение с камеры. Мой план заключается в том, чтобы заставить нарисовать на скрытый PictureBox и сделать GetDIBits из него. Есть другие предложения?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 17.01.2011 (Пн) 21:09

Debugger писал(а):нарисовать на скрытый PictureBox

Как ты планировал это сделать используя WM_PAINT?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 17.01.2011 (Пн) 21:43

For some common controls, the default WM_PAINT message processing checks the wParam parameter. If wParam is non-NULL, the control assumes that the value is an HDC and paints using that device context.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 17.01.2011 (Пн) 21:57

Не надо мне цитировать MSDN. Мне надо увидеть твои слова, чтобы найти в них логическую нестыковку, подчеркнуть её и указать на неё тебе. В тексте из MSDN её нет, она есть внутри твоей головы в твоём личном обосновании методики объединения сведений о WM_PAINT (отцитированных), задачи и замысла использования PictureBox-а.

То есть, что-то вроде «Я хочу отправить окну WM_PAINT, передав в качестве wParam ..., потому что в этом случае WM_PAINT интерпретируя wParam как ..., нарисует на ... нужную мне графику». Вместо многоточий подставь свои мысли.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 17.01.2011 (Пн) 23:09

Я хочу отправить моему окну WM_PAINT, передав в wParam hdc моего PictureBox, потому что в этом случае моё окно интерпретирует wParam как хендл устройства, на котором надо рисовать, и нарисует на PictureBox'e нужную мне графику.

Это решение я использую, поскольку мне нужно быстро получать данные с камеры. У меня здорово получается делать это в YUV-формате. Но после этого ручками конвертировать - теряю очень много скорости.
Мне решение нужно срочно. Поэтому подойдёт любое. В начале я не хотел использовать этот метод (он похож на печать на принтере и прикладывание отпечатка к сканеру), но срок вот-вот подойдёт к концу.
Последний раз редактировалось Debugger 17.01.2011 (Пн) 23:14, всего редактировалось 1 раз.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 17.01.2011 (Пн) 23:12

Debugger писал(а):Я хочу отправить моему окну WM_PAINT, передав в wParam hdc моего PictureBox, потому что в этом случае моё окно интерпретирует wParam как хендл устройства, на котором надо рисовать, и нарисует на PictureBox'e нужную мне графику.


Отлично. Сообщаю тебе, что из этого текста следует, что PictureBox является устройством, что неверно.

Исправялй ошибку (на другую ошибку) и продолжим разбор.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 17.01.2011 (Пн) 23:18

Я хочу отправить моему окну WM_PAINT, передав в wParam hdc моего PictureBox, потому что в этом случае моё окно интерпретирует wParam как хендл устройства, на котором надо рисовать, и нарисует на Image PictureBox'a нужную мне картинку.

Окно не хочет делать то, что мне хочет потому что оно не умеет этого делать. Оно не будет перерисовываться по WM_PAINT. Оно рисуется по внутренним событиям (таймеру).

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 17.01.2011 (Пн) 23:23

Debugger писал(а):Окно не хочет делать то, что мне хочет потому что оно не умеет этого делать. Оно не будет перерисовываться по WM_PAINT. Оно рисуется по внутренним событиям (таймеру).

Да это мелочь, сначала поработаем над глобальными ошибками/заблуждения.

Debugger писал(а):Я хочу отправить моему окну WM_PAINT, передав в wParam hdc моего PictureBox, потому что в этом случае моё окно интерпретирует wParam как хендл устройства, на котором надо рисовать, и нарисует на Image PictureBox'a нужную мне картинку.


Ошибки:
  • Image PictureBox'а — несуществующее понятие
  • WM_PAINT не интерпретирует wParam как хендл устройства. wParam интерпретируется как хендл DC. DC не есть устройство.

Исправляй и продолжим разбор дальше.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 17.01.2011 (Пн) 23:28

Бр-р.
Я хочу отправить моему окну WM_PAINT, передав в wParam hDC моего PictureBox, потому что в этом случае окно интерпретирует wParam как handle контекста устройства, на котором надо рисовать, и нарисует на PictureBox'е (разве не на нём?) нужную мне картинку.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 17.01.2011 (Пн) 23:37

Debugger писал(а):Я хочу отправить моему окну WM_PAINT, передав в wParam hDC моего PictureBox, потому что в этом случае окно интерпретирует wParam как handle контекста устройства, на котором надо рисовать, и нарисует на PictureBox'е (разве не на нём?) нужную мне картинку.


У твоего PictureBox-а нет hDC, у него есть два DC (для клиентской и неклиентской области), у каждого из которых есть хендл.

Ты хочешь рисовать на устройстве «дисплей», используя DC, принадлежащий клиентской области окна PictureBox-а. PictureBox при этом объявляется скрытым, из чего следует, что его окно скрыто, из чего следует, что его клиентская область не видна, из чего следует, что регион отсечения DC — пуст, из чего следует, что ни один пиксел на устройстве «дисплей» изменён не будет.

Таким образом, даже если бы WM_PAINT обрабатывался должым образом, что ты хотел?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 18.01.2011 (Вт) 18:52

Как получить хендл клиентской/неклиентской области PictureBox'a?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 18.01.2011 (Вт) 19:01

Область не является объектом какой-либо подсистемы и не имеет хендла.

Но для клиентской и неклиентской области любого окна создаётся DC, у которого есть хендл.

Хендл DC для клиентской области возвращается свойство hDC или функция GetDC(PB.hWnd). Хендл DC для неклиентской области — GetWindowDC(PB.hWnd).

Меня прямо таки раздирает вопрос: неужели ты не понял вышеизложенный текст? Перефразирую: в чём чертов смысл рисовать на скрытом PictureBox-а, если все функции рисования отработают в холостую, не изменив ни одного пиксела в устройстве «дисплей»?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 18.01.2011 (Вт) 19:28

Хакер писал(а):Меня прямо таки раздирает вопрос: неужели ты не понял вышеизложенный текст? Перефразирую: в чём чертов смысл рисовать на скрытом PictureBox-а, если все функции рисования отработают в холостую, не изменив ни одного пиксела в устройстве «дисплей»?

Понял. Я понадеялся на Autoredraw. Что же он делает?
Опытным путём выяснил, что происходит какая-то магия:
Код: Выделить всё
    TextOut GetDC(pct.hwnd), 0, 0, "A", 1
    TextOut GetWindowDC(pct.hwnd), 10, 0, "B", 1
    TextOut pct.hdc, 30, 0, "C", 1
    BitBlt Me.hdc, 0, 0, 50, 50, GetDC(pct.hwnd), 0, 0, vbSrcCopy
    BitBlt Me.hdc, 50, 0, 50, 50, GetWindowDC(pct.hwnd), 0, 0, vbSrcCopy
    BitBlt Me.hdc, 150, 0, 50, 50, pct.hdc, 0, 0, vbSrcCopy

Рисуется только буковка C (GetDC(PB.hWnd)=pct.hDC?).Соответственно, я предполагал, что когда мы пытаемся рисовать на PictureBox'e с Autoredraw=True, мы на самом деле рисуем на некоем буфере, и PB затем использует его для отрисовки себя. Также я предполагал, что этот "буфер" - это и есть PB.Image. Значит, заставив окно камеры рисовать себя в PictureBox, мы получить два в одном: превьюшку и буфер изображения (при Visible=True/False).

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 18.01.2011 (Вт) 19:36

Debugger писал(а):Соответственно, я предполагал, что когда мы пытаемся рисовать на PictureBox'e с Autoredraw=True, мы на самом деле рисуем на некоем буфере, и PB затем использует его для отрисовки себя.

Нет, это AutoRedraw работает только с методами самого PB. Как ты себе представляешь, чтобы GDI-функции, получив хендл контекста устройства-дисплея рисовали не на дисплее, а в каком-то левом буфере?

С тех пор, как для PB создался дисплейный DC, все графические операции с использованием этого DC производятся над дисплеем и только над ним. Тем не менее, если рисовать куда-то надо, но явно не на экран, ты можешь создать логический буфер и использовать не дисплейный DC, а DC для этого буфера. Ищи по «memory DC».
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 18.01.2011 (Вт) 19:52

Спасибо, почитаю.
А можно моё окно как-то заставить рисоваться в произвольный DC?

Хакер писал(а):Нет, это AutoRedraw работает только с методами самого PB. Как ты себе представляешь, чтобы GDI-функции, получив хендл контекста устройства-дисплея рисовали не на дисплее, а в каком-то левом буфере?

Получается, что да. Буковка "C" выведена не методом PictureBox'a на скрытом PB.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 18.01.2011 (Вт) 19:57

Debugger писал(а):Буковка "C" выведена не методом PictureBox'a на скрытом PB.

И что?
Проведи окном поверх своего PB и буковка сотрётся как мусор.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 18.01.2011 (Вт) 20:01

Проведи окном поверх своего PB

Он же невидим.

А можно моё окно как-то заставить рисоваться в произвольный DC?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 18.01.2011 (Вт) 20:07

Debugger писал(а):Он же невидим.

То есть ты рисуешь, когда он скрыт, потом делаешь его видимым, и там буква «C»?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Веб-камера

Сообщение Debugger » 18.01.2011 (Вт) 20:19

Код: Выделить всё
    TextOut GetDC(pct.hwnd), 0, 0, "A", 1
    TextOut GetWindowDC(pct.hwnd), 10, 0, "B", 1
    TextOut pct.hdc, 30, 0, "C", 1
    BitBlt Me.hdc, 0, 0, 50, 50, GetDC(pct.hwnd), 0, 0, vbSrcCopy
    BitBlt Me.hdc, 50, 0, 50, 50, GetWindowDC(pct.hwnd), 0, 0, vbSrcCopy
    BitBlt Me.hdc, 150, 0, 50, 50, pct.hdc, 0, 0, vbSrcCopy

Нет, "С" успешно копируется из PB на форму:
Код: Выделить всё
    BitBlt Me.hdc, 150, 0, 50, 50, pct.hdc, 0, 0, vbSrcCopy

рисуешь, когда он скрыт, потом делаешь его видимым, и там буква «C»?

Так тоже работает.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Веб-камера

Сообщение Хакер » 18.01.2011 (Вт) 20:35

Ответ очевиден: в режиме Autoredraw свойство hDC возвращает не хендл DC для клиентской области окна PB, а хендл DC буфера в памяти.

Ну, соответственно, можно использовать скрытый PB со включенным Autoredraw-ом как расточительный способ создания такого буфера в памяти, но не нужно.

Теперь по поводу того, как заставить чужое окно отрисовать себя в нужный DC.
  1. Единственный законным, правильным и документированным способом является отправка WM_CLIENTPRINT. Но это сообщение обычно не поддерживается кастомными окнами.
  2. Незаконный и хитрый пусть: перехватывать BeginPaint в процессе, владеющим окном, и делать подмену поля hdc в структуре PAINTSTRUCT. Но если чужое приложение написано в нарушение правил хорошего тона, может и не сработать.
  3. Тогда перехватывать в самом начале GetDC/GetWindowDC и подменять их своим значением.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

След.

Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: AhrefsBot и гости: 93

    TopList