Skip to content

Commit 0153652

Browse files
committed
Support video stream as input to camera.py
Signed-off-by: Bofu Chen (bafu) <bofu@dt42.io>
1 parent 99bf785 commit 0153652

File tree

1 file changed

+72
-8
lines changed

1 file changed

+72
-8
lines changed

berrynet/client/camera.py

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
# along with BerryNet. If not, see <http://www.gnu.org/licenses/>.
1919

2020
import argparse
21+
import logging
2122
import time
2223

2324
from datetime import datetime
@@ -36,6 +37,13 @@ def parse_args():
3637
default='stream',
3738
help='Camera creates frame(s) from stream or file. (default: stream)'
3839
)
40+
ap.add_argument(
41+
'--stream-src',
42+
default=0,
43+
help=('Camera stream source. '
44+
'It can be device node ID or RTSP URL. '
45+
'(default: 0)')
46+
)
3947
ap.add_argument(
4048
'--fps',
4149
type=float,
@@ -58,11 +66,24 @@ def parse_args():
5866
type=int,
5967
help='MQTT broker port.'
6068
)
69+
ap.add_argument('--display',
70+
action='store_true',
71+
help=('Open a window and display the sent out frames. '
72+
'This argument is only effective in stream mode.')
73+
)
74+
ap.add_argument('--debug',
75+
action='store_true',
76+
help='Debug mode toggle'
77+
)
6178
return vars(ap.parse_args())
6279

6380

6481
def main():
6582
args = parse_args()
83+
if args['debug']:
84+
logger.setLevel(logging.DEBUG)
85+
else:
86+
logger.setLevel(logging.INFO)
6687

6788
comm_config = {
6889
'subscribe': {},
@@ -77,19 +98,62 @@ def main():
7798

7899
if args['mode'] == 'stream':
79100
counter = 0
80-
capture = cv2.VideoCapture(0)
101+
# Check input stream source
102+
if args['stream_src'].isdigit():
103+
# source is a physically connected camera
104+
stream_source = '/dev/video{}'.format(int(args['stream_src']))
105+
capture = cv2.VideoCapture(int(args['stream_src']))
106+
else:
107+
# source is an IP camera
108+
stream_source = args['stream_src']
109+
capture = cv2.VideoCapture(args['stream_src'])
110+
cam_fps = capture.get(cv2.CAP_PROP_FPS)
111+
if cam_fps > 30 or cam_fps < 1:
112+
logger.warn('Camera FPS is {} (>30 or <1). Set it to 30.'.format(cam_fps))
113+
cam_fps = 30
114+
out_fps = args['fps']
115+
interval = int(cam_fps / out_fps)
116+
117+
# warmup
118+
#t_warmup_start = time.time()
119+
#t_warmup_now = time.time()
120+
#warmup_counter = 0
121+
#while t_warmup_now - t_warmup_start < 1:
122+
# capture.read()
123+
# warmup_counter += 1
124+
# t_warmup_now = time.time()
125+
126+
logger.debug('===== VideoCapture Information =====')
127+
logger.debug('Stream Source: {}'.format(stream_source))
128+
logger.debug('Camera FPS: {}'.format(cam_fps))
129+
logger.debug('Output FPS: {}'.format(out_fps))
130+
logger.debug('Interval: {}'.format(interval))
131+
#logger.debug('Warmup Counter: {}'.format(warmup_counter))
132+
logger.debug('====================================')
133+
81134
while True:
82135
status, im = capture.read()
83136
if (status is False):
84137
logger.warn('ERROR: Failure happened when reading frame')
85138

86-
t = datetime.now()
87-
retval, jpg_bytes = cv2.imencode('.jpg', im)
88-
mqtt_payload = payload.serialize_jpg(jpg_bytes)
89-
comm.send('berrynet/data/rgbimage', mqtt_payload)
90-
logger.debug('send: {} ms'.format(duration(t)))
91-
92-
time.sleep(1.0 / args['fps'])
139+
counter += 1
140+
if counter == interval:
141+
logger.debug('Drop frames: {}'.format(counter-1))
142+
counter = 0
143+
144+
# Open a window and display the ready-to-send frame.
145+
# This is useful for development and debugging.
146+
if args['display']:
147+
cv2.imshow('Frame', im)
148+
cv2.waitKey(1)
149+
150+
t = datetime.now()
151+
retval, jpg_bytes = cv2.imencode('.jpg', im)
152+
mqtt_payload = payload.serialize_jpg(jpg_bytes)
153+
comm.send('berrynet/data/rgbimage', mqtt_payload)
154+
logger.debug('send: {} ms'.format(duration(t)))
155+
else:
156+
pass
93157
elif args['mode'] == 'file':
94158
# Prepare MQTT payload
95159
im = cv2.imread(args['filepath'])

0 commit comments

Comments
 (0)