1818# along with BerryNet. If not, see <http://www.gnu.org/licenses/>.
1919
2020import argparse
21+ import logging
2122import time
2223
2324from 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
6481def 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