Форум программистов, компьютерный форум, киберфорум
Pure Basic
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.79/81: Рейтинг темы: голосов - 81, средняя оценка - 4.79
Ты за кого меня держиш!?
22 / 23 / 7
Регистрация: 26.10.2011
Сообщений: 308
Записей в блоге: 1
1

Обработка изображения с веб камеры на предмет движущихся объектов\изменившихся пикселей

14.08.2012, 21:13. Просмотров 14516. Ответов 93
Метки нет (Все метки)

Специально для тех кто долго дрючил свои мозги, перерыл пол гугля и нихрена не нашёл выкладываю готовый пример обработки изображения с веб камеры.

PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#WM_CAP_START                          = #WM_USER
#WM_CAP_SET_CALLBACK_ERROR             = #WM_CAP_START + 2
#WM_CAP_SET_CALLBACK_CAPCONTROL_STATUS = #WM_CAP_START + 3
#WM_CAP_SET_CALLBACK_YIELD             = #WM_CAP_START + 4
#WM_CAP_SET_CALLBACK_FRAME             = #WM_CAP_START + 5
#WM_CAP_SET_CALLBACK_VIDEOSTREAM       = #WM_CAP_START + 6
#WM_CAP_SET_CALLBACK_WAVESTREAM        = #WM_CAP_START + 7
#WM_CAP_GET_STATUS                     = #WM_CAP_START + 54;-------------------
#WM_CAP_DRIVER_CONNECT                 =  #WM_USER + 10
#WM_CAP_DRIVER_DISCONNECT              =  #WM_USER + 11
#WM_CAP_DRIVER_GET_CAPS                = #WM_CAP_START + 14
#WM_CAP_DLG_VIDEOFORMAT                = #WM_CAP_START + 41
#WM_CAP_DLG_VIDEOSOURCE                = #WM_CAP_START + 42
#WM_CAP_DLG_VIDEODISPLAY               = #WM_CAP_START + 43
#WM_CAP_SET_PREVIEW                    = #WM_CAP_START + 50
#WM_CAP_SET_PREVIEWRATE                = #WM_CAP_START + 52
#WM_CAP_GET_STATUS                     = #WM_CAP_START + 54
#WM_CAP_FILE_SAVEDIB                   =  #WM_USER + 25
#WM_CAP_SET_SCALE                      =  #WM_USER + 53
#WM_CAP_SET_CALLBACK_CAPCONTROL        = #WM_CAP_START + 85
 
 
 
;------------------------------------------------------------------------------------------------------------
 
 
 
Structure CAPSTATUS  ;Тут нас интересуют высота и ширина(первые две строчки)
  uiImageWidth.l 
  uiImageHeight.l 
  fLiveWindow.l 
  fOverlayWindow.l 
  fScale.l 
  ptScroll.Point 
  fUsingDefaultPalette.l 
  fAudioHardware.l 
  fCapFileExists.l 
  dwCurrentVideoFrame.l 
  dwCurrentVideoFramesDropped.l 
  dwCurrentWaveSamples.l 
  dwCurrentTimeElapsedMS.l 
  hPalCurrent.l 
  fCapturingNow.l 
  dwReturn.l 
  wNumVideoAllocated.l 
  wNumAudioAllocated.l 
EndStructure
 
CapStat.CAPSTATUS
 
Structure VIDEOHDR; в этой структуре первая строчка - кадр
  lpData.l
  dwBufferLength.l
  dwBytesUsed.l
  dwTimeCaptured.l
  dwUser.l
  dwFlags.l
  dwReserved.l[3]
EndStructure
 
Structure SBGR ;Цвета по байту на синий зелёный и красный считываемые из памяти далее
  b.b
  g.b
  r.b  
EndStructure
 
 
 
 
Global width     = 300
Global height    = 240
 
Global widthImg  = 0
Global heightImg = 0
 
Global Min       = 90
Global Max       = 110
 
Global Dim  B (0, 0);Объявление двух массивов, один для хранения старых данных, второй для записи в него результата
Global Dim  C (0, 0) ; Redim
 
 
 
Enumeration
  #STP         = 1;Шаг цикла. Если менять то надо в "*VideoMemoryAdress1 + 3" тройку умножать на шаг. Суть шага такова, что если он = 2 то скорость обработки увеличивается вдвое а качество тудаже уменьшается. 
  #Menu        = 1;Это всё про меню, оно для красоты
  #Menu_Device = 2
  #Menu_exit   = 3
  #Menu_Pause  = 4
EndEnumeration
 
 
 
;------------------------------------------------------------------------------------------------------------
 
 
 
Procedure FrameCallback(hWnd, *lpVHdr.VIDEOHDR);
  Protected *VideoMemoryAdress1.SBGR = *lpVHdr\lpData;Пошоль просесс
  Protected xn,yn, color, SA, SB
  For xn = heightImg - 1 To 0 Step - #STP
    For yn = 0 To widthImg - 1 Step #STP
      
      color = RGB(*VideoMemoryAdress1\r & $FF, *VideoMemoryAdress1\g & $FF,;считываем цвет *VideoMemoryAdress1\b & $FF)
      *VideoMemoryAdress1 + 3 ;перескакиваем на следующие 3 байта
      
      SA = color / 100;Один процент цвета 
      SB = B(yn, xn);Извлекаем цвет из предыдущего кадра, он в виде цифры в массиве
      B(yn, xn) = color;Присваиваем туда же новое значение, обновляя кадр
      If SA = 0 ; делить на 0 нельзя
        Shodstvo = 0
      Else
        Shodstvo =  SB / SA; Точка отсчёта равна ста процентам, а дальше дело техники, 110 мньше 100 на 10, 120 больше 100 на 20, чем больше разница - Shodstvo - 100, тем больше различий между пикселями в 2-х кадрах в одном и том же месте 
        If Shodstvo < 100 And shodstvo > Min Or Shodstvo > 100 And Shodstvo < Max
          С(yn, xn) = RGB(0, 0, 0))
        Else
          С(yn, xn) = color);Если ещё немного подшаманить и сдеать отрисовку результата а не присвоение значений элементам массива, то получим чёрный экран на котором будут видны только подвижные объекты. Хорошо фильтрует серую картинку, по тому что чем меньше диапазон значений, тем меньше разница между якобы похожими пикселями
        EndIf
      EndIf
      
    Next
  Next
 EndProcedure    
    
    
 
 
;------------------------------------------------------------------------------------------------------------
 
 
 
 
hWnd = OpenWindow(0, 0, 0, width + 4, height + 60, "", #PB_Window_SystemMenu| #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
 
If CreateMenu(#Menu, WindowID(0))
  MenuTitle("Программа")
    MenuItem(#Menu_exit, "Выключить")
      MenuBar()
    MenuItem(#Menu_Pause, "?")
  MenuTitle("Настройки")
    MenuItem(#Menu_Device, "Сменить устройство")
EndIf
 
 
 
;------------------------------------------------------------------------------------------------------------
 
 
 
 
If OpenLibrary(0, "AVICAP32.DLL")
  hWebcam = CallFunction(0, "capCreateCaptureWindowA", 0, #WS_VISIBLE+#WS_CHILD, 2, 20, width, height, hWnd, 0)
  
  SendMessage_(hWebcam, #WM_CAP_DRIVER_CONNECT          , 0 , 0);Подключаем устройство
  SendMessage_(hWebcam, #WM_CAP_SET_SCALE               , 1 , 0)
  SendMessage_(hWebcam, #WM_CAP_SET_PREVIEWRATE         , 50, 0)
  SendMessage_(hWebcam, #WM_CAP_SET_PREVIEW             , 1 , 0)
  
  SendMessage_(hWebcam, #WM_CAP_GET_STATUS              , SizeOf(CAPSTATUS), CapStat);------------
  widthImg  = CapStat\uiImageWidth;Устанавливаем ширину
  heightImg = CapStat\uiImageHeight;высоту
  ReDim B(widthImg, heightImg);устанавливаем размеры массивов, чтоб всё соответсвовало всему
  ReDim C(widthImg, heightImg)
  SendMessage_(hWebcam, #WM_CAP_SET_CALLBACK_FRAME      , 0 , @FrameCallback());и получаем заветные кадры
  
  
  
;------------------------------------------------------------------------------------------------------------
  
  
 
Repeat
  
  Event = WindowEvent()
  Select Event
      
    Case #PB_Event_CloseWindow
      Break
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case #Menu_exit
          Break
          
          Case #Menu_Pause
            
          Case #Menu_Device
            
        EndSelect
      
  EndSelect
ForEver
  
  
  
  
;------------------------------------------------------------------------------------------------------------
  
  
  
  
  SendMessage_(hWebcam, #WM_CAP_SET_PREVIEW       , 0, 0)
  SendMessage_(hWebcam, #WM_CAP_DRIVER_DISCONNECT, @"BLUBBER", 0)
  
  CloseWindow(0)
  CloseLibrary(0)
  
EndIf
 
End
Конец

Добавлено через 41 секунду
Там только надо память очищать чтоб не утекла.

Добавлено через 4 минуты
По остальным вопросам лазим тут: http://msdn.microsoft.com/en-u... s.85).aspx
тут: http://purebasic.ru/manual.php?id=1104&lng=rus
тут: http://www.google.ru/webhp?source=search_app
и здесь.
2
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.08.2012, 21:13
Ответы с готовыми решениями:

Обработка изображения(группировка пикселей)
Здравствуйте, почитал статью http://job-interview.ru/articles/post/362 и захотел реализовать тоже...

Обработка изображения размером 800х600 пикселей
Здравствуйте,подскажите пожалуйста, что не так. Есть исходное изображение размером 800х600...

Обработка изображения: поиск пикселей определённого цвета
Добрый вечер! Имеется такое задание: есть изображение, нужно найти пиксели определенного цвета и...

Анализ изображения с веб-камеры
Всем привет! Буду очень признателен, если вы подскажете мне на каком языке проще и/или удобнее...

93
Ты за кого меня держиш!?
22 / 23 / 7
Регистрация: 26.10.2011
Сообщений: 308
Записей в блоге: 1
15.08.2012, 21:50  [ТС] 2
Это снова я. По своей глупости и наивности думал что всё просто а оказалось не тут то было.
В общем когда кинулся пробовать записывать в память значения осознал что цикл в процедуре FrameCallback не исполняется. Как я понял эта процедура для обработки кадра перед выводом в окно. Помогите доработать.

PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#WM_CAP_START                          = #WM_USER
#WM_CAP_SET_CALLBACK_ERROR             = #WM_CAP_START + 2
#WM_CAP_SET_CALLBACK_CAPCONTROL_STATUS = #WM_CAP_START + 3
#WM_CAP_SET_CALLBACK_YIELD             = #WM_CAP_START + 4
#WM_CAP_SET_CALLBACK_FRAME             = #WM_CAP_START + 5
#WM_CAP_SET_CALLBACK_VIDEOSTREAM       = #WM_CAP_START + 6
#WM_CAP_SET_CALLBACK_WAVESTREAM        = #WM_CAP_START + 7
#WM_CAP_GET_STATUS                     = #WM_CAP_START + 54
#WM_CAP_DRIVER_CONNECT                 =  #WM_USER + 10
#WM_CAP_DRIVER_DISCONNECT              =  #WM_USER + 11
#WM_CAP_DRIVER_GET_CAPS                = #WM_CAP_START + 14
#WM_CAP_DLG_VIDEOFORMAT                = #WM_CAP_START + 41
#WM_CAP_DLG_VIDEOSOURCE                = #WM_CAP_START + 42
#WM_CAP_DLG_VIDEODISPLAY               = #WM_CAP_START + 43
#WM_CAP_SET_PREVIEW                    = #WM_CAP_START + 50
#WM_CAP_SET_PREVIEWRATE                = #WM_CAP_START + 52
#WM_CAP_GET_STATUS                     = #WM_CAP_START + 54
#WM_CAP_FILE_SAVEDIB                   =  #WM_USER + 25
#WM_CAP_SET_SCALE                      =  #WM_USER + 53
#WM_CAP_SET_CALLBACK_CAPCONTROL        = #WM_CAP_START + 85
 
 
 
 
;------------------------------------------------------------------------------------------------------------
 
 
 
 
Structure CAPSTATUS 
  uiImageWidth.l 
  uiImageHeight.l 
  fLiveWindow.l 
  fOverlayWindow.l 
  fScale.l 
  ptScroll.Point 
  fUsingDefaultPalette.l 
  fAudioHardware.l 
  fCapFileExists.l 
  dwCurrentVideoFrame.l 
  dwCurrentVideoFramesDropped.l 
  dwCurrentWaveSamples.l 
  dwCurrentTimeElapsedMS.l 
  hPalCurrent.l 
  fCapturingNow.l 
  dwReturn.l 
  wNumVideoAllocated.l 
  wNumAudioAllocated.l 
EndStructure
 
CapStat.CAPSTATUS
 
Structure VIDEOHDR
  lpData.l
  dwBufferLength.l
  dwBytesUsed.l
  dwTimeCaptured.l
  dwUser.l
  dwFlags.l
  dwReserved.l[3]
EndStructure
 
Structure SBGR
  b.b
  g.b
  r.b  
EndStructure
 
 
 
 
;------------------------------------------------------------------------------------------------------------
 
 
 
 
Global width     = 300
Global height    = 240
 
Global widthImg  = 0
Global heightImg = 0
 
Global Min       = 90
Global Max       = 110
 
Global Dim  B (0, 0)
Global Dim  C (0, 0) ; Redim
 
 
 
Enumeration
  #STP         = 1
  #Menu        = 1
  #Menu_Device = 2
  #Menu_exit   = 3
  #Menu_Stop   = 4
  #Menu_Start  = 5
EndEnumeration
 
 
 
;------------------------------------------------------------------------------------------------------------
 
 
 
Procedure FrameCallback(hWnd, *lpVHdr.VIDEOHDR)
  Protected *VideoMemoryAdress1.SBGR = *lpVHdr\lpData
  Protected xn,yn, color, SA, SB
  For xn = heightImg - 1 To 0 Step - #STP
    For yn = 0 To widthImg - 1 Step #STP
      Debug xn
      color = RGB(PeekB(*VideoMemoryAdress1\r),PeekB( *VideoMemoryAdress1\g), PeekB(*VideoMemoryAdress1\b)
      Debug color
      SA = color / 100
      SB = B(yn, xn)
      B(yn, xn) = color
      If SA = 0 ; делить на 0 нельзя
        Shodstvo = 0
      Else
        Shodstvo =  SB / SA
        If Shodstvo < 100 And shodstvo > Min Or Shodstvo > 100 And Shodstvo < Max
;**************************************
 
        EndIf
      EndIf
      
      *VideoMemoryAdress1 + 3 * #STP
    Next
  Next
 EndProcedure    
 
 Procedure Start(hWebcam)
   SendMessage_(hWebcam, #WM_CAP_DRIVER_CONNECT          , 0 , 0)
   SendMessage_(hWebcam, #WM_CAP_SET_SCALE               , 1 , 0)
   SendMessage_(hWebcam, #WM_CAP_SET_PREVIEWRATE         , 50, 0)
   SendMessage_(hWebcam, #WM_CAP_SET_PREVIEW             , 1 , 0)
 EndProcedure 
 
 Procedure Stop(hWebcam)
   SendMessage_(hWebcam, #WM_CAP_SET_PREVIEW       , 0, 0)
   SendMessage_(hWebcam, #WM_CAP_DRIVER_DISCONNECT, 0, 0)
 EndProcedure
    
 
 
;------------------------------------------------------------------------------------------------------------
 
 
 
 
hWnd = OpenWindow(0, 0, 0, width + 4, height + 60, "", #PB_Window_SystemMenu| #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
 
If CreateMenu(#Menu, WindowID(0))
  MenuTitle("Программа")    
  MenuItem(#Menu_Stop, "Стоп")
  MenuItem(#Menu_Start, "Старт")
  MenuBar()
  MenuItem(#Menu_exit, "Выключить")
  MenuTitle("Настройки")
  MenuItem(#Menu_Device, "Сменить устройство")
EndIf
 
 
 
;------------------------------------------------------------------------------------------------------------
 
 
 
 
If OpenLibrary(0, "AVICAP32.DLL")
  hWebcam = CallFunction(0, "capCreateCaptureWindowA", 0, #WS_VISIBLE + #WS_CHILD, 2, 10, width, height, hWnd, 0)
  Start(hWebcam)
 
  
  SendMessage_(hWebcam, #WM_CAP_GET_STATUS              , SizeOf(CAPSTATUS), CapStat)
  SendMessage_(hWebcam, #WM_CAP_SET_CALLBACK_FRAME      , 0 , @FrameCallback())
  widthImg  = CapStat\uiImageWidth
  heightImg = CapStat\uiImageHeight
  ReDim B(widthImg, heightImg)
  ReDim C(widthImg, heightImg)
  
  
  
  
;------------------------------------------------------------------------------------------------------------
  
  
 
Repeat
  
  Event = WindowEvent()
  Select Event
      
    Case #PB_Event_CloseWindow
      Break
      
    Case #PB_Event_Menu
      Select EventMenu()
          
        Case #Menu_exit
          Break
          
        Case #Menu_Start
          Start(hWebcam)
          
        Case #Menu_Stop
          Stop(hWebcam)
  
        Case #Menu_Device
          SendMessage_(hWebcam, #WM_CAP_DLG_VIDEOSOURCE, 0, 0)
          
      EndSelect
      
  EndSelect
ForEver
  
  
  
  
;------------------------------------------------------------------------------------------------------------
 
 
 
Stop(hWebcam)
CloseWindow(0)
CloseLibrary(0)
 
EndIf
 
End
0
Модератор
6478 / 2523 / 489
Регистрация: 24.04.2011
Сообщений: 4,604
Записей в блоге: 10
15.08.2012, 22:33 3
Цитата Сообщение от ЦарьКащей Посмотреть сообщение
Как я понял эта процедура для обработки кадра перед выводом в окно.
Я же тебе в другой теме написал, что надо данные записывать в Image, и уже с ним все манипуляции выполнять и его же отображать для контроля, а не то что с камеры идет - тут она что видит, то и отображает!
PureBasic
1
2
3
4
5
6
7
8
9
StartDrawing(ImageOutput(img1))
 
  For y = 240 - 1 To 0 Step -1
    For x = 0 To 320 - 1
      Plot(x, y, RGB(*VideoMemoryAdress1\r & $FF, *VideoMemoryAdress1\g & $FF, *VideoMemoryAdress1\b & $FF))
      *VideoMemoryAdress1 + 3
    Next
  Next
   StopDrawing()
Ты же когда из буфера обмена изображение брал, ты его в Image копировал, ну а тут почему думал, что по другому?
1
Ты за кого меня держиш!?
22 / 23 / 7
Регистрация: 26.10.2011
Сообщений: 308
Записей в блоге: 1
15.08.2012, 22:48  [ТС] 4
Цитата Сообщение от Pro_grammer Посмотреть сообщение
Я же тебе в другой теме написал, что надо данные записывать в Image, и уже с ним все манипуляции выполнять и его же отображать для контроля, а не то что с камеры идет - тут она что видит, то и отображает!
PureBasic
1
2
3
4
5
6
7
8
9
StartDrawing(ImageOutput(img1))
 
  For y = 240 - 1 To 0 Step -1
    For x = 0 To 320 - 1
      Plot(x, y, RGB(*VideoMemoryAdress1\r & $FF, *VideoMemoryAdress1\g & $FF, *VideoMemoryAdress1\b & $FF))
      *VideoMemoryAdress1 + 3
    Next
  Next
   StopDrawing()
Ты же когда из буфера обмена изображение брал, ты его в Image копировал, ну а тут почему думал, что по другому?
Цитирую:
The capture window calls the callback function before displaying preview frames. This allows an application to modify the frame if desired. This callback function is not used during streaming video capture.
http://msdn.microsoft.com/en-u... s.85).aspx
Что переводится как: Окно видеозахвата вызывает функцию обратного вызова для предварительного просмотра кадров. Это позволяет приложению при необходимости изменять кадр. Эта функция обратного вызова не используется во время захвата потокового видео.

По этому и думал что можно не вынимая кадр из памяти его изменить перед выводом на екран. Но ето даже не главное. Цикл то должен бы начаться или как? Если не идёт цикл для следующих неправильных манипуляций, то и для правильных наверно не пойдёт? А не идёт он я подозреваю по тому что widthImg и heightImg равны 0. А значит не вынимается значение из структуры CAPSTATUS и ошибки я не вижу. Будьте так любезны, ткните носом.
0
2677 / 1196 / 160
Регистрация: 28.10.2011
Сообщений: 4,298
Записей в блоге: 6
15.08.2012, 22:58 5
Цитата Сообщение от ЦарьКащей Посмотреть сообщение
я подозреваю по тому что widthImg и heightImg равны 0
А что по этому поводу "думает" отладчик?
0
Ты за кого меня держиш!?
22 / 23 / 7
Регистрация: 26.10.2011
Сообщений: 308
Записей в блоге: 1
15.08.2012, 23:01  [ТС] 6
Цитата Сообщение от locm Посмотреть сообщение
А что по этому поводу "думает" отладчик?
Подтверждает подозрения. Или ты чтото другое хотел прочесть?
0
Модератор
6478 / 2523 / 489
Регистрация: 24.04.2011
Сообщений: 4,604
Записей в блоге: 10
16.08.2012, 10:57 7
Цитата Сообщение от ЦарьКащей Посмотреть сообщение
Будьте так любезны, ткните носом.
А какой код конкретно ты запускаешь? А то я уже запутался...
Если тот, что в #2 то там полно ошибок - от забытых скобок, до неверного использования ReDim, исправлять нет желания, ну раз у тебя работает, то ты что то не то запостил?

Добавлено через 2 часа 24 минуты
В общем выдалась минутка, накидал код - детектор движения. Процедура сравнения изображений взята готовая, с английского форума. И работает вполне прилично, скорость обработки приемлемая.
Настраиваем чувствительность ползунком на неподвижном объекте ( на границе естественных шумов), а потом бегаем вокруг камеры, проверяем работу
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
WM_CAP_START = #WM_USER
#WM_CAP_SET_CALLBACK_ERROR = #WM_CAP_START + 2
#WM_CAP_SET_CALLBACK_STATUS = #WM_CAP_START + 3
#WM_CAP_SET_CALLBACK_YIELD = #WM_CAP_START + 4
#WM_CAP_SET_CALLBACK_FRAME = #WM_CAP_START + 5
#WM_CAP_SET_CALLBACK_VIDEOSTREAM = #WM_CAP_START + 6
#WM_CAP_SET_CALLBACK_WAVESTREAM = #WM_CAP_START + 7
 
#WM_CAP_DRIVER_CONNECT        =  #WM_USER + 10
#WM_CAP_DRIVER_DISCONNECT     =  #WM_USER + 11
#WM_CAP_DRIVER_GET_CAPS = #WM_CAP_START + 14
 
#WM_CAP_DLG_VIDEOFORMAT = #WM_CAP_START + 41
#WM_CAP_DLG_VIDEOSOURCE = #WM_CAP_START + 42
#WM_CAP_DLG_VIDEODISPLAY = #WM_CAP_START + 43
 
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52
#WM_CAP_GET_STATUS = #WM_CAP_START + 54
 
#WM_CAP_FILE_SAVEDIB          =  #WM_USER + 25
#WM_CAP_SET_SCALE             =  #WM_USER + 53
 
#WM_CAP_SET_CALLBACK_CAPCONTROL = #WM_CAP_START + 85
 
Structure CAPSTATUS 
  uiImageWidth.l 
  uiImageHeight.l 
  fLiveWindow.l 
  fOverlayWindow.l 
  fScale.l 
  ptScroll.Point 
  fUsingDefaultPalette.l 
  fAudioHardware.l 
  fCapFileExists.l 
  dwCurrentVideoFrame.l 
  dwCurrentVideoFramesDropped.l 
  dwCurrentWaveSamples.l 
  dwCurrentTimeElapsedMS.l 
  hPalCurrent.l 
  fCapturingNow.l 
  dwReturn.l 
  wNumVideoAllocated.l 
  wNumAudioAllocated.l 
EndStructure
 
CapStat.CAPSTATUS
 
Structure VIDEOHDR
  lpData.l
  dwBufferLength.l
  dwBytesUsed.l
  dwTimeCaptured.l
  dwUser.l
  dwFlags.l
  dwReserved.l[3]
EndStructure
 
Define *cp
 
OpenLibrary(1,"avicap32.dll"):*cp=GetFunction(1,"capCreateCaptureWindowW")
 
ExamineDesktops()
 
Structure SBGR
  b.b
  g.b
  r.b
EndStructure
 
Global img1=1,img2=2,hwnd ,hWebcam,gLow,gHigh,widthImg,heightImg,po=3
Global ev,GadgetID,EventType
 
Declare FrameCallback(hWnd.l, *lpVHdr.VIDEOHDR)
Declare compareIm(image_one, image_two, maxpercent = 100)
 
hWnd = OpenWindow(0, 0, 0, 640, 320, "Детектор движения", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
TrackBarGadget(3, 50, 245, 255, 30, 3, 100) : SetGadgetState(3,33)
TextGadget(5, 50, 285, 255, 20, "Чувствительность - " + Str(GetGadgetState(3)))
hWebcam= CallFunctionFast(*cp, @"My Capture Window", #WS_CHILD | #WS_VISIBLE, 0,0, 1 , 1, hWnd,0)
SendMessage_(hWebcam, #WM_CAP_DRIVER_CONNECT          , 0, 0)
SendMessage_(hWebcam, #WM_CAP_SET_SCALE               , 1, 0)
SendMessage_(hWebcam, #WM_CAP_SET_PREVIEWRATE         , 15, 0)
SendMessage_(hWebcam, #WM_CAP_SET_PREVIEW             , 0, 0)
 
SendMessage_(hWebcam, #WM_CAP_SET_CALLBACK_FRAME      , 0, @FrameCallback())
SendMessage_(hWebcam, #WM_CAP_GET_STATUS              , SizeOf(CAPSTATUS), CapStat)
widthImg  = CapStat\uiImageWidth
heightImg = CapStat\uiImageHeight
CreateImage(1, widthImg, heightImg)
CreateImage(2, widthImg, heightImg)
 
ImageGadget(1, 0, 0, widthImg, heightImg,ImageID(img1))
ImageGadget(4, widthImg+5, 0, widthImg, heightImg,0)
 
Repeat
 
ev = WaitWindowEvent(3)
 
GadgetID = EventGadget() 
   
EventType = EventType() 
                 
If Ev = #PB_Event_Gadget
         
    Select GadgetID
      Case 3
        po=GetGadgetState(3)
        SetGadgetText(5,"Чувствительность - " + Str(GetGadgetState(3)))
    EndSelect
EndIf     
Until ev = #PB_Event_CloseWindow Or GetAsyncKeyState_(#VK_ESCAPE) & $1
SendMessage_(hWebcam, #WM_CAP_SET_PREVIEW       , 0, 0)
SendMessage_(hWebcam, #WM_CAP_DRIVER_DISCONNECT, 0, 0)
CloseWindow(0)
CloseLibrary(0)
End
 
 
 
; **************************** Процедуры **********************************
 
Procedure FrameCallback(hWnd.l, *lpVHdr.VIDEOHDR)
 
  Protected *VideoMemoryAdress1.SBGR = *lpVHdr\lpData
  Protected y,x,rc.rect,ma,cx,cy,tc,mhigh
  StartDrawing(ImageOutput(img1))
 
  For y = heightImg - 1 To 0 Step -1
    For x = 0 To widthImg - 1
      Plot(x, y, RGB(*VideoMemoryAdress1\r & $FF, *VideoMemoryAdress1\g & $FF, *VideoMemoryAdress1\b & $FF))
      *VideoMemoryAdress1 + 3
    Next
  Next
 
  StopDrawing()
  If compareIm( img1, img2 ,po)= #True
                Debug "No motion"
                 Else
                   Debug "Motion detected"
                   Beep_(1000,50)
  EndIf
  
    CopyImage(img1, img2)
             
  SetGadgetState(1,ImageID(img1))
 
 
EndProcedure
 
Procedure compareIm(image_one, image_two, maxpercent = 100)
  cur_image = image_one
  Repeat
    If StartDrawing(ImageOutput(cur_image))
      wid = ImageWidth(cur_image)
      hei = ImageHeight(cur_image)
      If cur_image = image_two
        Dim pixels_image_two(wid - 1, hei - 1)
      ElseIf cur_image = image_one
        Dim pixels_image_one(wid - 1, hei - 1)
      EndIf
      For hei_temp = 0 To hei - 1 Step 1
        For wid_temp = 0 To wid - 1 Step 1
          color = Point(wid_temp, hei_temp)
          If cur_image = image_two
            pixels_image_two(wid_temp, hei_temp) = color
          ElseIf cur_image = image_one
            pixels_image_one(wid_temp, hei_temp) = color
          EndIf
        Next
      Next
    StopDrawing()
    EndIf
    ;FreeImage(cur_image)
    If cur_image = image_two
      Break
    ElseIf cur_image = image_one
      cur_image = image_two
    EndIf
  ForEver
 
  If ArraySize(pixels_image_one()) = ArraySize(pixels_image_two())
    If CreateImage(100, wid, hei) And StartDrawing(ImageOutput(100))
      For hei_temp = 1 To hei - 1 Step 1
        For wid_temp = 1 To wid - 1 Step 1
          If pixels_image_one(wid_temp, hei_temp) = pixels_image_two(wid_temp, hei_temp)
            counter + 1
          Else
            Plot(wid_temp, hei_temp, RGB(255, 100, 0))
          EndIf
        Next
      Next
      StopDrawing()
      SetGadgetState(4,ImageID(100))
    EndIf
    percent.f = hei * wid / 100
    ;Debug counter / percent.f
    If counter / percent.f >= maxpercent
      ProcedureReturn 1
    EndIf
  EndIf
EndProcedure
 
; **********************************************************************************
P.S.
Сразу предупреждаю - это не готовая программа, а просто рабочий код, который выполняет поставленную задачу. А т.к. был собран из разных источников, то возможно лишние переменные, константы, куски кода, утечка памяти и т.п. ляпусы. Проверен на версиях PureBasic 4.51 и выше, WinXP.
Копирайта нет, разрешаю использовать в коммерческих целях без отчислений
0
Ты за кого меня держиш!?
22 / 23 / 7
Регистрация: 26.10.2011
Сообщений: 308
Записей в блоге: 1
16.08.2012, 18:43  [ТС] 8
Цитата Сообщение от Pro_grammer Посмотреть сообщение
А какой код конкретно ты запускаешь? А то я уже запутался...
Если тот, что в #2 то там полно ошибок - от забытых скобок, до неверного использования ReDim, исправлять нет желания, ну раз у тебя работает, то ты что то не то запостил?

Добавлено через 2 часа 24 минуты
В общем выдалась минутка, накидал код - детектор движения. Процедура сравнения изображений взята готовая, с английского форума. И работает вполне прилично, скорость обработки приемлемая.
Настраиваем чувствительность ползунком на неподвижном объекте ( на границе естественных шумов), а потом бегаем вокруг камеры, проверяем работу

P.S.
Сразу предупреждаю - это не готовая программа, а просто рабочий код, который выполняет поставленную задачу. А т.к. был собран из разных источников, то возможно лишние переменные, константы, куски кода, утечка памяти и т.п. ляпусы. Проверен на версиях PureBasic 4.51 и выше, WinXP.
Копирайта нет, разрешаю использовать в коммерческих целях без отчислений
Какой код - я сам запутался, он постоянно меняется.
Не готовая программа - пофиг, главное есть материал для разбора. Где ты его искал я фиг знает, сам ненашёл ничего, а казалось бы константы то везде одинаковые.

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

Добавлено через 20 минут
Вот что значит разница между х86 и х64. На 64 битном компиляторе не работает, а на 32-х работает изъятие размеров получаемого изображения.
0
Модератор
6478 / 2523 / 489
Регистрация: 24.04.2011
Сообщений: 4,604
Записей в блоге: 10
16.08.2012, 18:51 9
Цитата Сообщение от ЦарьКащей Посмотреть сообщение
Толи лыжи не едут, толи код не рабочий.
Я свои версии компилятора написал - 4.51 и 4.61. Работает одинаково хорошо в обоих. Ошибки, которые выдает компилятор напиши, просто интересно. Я могу и скомпилированную версию выложить, если у тебя не получается, а у меня так работает - фото экрана камерой, которая следит за экраном
0
Миниатюры
Обработка изображения с веб камеры на предмет движущихся объектов\изменившихся пикселей  
Модератор
6478 / 2523 / 489
Регистрация: 24.04.2011
Сообщений: 4,604
Записей в блоге: 10
16.08.2012, 18:53 10
Цитата Сообщение от ЦарьКащей Посмотреть сообщение
работает изъятие размеров получаемого изображения
Это как - изъятие? Не понял
0
Ты за кого меня держиш!?
22 / 23 / 7
Регистрация: 26.10.2011
Сообщений: 308
Записей в блоге: 1
16.08.2012, 18:58  [ТС] 11
Цитата Сообщение от Pro_grammer Посмотреть сообщение
Я свои версии компилятора написал - 4.51 и 4.61. Работает одинаково хорошо в обоих. Ошибки, которые выдает компилятор напиши, просто интересно. Я могу и скомпилированную версию выложить, если у тебя не получается, а у меня так работает - фото экрана камерой, которая следит за экраном
PureBasic
1
Plot(x, y, RGB(*VideoMemoryAdress1\r & $FF, *VideoMemoryAdress1\g & $FF, *VideoMemoryAdress1\b & $FF))
Эта строка ругается ошибкой доступа к памяти по адресу ******** в х86

PureBasic
1
CreateImage(1, widthImg, heightImg)
Говорит The specified "Height" is negative в х64
0
Модератор
6478 / 2523 / 489
Регистрация: 24.04.2011
Сообщений: 4,604
Записей в блоге: 10
16.08.2012, 18:59 12
Цитата Сообщение от ЦарьКащей Посмотреть сообщение
На 64 битном компиляторе не работает
А зачем тебе х64 компилятор? Мы работаем в пределах памяти х86, и нет ни какой необходимости в подобных извращениях!
0
Модератор
6478 / 2523 / 489
Регистрация: 24.04.2011
Сообщений: 4,604
Записей в блоге: 10
16.08.2012, 18:59 13
Если камера не подключена, то такое бывает - размеры естественно 0.
Или камера уже занята другим ус-вом. Это баг не кода а юзера!
0
Ты за кого меня держиш!?
22 / 23 / 7
Регистрация: 26.10.2011
Сообщений: 308
Записей в блоге: 1
16.08.2012, 19:00  [ТС] 14
Цитата Сообщение от Pro_grammer Посмотреть сообщение
А зачем тебе х64 компилятор? Мы работаем в пределах памяти х86, и нет ни какой необходимости в подобных извращениях!
А почему бы и нет? Острой необходимости не испытываю, но и разницы до сегодняшнего дня не видел.
0
Модератор
6478 / 2523 / 489
Регистрация: 24.04.2011
Сообщений: 4,604
Записей в блоге: 10
16.08.2012, 19:04 15
Цитата Сообщение от ЦарьКащей Посмотреть сообщение
А почему бы и нет?
Нет обратной совместимости, да и библиотека называется AVICAP32, если понял о чем я.
1
2677 / 1196 / 160
Регистрация: 28.10.2011
Сообщений: 4,298
Записей в блоге: 6
16.08.2012, 19:08 16
Цитата Сообщение от ЦарьКащей Посмотреть сообщение
Говорит The specified "Height" is negative в х64
ИМХО как минимум структуры нужно переписать с учетом того, что будет работать на x64 платформе и тогда ошибка должна пропасть.
1
Ты за кого меня держиш!?
22 / 23 / 7
Регистрация: 26.10.2011
Сообщений: 308
Записей в блоге: 1
16.08.2012, 19:19  [ТС] 17
А что с РеДим?

PureBasic
1
2
3
4
5
6
7
8
 Procedure Resizer          (*CapStat.CAPSTATUS)
   widthImg  = *CapStat\uiImageWidth
   heightImg = *CapStat\uiImageHeight
   ReDim B (widthImg, heightImg)
   ReDim C (widthImg, heightImg)
   Debug widthImg
   Debug heightImg
 EndProcedure
Примерно так пишется тут http://purebasic.ru/manual.php?id=1062&lng=rus

Компилятор тока пишет что: Только последнее изменение размерности массива может быть выбрано с РеДим.

Только в заблуждение вводит.
0
Модератор
6478 / 2523 / 489
Регистрация: 24.04.2011
Сообщений: 4,604
Записей в блоге: 10
16.08.2012, 19:30 18
Цитата Сообщение от locm Посмотреть сообщение
ИМХО как минимум структуры нужно переписать с учетом того, что будет работать на x64 платформе и тогда ошибка должна пропасть.
Сомневаюсь, что 32 разрядная DLL вдруг станет работать в х64 режиме!
0
Ты за кого меня держиш!?
22 / 23 / 7
Регистрация: 26.10.2011
Сообщений: 308
Записей в блоге: 1
16.08.2012, 19:30  [ТС] 19
Цитата Сообщение от Pro_grammer Посмотреть сообщение
Если камера не подключена, то такое бывает - размеры естественно 0.
Или камера уже занята другим ус-вом. Это баг не кода а юзера!
Я же не настолько юзер чтобы не отличать есть камера или нет, подключилась она или нет, занята она или нет и т.д. Там же (сайт msdn) написано что Тру возвращается функциями отвечающими за то или иное действие при успехе и Фалос при его отсутствии.
0
Модератор
6478 / 2523 / 489
Регистрация: 24.04.2011
Сообщений: 4,604
Записей в блоге: 10
16.08.2012, 19:31 20
Цитата Сообщение от ЦарьКащей Посмотреть сообщение
А что с РеДим?
Справку почитай, компилятор правильно пишет.

Если ключевое слово ReDim используется с многомерным массивом, изменить можно только последнее измерение
.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.08.2012, 19:31

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Захват изображения с веб-камеры
Привет всем! Накипело, много статеек пересмотрел как это сделать, везде свои касяки, т.к....

Захват изображения с веб камеры
Здравствуйте Я как начинающий программист, в начале своего обучения столкнулся с тем, что мне...

Захват видео изображения с веб-камеры
Возникли проблемы при создании массива в C#.В общем дело обстоит так: имеется захват видео...

Обработка кадров с веб камеры
Здрасти, задался вот таким вот вопросом: Дано два пятна определённого цвета, произвольного...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.