Skip to content

Commit 7e5630d

Browse files
authored
Initial upload
0 parents  commit 7e5630d

8 files changed

Lines changed: 613 additions & 0 deletions

WebCamGrabber.py

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
#!/usr/bin/env python
2+
3+
from threading import Thread, Lock
4+
import cv2
5+
import time
6+
RESOLUTION=(640,480) ## resolution of input video. this has to be dupported by your camera
7+
FPS=30 ## FPS of your camera
8+
DEVICE=0 ## device number of camera. use -1 to disable video
9+
10+
'''
11+
resolutions=[(640,360),(640,480),(800,600),(1280,720),(1280,960),(1920,1080)]
12+
vid = cv2.VideoCapture(0)
13+
vid.set(cv2.CAP_PROP_AUTO_EXPOSURE, 3)
14+
vid.set(cv2.CAP_PROP_FPS, 30)
15+
vid.set(cv2.CAP_PROP_FRAME_WIDTH,resolutions[2][0])
16+
vid.set(cv2.CAP_PROP_FRAME_HEIGHT,resolutions[2][1])
17+
vid.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"MJPG"))
18+
t=time.perf_counter()
19+
f=0
20+
while True:
21+
ret, frame = vid.read()
22+
cv2.imshow('frame', frame)
23+
f+=1
24+
if time.perf_counter()>t+1.0:
25+
t=time.perf_counter()
26+
print("fps : ", f)
27+
f=0
28+
if cv2.waitKey(1) & 0xFF == ord('q'):
29+
break
30+
vid.release()
31+
cv2.destroyAllWindows()
32+
'''
33+
_USUAL_RESOLUTIONS=[
34+
(160, 120),
35+
(192, 144),
36+
(256, 144),
37+
(240, 160),
38+
(320, 240),
39+
(360, 240),
40+
(384, 240),
41+
(400, 240),
42+
(432, 240),
43+
(480, 320),
44+
(480, 360),
45+
(640, 360),
46+
(600, 480),
47+
(640, 480),
48+
(720, 480),
49+
(768, 480),
50+
(800, 480),
51+
(854, 480),
52+
(960, 480),
53+
(675, 540),
54+
(960, 540),
55+
(720, 576),
56+
(768, 576),
57+
(1024, 576),
58+
(750, 600),
59+
(800, 600),
60+
(800, 800),
61+
(1024, 600),
62+
(960, 640),
63+
(1024, 640),
64+
(1136, 640),
65+
(960, 720),
66+
(1152, 720),
67+
(1280, 720),
68+
(1440, 720),
69+
(960, 768),
70+
(1024, 768),
71+
(1152, 768),
72+
(1280, 768),
73+
(1366, 768),
74+
(1280, 800),
75+
(1152, 864),
76+
(1280, 864),
77+
(1536, 864),
78+
(1200, 900),
79+
(1440, 900),
80+
(1600, 900),
81+
(1280, 960),
82+
(1440, 960),
83+
(1536, 960),
84+
(1280, 1024),
85+
(1600, 1024),
86+
(1400, 1050),
87+
(1680, 1050),
88+
(1440, 1080),
89+
(1920, 1080),
90+
(2160, 1080),
91+
(2280, 1080),
92+
(2560, 1080),
93+
(2048, 1152),
94+
(1500, 1200),
95+
(1600, 1200),
96+
(1920, 1200),
97+
(1920, 1280),
98+
(2048, 1280),
99+
(1920, 1440),
100+
(2160, 1440),
101+
(2304, 1440),
102+
(2560, 1440),
103+
(2880, 1440),
104+
(2960, 1440),
105+
(3040, 1440),
106+
(3120, 1440),
107+
(3200, 1440),
108+
(3440, 1440),
109+
(5120, 1440),
110+
(2048, 1536),
111+
(2400, 1600),
112+
(2560, 1600),
113+
(3840, 1600),
114+
(2880, 1620),
115+
(2880, 1800),
116+
(3200, 1800),
117+
(2560, 1920),
118+
(2880, 1920),
119+
(3072, 1920),
120+
(2560, 2048),
121+
(2732, 2048),
122+
(3200, 2048),
123+
(2880, 2160),
124+
(3240, 2160),
125+
(3840, 2160),
126+
(4320, 2160),
127+
(5120, 2160),
128+
(3200, 2400),
129+
(3840, 2400),
130+
(3840, 2560),
131+
(4096, 2560),
132+
(5120, 2880),
133+
(5760, 2880),
134+
(4096, 3072),
135+
(7680, 4320),
136+
(10240, 4320)
137+
]
138+
139+
def list_cam_resolutions(src):
140+
cap = cv2.VideoCapture(src)
141+
res=[]
142+
for r in _USUAL_RESOLUTIONS:
143+
cap.set(cv2.CAP_PROP_FRAME_WIDTH,r[0])
144+
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,r[1])
145+
w=cap.get(cv2.CAP_PROP_FRAME_WIDTH)
146+
h=cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
147+
if w==r[0] and h==r[1]:
148+
res.append((w,h))
149+
cap.release()
150+
return res
151+
152+
def list_cam_fps(src):
153+
cap = cv2.VideoCapture(src)
154+
res=[]
155+
for fps in [5,15,30,60]:
156+
cap.set(cv2.CAP_PROP_FPS,fps)
157+
if fps==cap.get(cv2.CAP_PROP_FPS):
158+
res.append(fps)
159+
cap.release()
160+
return res
161+
162+
class WebcamVideoStream :
163+
def __init__(self, src = 0, width = 640, height =480) :
164+
self.stream = cv2.VideoCapture(src)
165+
self.stream.set(cv2.CAP_PROP_AUTO_EXPOSURE, 3)
166+
self.stream.set(cv2.CAP_PROP_FPS, 30)
167+
self.stream.set(cv2.CAP_PROP_FRAME_WIDTH,width)
168+
self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT,height)
169+
self.stream.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"MJPG"))
170+
(self.grabbed, self.frame) = self.stream.read()
171+
self.started = False
172+
self.t=0
173+
self.fps=0
174+
self.framecnt=0
175+
self.writer=None
176+
self.recording=False
177+
self.read_lock = Lock()
178+
179+
def start(self) :
180+
if self.started :
181+
print("already started!!")
182+
return None
183+
self.started = True
184+
self.t=time.perf_counter()
185+
self.framecnt=0
186+
self.fps=0
187+
self.thread = Thread(target=self.update, args=())
188+
self.thread.start()
189+
return self
190+
191+
def update(self) :
192+
while self.started :
193+
grabbed=False
194+
(grabbed, frame) = self.stream.read()
195+
## grabbed, frames are local variables to the thread.
196+
## because we will now access / modify members in WebCamVideoStream,
197+
## that can also be modified outside the thread,
198+
## we need to lock to be sure no other modification occurs during that time
199+
self.read_lock.acquire()
200+
self.framecnt+=1
201+
if time.perf_counter()>self.t+1:
202+
self.framecnt=0
203+
self.fps=self.framecnt
204+
self.t=time.perf_counter()
205+
if self.recording and not self.writer is None:
206+
self.writer.write(frame)
207+
self.grabbed, self.frame = grabbed, frame
208+
self.read_lock.release()
209+
210+
def read(self,cvt=False) :
211+
self.read_lock.acquire()
212+
if cvt:
213+
frame = cv2.cvtColor(self.frame,cv2.COLOR_BGR2RGB)
214+
else:
215+
frame=self.frame.copy()
216+
grabbed=self.grabbed
217+
self.grabbed=False
218+
self.read_lock.release()
219+
return grabbed,frame
220+
221+
def startrecording(self,filename,fourcc='avc1'):
222+
self.read_lock.acquire()
223+
self.writer=cv2.VideoWriter(filename,cv2.CAP_FFMPEG,
224+
cv2.VideoWriter_fourcc(*fourcc),
225+
self.stream.get(cv2.CAP_PROP_FPS),
226+
(int(self.stream.get(cv2.CAP_PROP_FRAME_WIDTH)),int(self.stream.get(cv2.CAP_PROP_FRAME_HEIGHT)))
227+
)
228+
self.recording=True
229+
self.read_lock.release()
230+
231+
def stoprecording(self):
232+
self.read_lock.acquire()
233+
if self.recording:
234+
self.recording=False
235+
self.writer.release()
236+
self.read_lock.release()
237+
238+
def stop(self) :
239+
self.started = False
240+
self.thread.join()
241+
242+
def __exit__(self, exc_type, exc_value, traceback) :
243+
if not self.writer is None:
244+
self.writer.release()
245+
self.stream.release()
246+
247+
if __name__ == "__main__" :
248+
print("Checking supported webcam resolutions...")
249+
print(list_cam_resolutions(2))
250+
print(list_cam_fps(2))
251+
instream = WebcamVideoStream(2).start()
252+
while True :
253+
got,frame = instream.read()
254+
if got:
255+
cv2.imshow('webcam', frame)
256+
k=cv2.waitKey(1)
257+
if k==27:
258+
break
259+
elif k==ord(' ') and not instream.recording:
260+
instream.startrecording("test.mts",fourcc='avc1')
261+
elif k==ord(' ') and instream.recording:
262+
instream.stoprecording()
263+
264+
instream.stop()
265+
cv2.destroyAllWindows()

openh264-1.8.0-win32.dll

682 KB
Binary file not shown.

openh264-1.8.0-win64.dll

806 KB
Binary file not shown.

params.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
##############################################################################
2+
## Tapetest options. time units in seconds
3+
X_SCALE_WIDTH=10 ## scale of x axis
4+
DEBOUNCE=0.01 ## key debounce delay. on windows, you may need to increase this delay (0.05 - 0.1)
5+
TIMEOUT=10*60 ## timeout to stop recordings
6+
LINEWIDTH=30 ## line width
7+
RIGHTCOLOR='g' ## green is fantastic!
8+
LEFTCOLOR='r' ## red is even nicer!
9+
FILENAMETEMPLATE='mouse_xx_wt_wt_{date}' ## {date} will be replaced by current date & time
10+
## key bindings. some people may use qwerty keyboards or something else
11+
KEYLEFT='a'
12+
KEYRIGHT='p'
13+
KEYSTART=' '
14+
KEYSAVE='s'
15+
KEYZOOMIN='+'
16+
KEYZOOMOUT='-'
17+
## video recordings options
18+
CAMERA=-1 ## which camera to use. use any negative number to disable synchronous video recordings
19+
RESOLUTION=(640,480) ## camera resolution. The software will not check if resolution is supported!
20+
VIDFOURCC='avc1' ## video codec for video compression
21+
VIDCONTAINER='.mts' ## video container for video storage

scripts/generate_win_binary.bat

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@echo off
2+
cd ..
3+
del /s /q /f *.pyc
4+
SET TARGET=tapetest
5+
pyinstaller.exe --clean ^
6+
-p ./modules/ ^
7+
--additional-hooks-dir=hooks ^
8+
--exclude-module FixTk ^
9+
--exclude-module tcl ^
10+
--exclude-module _tkinter ^
11+
--exclude-module tkinter ^
12+
--exclude-module Tkinter ^
13+
--exclude-module tk ^
14+
--exclude-module win32com ^
15+
--exclude-module pywin32 ^
16+
--exclude-module pubsub ^
17+
--exclude-module smokesignal ^
18+
--exclude tornado ^
19+
--exclude jedi ^
20+
--exclude numba ^
21+
%TARGET%.py
22+
xcopy /e /Y /i openh264-1.8.0-win32.dll dist\tapetest\
23+
xcopy /e /Y /i openh264-1.8.0-win64.dll dist\tapetest\
24+
xcopy /e /Y /i params.py dist\
25+
xcopy /e /Y /i scripts\tapetest.bat dist\
26+
pause

scripts/tapetest.bat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@echo on
2+
chdir tapetest
3+
tapetest.exe

0 commit comments

Comments
 (0)