Веб-камера

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

Веб-камера

Сообщение Debugger » 12.08.2010 (Чт) 20:13

В программе необходимо анализировать изображение, полученное через веб-камеру.
Нагуглил пример http://www.codeproject.com/KB/vb/webcamcapture.aspx
Но в моей программе не надо показывать изображение с вебкамеры, нужно показывать только результаты анализа. Первое, что приходит в голову - скрыть PictureBox, в котором показывается картинка, и включить ему AutoRedraw. Но изображение на самом деле рисуется не PictureBox, а в окне, которое мы создаём, и это не прокатывает.
Как скрыть изображение, которое мы получаем с Web-камеры, но иметь возможность скопировать/анализировать его?

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

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

Сообщение FireFenix » 12.08.2010 (Чт) 20:26

Погуглю за тебя :)

How can I capture an image from a video source?

+

На одном форуме:
Код: Выделить всё
У меня на форме есть компонент Image. КАк сохранять в файл bmp
if SaveDialog1.Execute then
SendMessage(hWndC,
WM_CAP_SAVEDIB,
0,
longint(pchar(SaveDialog1.FileName)));

где WM_CAP_SAVEDIB=WM_CAP_START+25
а как сохранить фото сразу в этот компонент без временного сохранения в файл.


Код: Выделить всё
все разобрался
if (hWndC <> 0) and (SendMessage(hWndC, WM_CAP_GRAB_FRAME, 0, 0) = 1) and
(SendMessage(hWndC, WM_CAP_EDIT_COPY, 0, 0) = 1) and (Clipboard.HasFormat(CF_BITMAP)) then
begin
// bmp.
bmp:=TBitmap.Create;
BMP.Assign(Clipboard);
Image1.Picture.Assign(bmp);
end;
SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
hWndC := 0;


Вообще правильные пацаны делают получают фреймы или поток напрямую http://msdn.microsoft.com/en-us/library/ms713478
И загляни сюда:
http://www.codeproject.com/KB/audio-vid ... ebcam.aspx
http://www.blitzbasic.com/codearcs/code ... ?code=1437
http://www.experts-exchange.com/Program ... 22577.html
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

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

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

Сообщение Debugger » 12.08.2010 (Чт) 23:15

Спасибо :D
Получать изображение через буффер - неправильно. Поэтому буду посылать окну сообщение WM_CAP_SINGLE_FRAME. Перед этим сообщением надо установить процедуру-обработчик с помощью сообщения WM_CAP_SET_CALLBACK_FRAME. Процедура-обработчик будет принимать структуру типа VIDEOHDR. Тут меня смутило одно:
Код: Выделить всё
typedef struct videohdr_tag {
  LPBYTE    lpData;
  DWORD     dwBufferLength;
  DWORD     dwBytesUsed;
  DWORD     dwTimeCaptured;
  DWORD_PTR dwUser;
  DWORD     dwFlags;
  DWORD_PTR dwReserved[4];
} VIDEOHDR, *PVIDEOHDR, *LPVIDEOHDR;

lpData
Pointer to locked data buffer.
Однобайтовый указатель? Похоже да:
A BYTE is an 8-bit unsigned value that corresponds to a single octet in a network protocol.
This type is declared as follows:
typedef unsigned char BYTE, *PBYTE, *LPBYTE;

Однако на форумах считают вот как:
Код: Выделить всё
    Private Structure VIDEOHDR   
        Dim lpData As Integer '// address of video buffer   
        Dim dwBufferLength As Integer '// size, in bytes, of the Data buffer   
        Dim dwBytesUsed As Integer '// see below   
        Dim dwTimeCaptured As Integer '// see below   
        Dim dwUser As Integer '// user-specific data   
        Dim dwFlags As Integer '// see below   
        <VBFixedArray(3)> Dim dwReserved() As Integer '   
    End Structure   

Что же это?

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

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

Сообщение FireFenix » 12.08.2010 (Чт) 23:24

формально - LPBYTE = "дальний" (far) указатель на BYTE, PBYTE - "ближний" (near) указатель на BYTE, практически, с учётом модели памяти в Windows (flat) разницы никакой.

В данном случае указатель на Dim Buffer() as Byte

Т.е. Byte не тип указателя, а тип объекта на который ссылается
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

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

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

Сообщение Debugger » 13.08.2010 (Пт) 11:01

Понятно.
Насколько мне известно, дальний адрес занимает 48 бит, а ближний - 32. А в коде As Integer:
Код: Выделить всё
        Dim lpData As Integer '// address of video buffer   
        Dim dwBufferLength As Integer '// size, in bytes, of the Data buffer   

Впрочем, не важно. Получить байты получилось. Callback-функция вызывается с заполненной структурой, всё хорошо. Но при разрешении камеры 640 на 480 поле dwBytesUsed равно 614400. Получается 614400/(640*480) = 2 байта на пиксель?

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

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

Сообщение FireFenix » 13.08.2010 (Пт) 12:28

Debugger писал(а):адрес занимает 48 бит

Вроде адресация равна разрядности системы

fixed: глупая цитата с мануала. Каюсь...

Debugger писал(а):Впрочем, не важно. Получить байты получилось. Callback-функция вызывается с заполненной структурой, всё хорошо. Но при разрешении камеры 640 на 480 поле dwBytesUsed равно 614400. Получается 614400/(640*480)

Ты уверен что видео точно 640*480, а не 640*320?

Debugger писал(а):2 байта на пиксель?

Глубина цвета бывает 16 битной
Последний раз редактировалось FireFenix 13.08.2010 (Пт) 15:22, всего редактировалось 4 раз(а).
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

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

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

Сообщение Хакер » 13.08.2010 (Пт) 12:36

Бред. Адресация равна разрядности системы

В 32-битной ОС Windows — да. В 32-битном процессоре в 32-битном режиме адресация 48-битная, причём старшие 16 битов можно не указывать, тогда они берутся из сегментного регистра и адресация становится как-бы 32-битной.

Прыжок считается ближним, если адрес, на который делается прыжок, находится не дальше чем 128 байт назад и 127 байт вперёд от следующей команды. Дальний прыжок это прыжок дальше, чем на [-128,127] байт.
© с какого-то манула

Чушь. Авторов мануала казнить. Ибо касается это во-первых относительного прыжка, а во-вторых, там терминология не «дальний» (far) и «ближний» (near), а «длинный» (long) и «короткий» (short).
—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 » 13.08.2010 (Пт) 14:59

2 байта на пиксель. Как там кодируются каналы R, G и B - неизвестно:
http://www.pcreview.co.uk/forums/thread-2212580.php
http://forum.vingrad.ru/act-ST/f-95/t-225478.html
Выходит, картинку с изображением с web-камеры показывать придется?

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

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

Сообщение Хакер » 13.08.2010 (Пт) 15:10

Так, я что-то не понял.

Здесь VB.NET что-ли обсуждается? Тогда что эта тема делает тут?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

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

Сообщение FireFenix » 13.08.2010 (Пт) 15:14

Debugger писал(а):2 байта на пиксель. Как там кодируются каналы R, G и B - неизвестно

Using Video Capture -> Obtaining and Setting the Video Format -> BITMAPINFO -> BITMAPINFOHEADER

biBitCount = 16
The bitmap has a maximum of 2^16 colors. If the biCompression member of the BITMAPINFOHEADER is BI_RGB, the bmiColors member of BITMAPINFO is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of red, green, and blue are represented with five bits for each color component. The value for blue is in the least significant five bits, followed by five bits each for green and red. The most significant bit is not used. The bmiColors color table is used for optimizing colors used on palette-based devices, and must contain the number of entries specified by the biClrUsed member of the BITMAPINFOHEADER.

If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each WORD in the bitmap array represents a single pixel.

When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must be contiguous and should not overlap the bits of another mask. All the bits in the pixel do not have to be used.

© BITMAPINFOHEADER
16 — если поле biCompression содержит значение BI_RGB, файл не содержит палитры. Каждые два байта изображения хранят интенсивность красной, зелёной и синей компоненты одного пиксела. При этом старший бит не используется, на каждую компоненту отведено 5 бит: 0RRRRRGGGGGBBBBB.
Если поле biCompression содержит значение BI_BITFIELDS, палитра хранит три четырёхбайтовых значения, определяющих маску для каждой из трёх компонент цвета. Каждый пиксел изображения представлен двухбайтным значением, из которого с помощью масок извлекаются цветовые компоненты. Для WinNT/2000/XP — последовательности бит каждой компоненты должны следовать непрерывно, не перекрываясь и не пересекаясь с последовательностями других компонент. Для Win95/98/Me — поддерживаются только следующие маски: 5-5-5, где маска синей компоненты 0х001F, зелёной 0x03E0, красной 0x7C00; и 5-6-5, где маска синей компоненты 0x001F, зелёной 0x07E0, красной 0xF800.

© http://ru.wikipedia.org/wiki/BMP
не?

Поидее правильнее было бы
1) Получить капсы устройства
2) Найти в капсах поддерживаемые настройки глубины цвета разрешения и т.д.
3) Сравнить с теми которые задаёт юзер и установить оптимальные
4) Захват

P.S. Набрёл на китайском сайте xD
CAvicap.cpp
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

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

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

Сообщение Debugger » 13.08.2010 (Пт) 22:42

Нет. Все капсы я захватил, камера показывает в том режиме, в котором может.
Все оказалось хитрее значительно сложнее и эффективней, в общем-то, чем я думал.
Я все-таки получил BITMAPINFO и довольно долго созерцал biCompression=844715353. С полпинка такая константа не находится, но все же я выяснил, что в этих 16 битах YUY2.
Находим описание
http://fourcc.org/yuv.php#YUY2 (как я понял, тут на два пикселя общие коэффициенты U и V, да?)
Находим формулы перевода YUV->RGB
http://www.fourcc.org/fccyvrgb.php
Уже довольно поздно что-то ваять, завтра отпишусь, что получилось :)

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

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

Сообщение FireFenix » 13.08.2010 (Пт) 23:13

Код: Выделить всё
довольно долго созерцал biCompression=844715353

Вбив в гугль я довольно быстро нашёл формат :)

http://fourcc.org/yuv.php#YUY2 (как я понял, тут на два пикселя общие коэффициенты U и V, да?)

YUY2 разновидность формата YUV => минимум 3 коэффициента(Y, U, V) определяющие цвет
msdn писал(а):In YUY2 format, the data can be treated as an array of unsigned char values, where the first byte contains the first Y sample, the second byte contains the first U (Cb) sample, the third byte contains the second Y sample, and the fourth byte contains the first V (Cr) sample


Возможно лучше покурить http://msdn.microsoft.com/en-us/library/Aa904813 , ибо переводы на разных сайтах немного отличаются...
Последний раз редактировалось FireFenix 14.08.2010 (Сб) 12:02, всего редактировалось 1 раз.
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

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

Сообщение iGrok » 14.08.2010 (Сб) 0:32

Неа. Не *fail*.

Debugger писал(а):как я понял, тут на два пикселя общие коэффициенты U и V, да?

Именно.

4 байта YUY2 (YUYV) определяют 6 байт RGB. В первой паре y0 и u, во второй - y1 и v.
Соответственно, rgb для первого пикселя получается из y0, u, v; для второго - y1, u, v.

Насчёт верности формул ничего не скажу - не знаю. Но с виду похоже на правду.

UPD: О какая фишка:
Код: Выделить всё
y0 = (unsigned char) YUV[i + 0];
u = (unsigned char) YUV[i + 1] - 128;
y1 = (unsigned char) YUV[i + 2];
v = (unsigned char) YUV[i + 3] - 128;

http://csclab.ucsd.edu/documentation/ht ... c.html#a14
label:
cli
jmp label

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

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

Сообщение Debugger » 14.08.2010 (Сб) 13:45

Разобрался.
Код: Выделить всё
Public VIDEOINFO As BITMAPINFO
Public VIDEOBUFF() As RGBQUAD
Dim FrameBytes() As Byte
Dim BufInit As Boolean

Private Function Clamp(tmp As Integer) As Byte
    If tmp < 0 Then tmp = 0
    If tmp > 255 Then tmp = 255
    Clamp = tmp
End Function

Function YUV2RGB(ByVal y As Single, ByVal U As Single, ByVal V As Single) As RGBQUAD
    YUV2RGB.rgbBlue = Clamp(1.164 * (y - 16) + 2.018 * (U - 128))
    YUV2RGB.rgbGreen = Clamp(1.164 * (y - 16) - 0.813 * (V - 128) - 0.391 * (U - 128))
    YUV2RGB.rgbRed = Clamp(1.164 * (y - 16) + 1.596 * (V - 128))
End Function

Function FrameCallback(ByVal hwnd As Long, ByRef struc As VIDEOHDR) As Long
    Dim b() As Byte, x As Integer, y As Integer, c As Long
    If Not BufInit Then
        ReDim FrameBytes(struc.dwBytesUsed)
        BufInit = True
    End If
    CopyMemory FrameBytes(0), ByVal struc.lpData, struc.dwBytesUsed
    For x = 0 To VIDEOINFO.bmiHeader.biWidth - 1 Step 2
        For y = 0 To VIDEOINFO.bmiHeader.biHeight - 1
            c = y * VIDEOINFO.bmiHeader.biWidth + x
            c = c * 2
            VIDEOBUFF(x, y) = YUV2RGB(FrameBytes(c), FrameBytes(c + 1), FrameBytes(c + 3))
            VIDEOBUFF(x + 1, y) = YUV2RGB(FrameBytes(c + 2), FrameBytes(c + 1), FrameBytes(c + 3))
            'Проверка (чисто тест)
            SetPixel Form1.pct.hdc, x, y, RGB(VIDEOBUFF(x, y).rgbRed, VIDEOBUFF(x, y).rgbRed, VIDEOBUFF(x, y).rgbRed)
            SetPixel Form1.pct.hdc, x + 1, y, RGB(VIDEOBUFF(x + 1, y).rgbRed, VIDEOBUFF(x + 1, y).rgbRed, VIDEOBUFF(x + 1, y).rgbRed)
        Next
    Next
    DoEvents
End Function

Кусок кода (не весь), в котором YUV-массив переводится (и рисуется для проверки) в RGB. Работает, но оочень медленно (даже без SetPixel).
( кстати, именование компонент буквами YUV - плохая затея. Они очень похожи. )

Mihail_
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 31.03.2008 (Пн) 20:57

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

Сообщение Mihail_ » 19.09.2010 (Вс) 15:54

а в настройках видеоустройства нельзя при помощи WM_CAP_DLG_VIDEOFORMAT сразу режим RGB установить? обычно это даже самые дешевые веб камеры и платы видеозахвата по 10$ позволяют сделать..

Изображение

тогда в VIDEOHDR.lpData получим байты в формате Blrue Green Red, и перевернутые вверх ногами по X и Y.. и уже даже обсуждали как их быстрее всего перевернуть и отрисовать viewtopic.php?f=1&t=40547

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

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

Сообщение Debugger » 19.09.2010 (Вс) 16:36

Mihail_ писал(а):обычно это даже самые дешевые веб камеры и платы видеозахвата по 10$ позволяют сделать

Пруф?

Mihail_
Обычный пользователь
Обычный пользователь
 
Сообщения: 96
Зарегистрирован: 31.03.2008 (Пн) 20:57

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

Сообщение Mihail_ » 19.09.2010 (Вс) 17:41

на что именно? это из личного опыта.. неужели идущий в комплекте к камере WDM драйвер совсем не позволяет выбирать глубину цвета? что это за камера такая? возможно тогда стоит поискать новую версию или альтернативный драйвер по VID & PID устройства? цветовая модель изображения с камеры это ж программное...
если нужен линк на usb плату видеозахвата за 10$ которая даже со стандартными дровами все это позволяет это делать я дам...

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

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

Сообщение Debugger » 19.09.2010 (Вс) 17:58

Доказательства-то где?
Две вполне приличные камеры от A4Tech. У обоих этой функции нет:
Вложения
videocap.png
videocap.png (13.3 Кб) Просмотров: 2917


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

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

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

    TopList  
cron