如何在命令行中接受多个参数并正确处理?
How can I accept multiple arguments in command line and process it correctly?
尝试通过命令行接受多个 RTSP 地址,但我一直失败。下面是我的输入:
python rtsp.py --rtsp --uri rtsp://admin:password@192.168.1.63:554 rtsp://admin:password@192.168.1.61:554 rtsp://admin:password@192.168.1.62:554
它没有像我想要的那样同时显示视频,而是在您关闭它们后一个一个地显示。
import sys
import argparse
import cv2
from multiprocessing import Process
WINDOW_NAME = 'Network Camera Demo'
def parse_args():
# Parse input arguments
desc = 'Capture and display live video feed'
parser = argparse.ArgumentParser(description=desc)
parser.add_argument('--rtsp', dest='use_rtsp',
help='use IP CAM (remember to also set --uri)',
action='store_true')
parser.add_argument('--uri', dest='rtsp_uri',
help='RTSP URI, e.g. rtsp://192.168.1.64:554',
default=None, type=str)
parser.add_argument('--latency', dest='rtsp_latency',
help='latency in ms for RTSP [200]',
default=25, type=int)
parser.add_argument('--width', dest='image_width',
help='image width [1920]',
default=1920, type=int)
parser.add_argument('--height', dest='image_height',
help='image height [1080]',
default=1080, type=int)
args = parser.parse_args()
return args
def open_cam_rtsp(uri, width, height, latency):
gst_str = ('rtspsrc location={} latency={} ! '
'rtph264depay ! h264parse ! omxh264dec ! '
'nvvidconv ! '
'video/x-raw, width=(int){}, height=(int){}, '
'format=(string)BGRx ! '
'videoconvert ! appsink').format(uri, latency, width, height)
return cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
def open_window(width, height):
cv2.namedWindow(WINDOW_NAME, cv2.WINDOW_NORMAL)
cv2.resizeWindow(WINDOW_NAME, width, height)
cv2.moveWindow(WINDOW_NAME, 0, 0)
cv2.setWindowTitle(WINDOW_NAME, 'Network Cam Demo')
def read_cam(cap):
show_help = True
full_scrn = False
help_text = '"Esc" to Quit, "H" for Help, "F" to Toggle Fullscreen'
font = cv2.FONT_HERSHEY_PLAIN
while True:
if cv2.getWindowProperty(WINDOW_NAME, 0) < 0:
# Check to see if the user has closed the window
# If yes, terminate the program
break
_, img = cap.read() # grab the next image frame from camera
if show_help:
cv2.putText(img, help_text, (11, 20), font,
1.0, (32, 32, 32), 4, cv2.LINE_AA)
cv2.putText(img, help_text, (10, 20), font,
1.0, (240, 240, 240), 1, cv2.LINE_AA)
cv2.imshow(WINDOW_NAME, img)
key = cv2.waitKey(10)
if key == 27: # ESC key: quit program
break
def main(rtsp_uri):
# args = parse_args()
print('Called with args:')
print(args)
print('OpenCV version: {}'.format(cv2.__version__))
cap = open_cam_rtsp(rtsp_uri,
args.image_width,
args.image_height,
args.rtsp_latency)
if not cap.isOpened():
sys.exit('Failed to open camera!')
open_window(args.image_width, args.image_height)
read_cam(cap)
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
args = parse_args()
for rtsp_uri in args.rtsp_uri:
process = Process(target=main, args=(rtsp_uri))
process.start()
process.join()
我有点卡在如何让它真正接受多个参数,比如某些框架,例如
gst-launch-1.0 rtspsrc location=rtsp://admin:password@192.168.1.61 ! rtph264depay ! h264parse ! omxh264dec ! nvvidconv ! videoconvert ! appsink
rtspsrc location=rtsp://admin:password@192.168.1.62 ! rtph264depay ! h264parse ! omxh264dec ! nvvidconv ! videoconvert ! appsink
编辑:在 Right Leg 的帮助下,我设法解决了我的代码中存在的问题,该问题是由于误解了进程在多处理中的实际工作方式。
出于某些奇怪的原因,必须使用 action=append
和 nargs='+
才能从命令行接受多个参数。
最终代码如下图:
parser.add_argument('--uri', dest='rtsp_uri', action='append'
help='RTSP URI, e.g. rtsp://192.168.1.64:554',
default=None, type=str, nargs='+')
...
if __name__ == '__main__':
args = parse_args()
processes = []
for args.rtsp_uri in args.rtsp_uri:
process = Process(target=main, args=(args.rtsp_uri))
processes.append(process)
process.start()
for process in processes:
process.join()
在您的 main 中,对于每个 url,您创建一个进程,启动它,然后加入它。
if __name__ == '__main__':
args = parse_args()
for rtsp_uri in args.rtsp_uri:
process = Process(target=main, args=(rtsp_uri))
process.start()
process.join()
问题是 Process.join
等待进程结束。
结果,流程被创建、启动,因此 运行 顺序进行:只有当一个流程结束后,下一个流程才会开始。
您需要启动所有进程,然后才加入它们:
if __name__ == '__main__':
args = parse_args()
processes = []
for rtsp_uri in args.rtsp_uri:
process = Process(target=main, args=(rtsp_uri))
processes.append(process)
process.start()
for process in processes:
process.join()
尝试通过命令行接受多个 RTSP 地址,但我一直失败。下面是我的输入:
python rtsp.py --rtsp --uri rtsp://admin:password@192.168.1.63:554 rtsp://admin:password@192.168.1.61:554 rtsp://admin:password@192.168.1.62:554
它没有像我想要的那样同时显示视频,而是在您关闭它们后一个一个地显示。
import sys
import argparse
import cv2
from multiprocessing import Process
WINDOW_NAME = 'Network Camera Demo'
def parse_args():
# Parse input arguments
desc = 'Capture and display live video feed'
parser = argparse.ArgumentParser(description=desc)
parser.add_argument('--rtsp', dest='use_rtsp',
help='use IP CAM (remember to also set --uri)',
action='store_true')
parser.add_argument('--uri', dest='rtsp_uri',
help='RTSP URI, e.g. rtsp://192.168.1.64:554',
default=None, type=str)
parser.add_argument('--latency', dest='rtsp_latency',
help='latency in ms for RTSP [200]',
default=25, type=int)
parser.add_argument('--width', dest='image_width',
help='image width [1920]',
default=1920, type=int)
parser.add_argument('--height', dest='image_height',
help='image height [1080]',
default=1080, type=int)
args = parser.parse_args()
return args
def open_cam_rtsp(uri, width, height, latency):
gst_str = ('rtspsrc location={} latency={} ! '
'rtph264depay ! h264parse ! omxh264dec ! '
'nvvidconv ! '
'video/x-raw, width=(int){}, height=(int){}, '
'format=(string)BGRx ! '
'videoconvert ! appsink').format(uri, latency, width, height)
return cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
def open_window(width, height):
cv2.namedWindow(WINDOW_NAME, cv2.WINDOW_NORMAL)
cv2.resizeWindow(WINDOW_NAME, width, height)
cv2.moveWindow(WINDOW_NAME, 0, 0)
cv2.setWindowTitle(WINDOW_NAME, 'Network Cam Demo')
def read_cam(cap):
show_help = True
full_scrn = False
help_text = '"Esc" to Quit, "H" for Help, "F" to Toggle Fullscreen'
font = cv2.FONT_HERSHEY_PLAIN
while True:
if cv2.getWindowProperty(WINDOW_NAME, 0) < 0:
# Check to see if the user has closed the window
# If yes, terminate the program
break
_, img = cap.read() # grab the next image frame from camera
if show_help:
cv2.putText(img, help_text, (11, 20), font,
1.0, (32, 32, 32), 4, cv2.LINE_AA)
cv2.putText(img, help_text, (10, 20), font,
1.0, (240, 240, 240), 1, cv2.LINE_AA)
cv2.imshow(WINDOW_NAME, img)
key = cv2.waitKey(10)
if key == 27: # ESC key: quit program
break
def main(rtsp_uri):
# args = parse_args()
print('Called with args:')
print(args)
print('OpenCV version: {}'.format(cv2.__version__))
cap = open_cam_rtsp(rtsp_uri,
args.image_width,
args.image_height,
args.rtsp_latency)
if not cap.isOpened():
sys.exit('Failed to open camera!')
open_window(args.image_width, args.image_height)
read_cam(cap)
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
args = parse_args()
for rtsp_uri in args.rtsp_uri:
process = Process(target=main, args=(rtsp_uri))
process.start()
process.join()
我有点卡在如何让它真正接受多个参数,比如某些框架,例如
gst-launch-1.0 rtspsrc location=rtsp://admin:password@192.168.1.61 ! rtph264depay ! h264parse ! omxh264dec ! nvvidconv ! videoconvert ! appsink
rtspsrc location=rtsp://admin:password@192.168.1.62 ! rtph264depay ! h264parse ! omxh264dec ! nvvidconv ! videoconvert ! appsink
编辑:在 Right Leg 的帮助下,我设法解决了我的代码中存在的问题,该问题是由于误解了进程在多处理中的实际工作方式。
出于某些奇怪的原因,必须使用 action=append
和 nargs='+
才能从命令行接受多个参数。
最终代码如下图:
parser.add_argument('--uri', dest='rtsp_uri', action='append'
help='RTSP URI, e.g. rtsp://192.168.1.64:554',
default=None, type=str, nargs='+')
...
if __name__ == '__main__':
args = parse_args()
processes = []
for args.rtsp_uri in args.rtsp_uri:
process = Process(target=main, args=(args.rtsp_uri))
processes.append(process)
process.start()
for process in processes:
process.join()
在您的 main 中,对于每个 url,您创建一个进程,启动它,然后加入它。
if __name__ == '__main__':
args = parse_args()
for rtsp_uri in args.rtsp_uri:
process = Process(target=main, args=(rtsp_uri))
process.start()
process.join()
问题是 Process.join
等待进程结束。
结果,流程被创建、启动,因此 运行 顺序进行:只有当一个流程结束后,下一个流程才会开始。
您需要启动所有进程,然后才加入它们:
if __name__ == '__main__':
args = parse_args()
processes = []
for rtsp_uri in args.rtsp_uri:
process = Process(target=main, args=(rtsp_uri))
processes.append(process)
process.start()
for process in processes:
process.join()