From 3745f7dea048fca00d72a95ee942f97383843e24 Mon Sep 17 00:00:00 2001 From: irvingzhang0512 Date: Fri, 5 Nov 2021 14:43:23 +0800 Subject: [PATCH 1/5] First commit for video demo --- demo/video_demo.py | 109 ++++++++++++++++++++++++++++++++++++++++++++ docs/get_started.md | 52 +++++++++++++-------- 2 files changed, 143 insertions(+), 18 deletions(-) create mode 100644 demo/video_demo.py diff --git a/demo/video_demo.py b/demo/video_demo.py new file mode 100644 index 0000000000..c7ef219935 --- /dev/null +++ b/demo/video_demo.py @@ -0,0 +1,109 @@ +from argparse import ArgumentParser + +from mmseg.apis import inference_segmentor, init_segmentor +from mmseg.core.evaluation import get_palette +import cv2 + + +def main(): + parser = ArgumentParser() + parser.add_argument('video', help='Video file or webcam id') + parser.add_argument('config', help='Config file') + parser.add_argument('checkpoint', help='Checkpoint file') + parser.add_argument( + '--device', default='cuda:0', help='Device used for inference') + parser.add_argument( + '--palette', + default='cityscapes', + help='Color palette used for segmentation map') + parser.add_argument( + '--show', action="store_true", help="Whether to show draw result") + parser.add_argument( + '--show-wait-time', default=1, type=int, help='Wait time after imshow') + parser.add_argument( + '--output-file', default=None, type=str, help='Output video file path') + parser.add_argument( + '--output-fourcc', + default='MJPG', + type=str, + help='Fourcc of the output video') + parser.add_argument( + '--output-fps', default=-1, type=int, help='FPS of the output video') + parser.add_argument( + '--output-height', + default=-1, + type=int, + help='Frame height of the output video') + parser.add_argument( + '--output-width', + default=-1, + type=int, + help='Frame width of the output video') + parser.add_argument( + '--opacity', + type=float, + default=0.5, + help='Opacity of painted segmentation map. In (0, 1] range.') + args = parser.parse_args() + + assert args.show or args.output_file, 'At least one output should be enabled.' + + # build the model from a config file and a checkpoint file + model = init_segmentor(args.config, args.checkpoint, device=args.device) + + # build input video + cap = cv2.VideoCapture(args.video) + assert (cap.isOpened()) + input_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) + input_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) + input_fps = cap.get(cv2.CAP_PROP_FPS) + + # init output video + writer = None + output_height = None + output_width = None + if args.output_file is not None: + fourcc = cv2.VideoWriter_fourcc(*args.output_fourcc) + output_fps = args.output_fps if args.output_fps > 0 else input_fps + output_height = args.output_height if args.output_height > 0 else int( + input_height) + output_width = args.output_width if args.output_width > 0 else int( + input_width) + print(args.output_file, fourcc, output_fps, output_width, + output_height) + writer = cv2.VideoWriter(args.output_file, fourcc, output_fps, + (output_width, output_height), True) + + # start looping + while True: + flag, frame = cap.read() + if not flag: + break + + # test a single image + result = inference_segmentor(model, frame) + + # blend raw image and prediction + draw_img = model.show_result( + frame, + result, + palette=get_palette(args.palette), + show=False, + opacity=args.opacity) + + if args.show: + cv2.imshow("video_demo", draw_img) + cv2.waitKey(args.show_wait_time) + if writer: + if draw_img.shape[0] != output_height or draw_img.shape[ + 1] != output_width: + draw_img = cv2.resize(draw_img, (output_width, output_height)) + writer.write(draw_img) + + if writer: + writer.release() + cap.release() + + +if __name__ == '__main__': + main() diff --git a/docs/get_started.md b/docs/get_started.md index 0aceb37587..81853d1882 100644 --- a/docs/get_started.md +++ b/docs/get_started.md @@ -9,24 +9,24 @@ The compatible MMSegmentation and MMCV versions are as below. Please install the correct version of MMCV to avoid installation issues. -| MMSegmentation version | MMCV version | -|:-------------------:|:-------------------:| -| master | mmcv-full>=1.3.13, <1.4.0 | -| 0.19.0 | mmcv-full>=1.3.13, <1.4.0 | -| 0.18.0 | mmcv-full>=1.3.13, <1.4.0 | -| 0.17.0 | mmcv-full>=1.3.7, <1.4.0 | -| 0.16.0 | mmcv-full>=1.3.7, <1.4.0 | -| 0.15.0 | mmcv-full>=1.3.7, <1.4.0 | -| 0.14.1 | mmcv-full>=1.3.7, <1.4.0 | -| 0.14.0 | mmcv-full>=1.3.1, <1.3.2 | -| 0.13.0 | mmcv-full>=1.3.1, <1.3.2 | -| 0.12.0 | mmcv-full>=1.1.4, <1.3.2 | -| 0.11.0 | mmcv-full>=1.1.4, <1.3.0 | -| 0.10.0 | mmcv-full>=1.1.4, <1.3.0 | -| 0.9.0 | mmcv-full>=1.1.4, <1.3.0 | -| 0.8.0 | mmcv-full>=1.1.4, <1.2.0 | -| 0.7.0 | mmcv-full>=1.1.2, <1.2.0 | -| 0.6.0 | mmcv-full>=1.1.2, <1.2.0 | +| MMSegmentation version | MMCV version | +| :--------------------: | :-----------------------: | +| master | mmcv-full>=1.3.13, <1.4.0 | +| 0.19.0 | mmcv-full>=1.3.13, <1.4.0 | +| 0.18.0 | mmcv-full>=1.3.13, <1.4.0 | +| 0.17.0 | mmcv-full>=1.3.7, <1.4.0 | +| 0.16.0 | mmcv-full>=1.3.7, <1.4.0 | +| 0.15.0 | mmcv-full>=1.3.7, <1.4.0 | +| 0.14.1 | mmcv-full>=1.3.7, <1.4.0 | +| 0.14.0 | mmcv-full>=1.3.1, <1.3.2 | +| 0.13.0 | mmcv-full>=1.3.1, <1.3.2 | +| 0.12.0 | mmcv-full>=1.1.4, <1.3.2 | +| 0.11.0 | mmcv-full>=1.1.4, <1.3.0 | +| 0.10.0 | mmcv-full>=1.1.4, <1.3.0 | +| 0.9.0 | mmcv-full>=1.1.4, <1.3.0 | +| 0.8.0 | mmcv-full>=1.1.4, <1.2.0 | +| 0.7.0 | mmcv-full>=1.1.2, <1.2.0 | +| 0.6.0 | mmcv-full>=1.1.2, <1.2.0 | :::{note} You need to run `pip uninstall mmcv` first if you have mmcv installed. @@ -216,3 +216,19 @@ python demo/image_demo.py demo/demo.jpg configs/pspnet/pspnet_r50-d8_512x1024_40 ``` A notebook demo can be found in [demo/inference_demo.ipynb](../demo/inference_demo.ipynb). + +Now we also provide a demo script to test a single video. + +```shell +python demo/video_demo.py ${VIDEO_FILE} ${CONFIG_FILE} ${CHECKPOINT_FILE} [--device ${DEVICE_NAME}] [--palette-thr ${PALETTE}] \ + [--show] [--show-wait-time {SHOW_WAIT_TIME}] [--output-file {OUTPUT_FILE}] [--output-fps {OUTPUT_FPS}] \ + [--output-height {OUTPUT_HEIGHT}] [--output-width {OUTPUT_WIDTH}] [--opacity {OPACITY}] +``` + +Examples: + +```shell +python demo/video_demo.py demo/demo.mp4 configs/cgnet/cgnet_680x680_60k_cityscapes.py \ + checkpoints/cgnet_680x680_60k_cityscapes_20201101_110253-4c0b2f2d.pth \ + --device cuda:0 --palette cityscapes --show +``` From 561beb59bc0c53a710d37aba4a2ce58d8739fa3f Mon Sep 17 00:00:00 2001 From: irvingzhang0512 Date: Fri, 5 Nov 2021 15:21:26 +0800 Subject: [PATCH 2/5] fix lint --- demo/video_demo.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/demo/video_demo.py b/demo/video_demo.py index c7ef219935..0e602d0395 100644 --- a/demo/video_demo.py +++ b/demo/video_demo.py @@ -1,8 +1,9 @@ from argparse import ArgumentParser +import cv2 + from mmseg.apis import inference_segmentor, init_segmentor from mmseg.core.evaluation import get_palette -import cv2 def main(): @@ -17,7 +18,7 @@ def main(): default='cityscapes', help='Color palette used for segmentation map') parser.add_argument( - '--show', action="store_true", help="Whether to show draw result") + '--show', action='store_true', help='Whether to show draw result') parser.add_argument( '--show-wait-time', default=1, type=int, help='Wait time after imshow') parser.add_argument( @@ -46,7 +47,8 @@ def main(): help='Opacity of painted segmentation map. In (0, 1] range.') args = parser.parse_args() - assert args.show or args.output_file, 'At least one output should be enabled.' + assert args.show or args.output_file, \ + 'At least one output should be enabled.' # build the model from a config file and a checkpoint file model = init_segmentor(args.config, args.checkpoint, device=args.device) @@ -92,7 +94,7 @@ def main(): opacity=args.opacity) if args.show: - cv2.imshow("video_demo", draw_img) + cv2.imshow('video_demo', draw_img) cv2.waitKey(args.show_wait_time) if writer: if draw_img.shape[0] != output_height or draw_img.shape[ From 9a5e8d575304ece33f823518cf5967d4c6cd2d29 Mon Sep 17 00:00:00 2001 From: irvingzhang0512 Date: Wed, 1 Dec 2021 17:55:29 +0800 Subject: [PATCH 3/5] update --- demo/video_demo.py | 52 ++++++++++++++++++++++----------------------- docs/get_started.md | 1 + 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/demo/video_demo.py b/demo/video_demo.py index 0e602d0395..acdb531b7a 100644 --- a/demo/video_demo.py +++ b/demo/video_demo.py @@ -71,40 +71,40 @@ def main(): input_height) output_width = args.output_width if args.output_width > 0 else int( input_width) - print(args.output_file, fourcc, output_fps, output_width, - output_height) writer = cv2.VideoWriter(args.output_file, fourcc, output_fps, (output_width, output_height), True) # start looping - while True: - flag, frame = cap.read() - if not flag: - break + try: + while True: + flag, frame = cap.read() + if not flag: + break - # test a single image - result = inference_segmentor(model, frame) + # test a single image + result = inference_segmentor(model, frame) - # blend raw image and prediction - draw_img = model.show_result( - frame, - result, - palette=get_palette(args.palette), - show=False, - opacity=args.opacity) + # blend raw image and prediction + draw_img = model.show_result( + frame, + result, + palette=get_palette(args.palette), + show=False, + opacity=args.opacity) - if args.show: - cv2.imshow('video_demo', draw_img) - cv2.waitKey(args.show_wait_time) + if args.show: + cv2.imshow('video_demo', draw_img) + cv2.waitKey(args.show_wait_time) + if writer: + if draw_img.shape[0] != output_height or draw_img.shape[ + 1] != output_width: + draw_img = cv2.resize(draw_img, + (output_width, output_height)) + writer.write(draw_img) + finally: if writer: - if draw_img.shape[0] != output_height or draw_img.shape[ - 1] != output_width: - draw_img = cv2.resize(draw_img, (output_width, output_height)) - writer.write(draw_img) - - if writer: - writer.release() - cap.release() + writer.release() + cap.release() if __name__ == '__main__': diff --git a/docs/get_started.md b/docs/get_started.md index 81853d1882..0594ae6170 100644 --- a/docs/get_started.md +++ b/docs/get_started.md @@ -228,6 +228,7 @@ python demo/video_demo.py ${VIDEO_FILE} ${CONFIG_FILE} ${CHECKPOINT_FILE} [--dev Examples: ```shell +# TODO: add mp4 link link `wget -P demo/ ` python demo/video_demo.py demo/demo.mp4 configs/cgnet/cgnet_680x680_60k_cityscapes.py \ checkpoints/cgnet_680x680_60k_cityscapes_20201101_110253-4c0b2f2d.pth \ --device cuda:0 --palette cityscapes --show From ccf1ea5ec80199603d99fa1667762cb469c01185 Mon Sep 17 00:00:00 2001 From: irvingzhang0512 Date: Thu, 2 Dec 2021 09:53:27 +0800 Subject: [PATCH 4/5] fix --- docs/get_started.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/get_started.md b/docs/get_started.md index 0594ae6170..0465594c9c 100644 --- a/docs/get_started.md +++ b/docs/get_started.md @@ -9,24 +9,24 @@ The compatible MMSegmentation and MMCV versions are as below. Please install the correct version of MMCV to avoid installation issues. -| MMSegmentation version | MMCV version | -| :--------------------: | :-----------------------: | -| master | mmcv-full>=1.3.13, <1.4.0 | -| 0.19.0 | mmcv-full>=1.3.13, <1.4.0 | -| 0.18.0 | mmcv-full>=1.3.13, <1.4.0 | -| 0.17.0 | mmcv-full>=1.3.7, <1.4.0 | -| 0.16.0 | mmcv-full>=1.3.7, <1.4.0 | -| 0.15.0 | mmcv-full>=1.3.7, <1.4.0 | -| 0.14.1 | mmcv-full>=1.3.7, <1.4.0 | -| 0.14.0 | mmcv-full>=1.3.1, <1.3.2 | -| 0.13.0 | mmcv-full>=1.3.1, <1.3.2 | -| 0.12.0 | mmcv-full>=1.1.4, <1.3.2 | -| 0.11.0 | mmcv-full>=1.1.4, <1.3.0 | -| 0.10.0 | mmcv-full>=1.1.4, <1.3.0 | -| 0.9.0 | mmcv-full>=1.1.4, <1.3.0 | -| 0.8.0 | mmcv-full>=1.1.4, <1.2.0 | -| 0.7.0 | mmcv-full>=1.1.2, <1.2.0 | -| 0.6.0 | mmcv-full>=1.1.2, <1.2.0 | +| MMSegmentation version | MMCV version | +|:-------------------:|:-------------------:| +| master | mmcv-full>=1.3.13, <1.4.0 | +| 0.19.0 | mmcv-full>=1.3.13, <1.4.0 | +| 0.18.0 | mmcv-full>=1.3.13, <1.4.0 | +| 0.17.0 | mmcv-full>=1.3.7, <1.4.0 | +| 0.16.0 | mmcv-full>=1.3.7, <1.4.0 | +| 0.15.0 | mmcv-full>=1.3.7, <1.4.0 | +| 0.14.1 | mmcv-full>=1.3.7, <1.4.0 | +| 0.14.0 | mmcv-full>=1.3.1, <1.3.2 | +| 0.13.0 | mmcv-full>=1.3.1, <1.3.2 | +| 0.12.0 | mmcv-full>=1.1.4, <1.3.2 | +| 0.11.0 | mmcv-full>=1.1.4, <1.3.0 | +| 0.10.0 | mmcv-full>=1.1.4, <1.3.0 | +| 0.9.0 | mmcv-full>=1.1.4, <1.3.0 | +| 0.8.0 | mmcv-full>=1.1.4, <1.2.0 | +| 0.7.0 | mmcv-full>=1.1.2, <1.2.0 | +| 0.6.0 | mmcv-full>=1.1.2, <1.2.0 | :::{note} You need to run `pip uninstall mmcv` first if you have mmcv installed. @@ -228,7 +228,7 @@ python demo/video_demo.py ${VIDEO_FILE} ${CONFIG_FILE} ${CHECKPOINT_FILE} [--dev Examples: ```shell -# TODO: add mp4 link link `wget -P demo/ ` +wget -O demo/demo.mp4 https://user-images.githubusercontent.com/22089207/144212749-44411ef4-b564-4b37-96d4-04bedec629ab.mp4 python demo/video_demo.py demo/demo.mp4 configs/cgnet/cgnet_680x680_60k_cityscapes.py \ checkpoints/cgnet_680x680_60k_cityscapes_20201101_110253-4c0b2f2d.pth \ --device cuda:0 --palette cityscapes --show From f561bb04f9b8a94ead18694b7c8daac92070a5a5 Mon Sep 17 00:00:00 2001 From: irvingzhang0512 Date: Thu, 2 Dec 2021 09:56:38 +0800 Subject: [PATCH 5/5] add wget in shell --- docs/get_started.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/get_started.md b/docs/get_started.md index 0465594c9c..2458b067ef 100644 --- a/docs/get_started.md +++ b/docs/get_started.md @@ -220,6 +220,7 @@ A notebook demo can be found in [demo/inference_demo.ipynb](../demo/inference_de Now we also provide a demo script to test a single video. ```shell +wget -O demo/demo.mp4 https://user-images.githubusercontent.com/22089207/144212749-44411ef4-b564-4b37-96d4-04bedec629ab.mp4 python demo/video_demo.py ${VIDEO_FILE} ${CONFIG_FILE} ${CHECKPOINT_FILE} [--device ${DEVICE_NAME}] [--palette-thr ${PALETTE}] \ [--show] [--show-wait-time {SHOW_WAIT_TIME}] [--output-file {OUTPUT_FILE}] [--output-fps {OUTPUT_FPS}] \ [--output-height {OUTPUT_HEIGHT}] [--output-width {OUTPUT_WIDTH}] [--opacity {OPACITY}]