From a08260a7b16645705416b11362621950e683e6da Mon Sep 17 00:00:00 2001 From: mzr1996 Date: Thu, 19 Aug 2021 11:05:07 +0800 Subject: [PATCH 1/6] Imporve result visualization to support wait time and change the backend to matplotlib. --- mmcls/apis/inference.py | 9 +-- mmcls/core/visualization/__init__.py | 3 + mmcls/core/visualization/image.py | 98 ++++++++++++++++++++++++++++ mmcls/models/classifiers/base.py | 39 +++++------ setup.cfg | 2 +- 5 files changed, 120 insertions(+), 31 deletions(-) create mode 100644 mmcls/core/visualization/__init__.py create mode 100644 mmcls/core/visualization/image.py diff --git a/mmcls/apis/inference.py b/mmcls/apis/inference.py index 5483c86a49c..e3f3fcf3274 100644 --- a/mmcls/apis/inference.py +++ b/mmcls/apis/inference.py @@ -1,6 +1,5 @@ import warnings -import matplotlib.pyplot as plt import mmcv import numpy as np import torch @@ -89,7 +88,7 @@ def inference_model(model, img): return result -def show_result_pyplot(model, img, result, fig_size=(15, 10)): +def show_result_pyplot(model, img, result, fig_size=(15, 10), wait_time=0): """Visualize the classification results on the image. Args: @@ -100,7 +99,5 @@ def show_result_pyplot(model, img, result, fig_size=(15, 10)): """ if hasattr(model, 'module'): model = model.module - img = model.show_result(img, result, show=False) - plt.figure(figsize=fig_size) - plt.imshow(mmcv.bgr2rgb(img)) - plt.show() + model.show_result( + img, result, show=True, fig_size=fig_size, wait_time=wait_time) diff --git a/mmcls/core/visualization/__init__.py b/mmcls/core/visualization/__init__.py new file mode 100644 index 00000000000..6986314f028 --- /dev/null +++ b/mmcls/core/visualization/__init__.py @@ -0,0 +1,3 @@ +from .image import color_val_matplotlib, imshow_cls_result + +__all__ = ['imshow_cls_result', 'color_val_matplotlib'] diff --git a/mmcls/core/visualization/image.py b/mmcls/core/visualization/image.py new file mode 100644 index 00000000000..cc0aa9ddd4e --- /dev/null +++ b/mmcls/core/visualization/image.py @@ -0,0 +1,98 @@ +import matplotlib.pyplot as plt +import mmcv +import numpy as np + +EPS = 1e-2 + + +def color_val_matplotlib(color): + """Convert various input in BGR order to normalized RGB matplotlib color + tuples, + + Args: + color (:obj:`Color`/str/tuple/int/ndarray): Color inputs + + Returns: + tuple[float]: A tuple of 3 normalized floats indicating RGB channels. + """ + color = mmcv.color_val(color) + color = [color / 255 for color in color[::-1]] + return tuple(color) + + +def imshow_cls_result(img, + result, + text_color='white', + font_size=26, + row_width=20, + win_name='', + show=True, + fig_size=(15, 10), + wait_time=0, + out_file=None): + x, y = 3, row_width // 2 + text_color = color_val_matplotlib(text_color) + + img = mmcv.bgr2rgb(img) + width, height = img.shape[1], img.shape[0] + img = np.ascontiguousarray(img) + + fig = plt.figure(win_name, frameon=False, figsize=fig_size) + plt.title(win_name) + canvas = fig.canvas + dpi = fig.get_dpi() + # add a small EPS to avoid precision lost due to matplotlib's truncation + # (https://github.com/matplotlib/matplotlib/issues/15363) + fig.set_size_inches((width + EPS) / dpi, (height + EPS) / dpi) + + # remove white edges by set subplot margin + plt.subplots_adjust(left=0, right=1, bottom=0, top=1) + ax = plt.gca() + ax.axis('off') + + for k, v in result.items(): + if isinstance(v, float): + v = f'{v:.2f}' + label_text = f'{k}: {v}' + ax.text( + x, + y, + f'{label_text}', + bbox={ + 'facecolor': 'black', + 'alpha': 0.7, + 'pad': 0.2, + 'edgecolor': 'none', + 'boxstyle': 'round' + }, + color=text_color, + fontsize=font_size, + family='monospace', + verticalalignment='top', + horizontalalignment='left') + y += row_width + + plt.imshow(img) + stream, _ = canvas.print_to_buffer() + buffer = np.frombuffer(stream, dtype='uint8') + img_rgba = buffer.reshape(height, width, 4) + rgb, _ = np.split(img_rgba, [3], axis=2) + img = rgb.astype('uint8') + img = mmcv.rgb2bgr(img) + + if show: + # We do not use cv2 for display because in some cases, opencv will + # conflict with Qt, it will output a warning: Current thread + # is not the object's thread. You can refer to + # https://github.com/opencv/opencv-python/issues/46 for details + if wait_time == 0: + plt.show() + else: + plt.show(block=False) + plt.pause(wait_time) + if out_file is not None: + mmcv.imwrite(img, out_file) + + plt.close() + + return img diff --git a/mmcls/models/classifiers/base.py b/mmcls/models/classifiers/base.py index 3acb3e9f5a2..79900066d35 100644 --- a/mmcls/models/classifiers/base.py +++ b/mmcls/models/classifiers/base.py @@ -2,13 +2,13 @@ from abc import ABCMeta, abstractmethod from collections import OrderedDict -import cv2 import mmcv import torch import torch.distributed as dist -from mmcv import color_val from mmcv.runner import BaseModule +from mmcls.core.visualization import imshow_cls_result + # TODO import `auto_fp16` from mmcv and delete them from mmcls try: from mmcv.runner import auto_fp16 @@ -168,10 +168,11 @@ def val_step(self, data, optimizer): def show_result(self, img, result, - text_color='green', + text_color='white', font_scale=0.5, row_width=20, show=False, + fig_size=(15, 10), win_name='', wait_time=0, out_file=None): @@ -197,27 +198,17 @@ def show_result(self, img = mmcv.imread(img) img = img.copy() - # write results on left-top of the image - x, y = 0, row_width - text_color = color_val(text_color) - for k, v in result.items(): - if isinstance(v, float): - v = f'{v:.2f}' - label_text = f'{k}: {v}' - cv2.putText(img, label_text, (x, y), cv2.FONT_HERSHEY_COMPLEX, - font_scale, text_color) - y += row_width - - # if out_file specified, do not show image in window - if out_file is not None: - show = False - - if show: - mmcv.imshow(img, win_name, wait_time) - if out_file is not None: - mmcv.imwrite(img, out_file) + img = imshow_cls_result( + img, + result, + text_color=text_color, + font_size=int(font_scale * 50), + row_width=row_width, + win_name=win_name, + show=show, + fig_size=fig_size, + wait_time=wait_time, + out_file=out_file) if not (show or out_file): - warnings.warn('show==False and out_file is not specified, only ' - 'result image will be returned') return img diff --git a/setup.cfg b/setup.cfg index 262a3f11dfb..27a9c11aba5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -14,6 +14,6 @@ line_length = 79 multi_line_output = 0 known_standard_library = pkg_resources,setuptools known_first_party = mmcls -known_third_party = PIL,cv2,matplotlib,mmcv,mmdet,numpy,onnxruntime,packaging,pytest,seaborn,torch,torchvision,ts +known_third_party = PIL,matplotlib,mmcv,mmdet,numpy,onnxruntime,packaging,pytest,seaborn,torch,torchvision,ts no_lines_before = STDLIB,LOCALFOLDER default_section = THIRDPARTY From 80318ae3cfa24b3ecb7d934cd1f521c930f7dc2f Mon Sep 17 00:00:00 2001 From: mzr1996 Date: Thu, 19 Aug 2021 12:02:14 +0800 Subject: [PATCH 2/6] Add unit test for visualization --- tests/test_models/test_classifiers.py | 11 ---- tests/test_utils/test_visualization.py | 80 ++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 tests/test_utils/test_visualization.py diff --git a/tests/test_models/test_classifiers.py b/tests/test_models/test_classifiers.py index 5f44612b8c1..4fe05a2cc79 100644 --- a/tests/test_models/test_classifiers.py +++ b/tests/test_models/test_classifiers.py @@ -1,7 +1,6 @@ import os.path as osp import tempfile from copy import deepcopy -from unittest.mock import patch import numpy as np import pytest @@ -84,16 +83,6 @@ def test_image_classifier(): model.show_result(img, result, out_file=out_file) assert osp.exists(out_file) - def save_show(_, *args): - out_path = osp.join(tmpdir, '_'.join([str(arg) for arg in args])) - with open(out_path, 'w') as f: - f.write('test') - - with patch('mmcv.imshow', save_show): - model.show_result( - img, result, show=True, win_name='img', wait_time=5) - assert osp.exists(osp.join(tmpdir, 'img_5')) - def test_image_classifier_with_mixup(): # Test mixup in ImageClassifier diff --git a/tests/test_utils/test_visualization.py b/tests/test_utils/test_visualization.py new file mode 100644 index 00000000000..384a0f9eac2 --- /dev/null +++ b/tests/test_utils/test_visualization.py @@ -0,0 +1,80 @@ +# Copyright (c) Open-MMLab. All rights reserved. +import os +import os.path as osp +import shutil +import tempfile +from unittest.mock import patch + +import mmcv +import numpy as np +import pytest + +from mmcls.core import visualization as vis + + +def test_color(): + assert vis.color_val_matplotlib(mmcv.Color.blue) == (0., 0., 1.) + assert vis.color_val_matplotlib('green') == (0., 1., 0.) + assert vis.color_val_matplotlib((1, 2, 3)) == (3 / 255, 2 / 255, 1 / 255) + assert vis.color_val_matplotlib(100) == (100 / 255, 100 / 255, 100 / 255) + assert vis.color_val_matplotlib(np.zeros(3, dtype=np.int)) == (0., 0., 0.) + # forbid white color + with pytest.raises(TypeError): + vis.color_val_matplotlib([255, 255, 255]) + # forbid float + with pytest.raises(TypeError): + vis.color_val_matplotlib(1.0) + # overflowed + with pytest.raises(AssertionError): + vis.color_val_matplotlib((0, 0, 500)) + + +def test_imshow_cls_results(): + tmp_dir = osp.join(tempfile.gettempdir(), 'cls_results_image') + tmp_filename = osp.join(tmp_dir, 'image.jpg') + + image = np.ones((10, 10, 3), np.uint8) + result = {'pred_label': 1, 'pred_class': 'bird', 'pred_score': 0.98} + out_image = vis.imshow_cls_result( + image, result, out_file=tmp_filename, show=False) + assert osp.isfile(tmp_filename) + assert image.shape == out_image.shape + assert not np.allclose(image, out_image) + os.remove(tmp_filename) + + # test grayscale images + image = np.ones((10, 10), np.uint8) + result = {'pred_label': 1, 'pred_class': 'bird', 'pred_score': 0.98} + out_image = vis.imshow_cls_result( + image, result, out_file=tmp_filename, show=False) + assert osp.isfile(tmp_filename) + assert image.shape == out_image.shape[:2] + os.remove(tmp_filename) + + # test show=True + image = np.ones((10, 10, 3), np.uint8) + result = {'pred_label': 1, 'pred_class': 'bird', 'pred_score': 0.98} + + def save_args(*args, **kwargs): + args_list = ['args'] + args_list += [ + str(arg) for arg in args if isinstance(arg, (str, bool, int)) + ] + args_list += [ + f'{k}-{v}' for k, v in kwargs.items() + if isinstance(v, (str, bool, int)) + ] + out_path = osp.join(tmp_dir, '_'.join(args_list)) + with open(out_path, 'w') as f: + f.write('test') + + with patch('matplotlib.pyplot.show', save_args), \ + patch('matplotlib.pyplot.pause', save_args): + vis.imshow_cls_result(image, result, show=True, wait_time=5) + assert osp.exists(osp.join(tmp_dir, 'args_block-False')) + assert osp.exists(osp.join(tmp_dir, 'args_5')) + + vis.imshow_cls_result(image, result, show=True, wait_time=0) + assert osp.exists(osp.join(tmp_dir, 'args')) + + shutil.rmtree(tmp_dir) From 4d321eb5740c044e5bc3ad590efe209ad86d2a7b Mon Sep 17 00:00:00 2001 From: mzr1996 Date: Thu, 19 Aug 2021 15:23:58 +0800 Subject: [PATCH 3/6] Add adaptive dpi function --- mmcls/core/visualization/image.py | 12 +++++++++++- tests/test_utils/test_visualization.py | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/mmcls/core/visualization/image.py b/mmcls/core/visualization/image.py index cc0aa9ddd4e..f69f1580071 100644 --- a/mmcls/core/visualization/image.py +++ b/mmcls/core/visualization/image.py @@ -37,7 +37,8 @@ def imshow_cls_result(img, width, height = img.shape[1], img.shape[0] img = np.ascontiguousarray(img) - fig = plt.figure(win_name, frameon=False, figsize=fig_size) + # A proper dpi for image save with default font size. + fig = plt.figure(win_name, frameon=False, figsize=fig_size, dpi=36) plt.title(win_name) canvas = fig.canvas dpi = fig.get_dpi() @@ -81,6 +82,15 @@ def imshow_cls_result(img, img = mmcv.rgb2bgr(img) if show: + # Matplotlib will adjust text size depends on window size and image + # aspect ratio. It's hard to get, so here we set an adaptive dpi + # according to screen height. 20 here is an empirical parameter. + fig_manager = plt.get_current_fig_manager() + if hasattr(fig_manager, 'window'): + # Figure manager doesn't have window if no screen. + screen_dpi = fig_manager.window.winfo_screenheight() // 20 + fig.set_dpi(screen_dpi) + # We do not use cv2 for display because in some cases, opencv will # conflict with Qt, it will output a warning: Current thread # is not the object's thread. You can refer to diff --git a/tests/test_utils/test_visualization.py b/tests/test_utils/test_visualization.py index 384a0f9eac2..340fb6c8766 100644 --- a/tests/test_utils/test_visualization.py +++ b/tests/test_utils/test_visualization.py @@ -3,7 +3,7 @@ import os.path as osp import shutil import tempfile -from unittest.mock import patch +from unittest.mock import Mock, patch import mmcv import numpy as np @@ -17,7 +17,7 @@ def test_color(): assert vis.color_val_matplotlib('green') == (0., 1., 0.) assert vis.color_val_matplotlib((1, 2, 3)) == (3 / 255, 2 / 255, 1 / 255) assert vis.color_val_matplotlib(100) == (100 / 255, 100 / 255, 100 / 255) - assert vis.color_val_matplotlib(np.zeros(3, dtype=np.int)) == (0., 0., 0.) + assert vis.color_val_matplotlib(np.zeros(3, dtype=int)) == (0., 0., 0.) # forbid white color with pytest.raises(TypeError): vis.color_val_matplotlib([255, 255, 255]) @@ -77,4 +77,14 @@ def save_args(*args, **kwargs): vis.imshow_cls_result(image, result, show=True, wait_time=0) assert osp.exists(osp.join(tmp_dir, 'args')) + # test adaptive dpi + def mock_fig_manager(): + fig_manager = Mock() + fig_manager.window.winfo_screenheight = Mock(return_value=1440) + return fig_manager + + with patch('matplotlib.pyplot.get_current_fig_manager', + mock_fig_manager), patch('matplotlib.pyplot.show'): + vis.imshow_cls_result(image, result, show=True) + shutil.rmtree(tmp_dir) From 5856a5d739baebcd87d44b6d6a315277efb62d49 Mon Sep 17 00:00:00 2001 From: mzr1996 Date: Thu, 26 Aug 2021 14:09:07 +0800 Subject: [PATCH 4/6] Rename `imshow_cls_result` to `imshow_infos`. --- mmcls/core/visualization/__init__.py | 4 +-- mmcls/core/visualization/image.py | 44 +++++++++++++++++++------- mmcls/models/classifiers/base.py | 10 +++--- tests/test_utils/test_visualization.py | 14 ++++---- 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/mmcls/core/visualization/__init__.py b/mmcls/core/visualization/__init__.py index 6986314f028..ea89d749b25 100644 --- a/mmcls/core/visualization/__init__.py +++ b/mmcls/core/visualization/__init__.py @@ -1,3 +1,3 @@ -from .image import color_val_matplotlib, imshow_cls_result +from .image import color_val_matplotlib, imshow_infos -__all__ = ['imshow_cls_result', 'color_val_matplotlib'] +__all__ = ['imshow_infos', 'color_val_matplotlib'] diff --git a/mmcls/core/visualization/image.py b/mmcls/core/visualization/image.py index f69f1580071..9ee9dca69d3 100644 --- a/mmcls/core/visualization/image.py +++ b/mmcls/core/visualization/image.py @@ -2,6 +2,7 @@ import mmcv import numpy as np +# A small value EPS = 1e-2 @@ -10,7 +11,7 @@ def color_val_matplotlib(color): tuples, Args: - color (:obj:`Color`/str/tuple/int/ndarray): Color inputs + color (:obj:`mmcv.Color`/str/tuple/int/ndarray): Color inputs Returns: tuple[float]: A tuple of 3 normalized floats indicating RGB channels. @@ -20,16 +21,35 @@ def color_val_matplotlib(color): return tuple(color) -def imshow_cls_result(img, - result, - text_color='white', - font_size=26, - row_width=20, - win_name='', - show=True, - fig_size=(15, 10), - wait_time=0, - out_file=None): +def imshow_infos(img, + infos, + text_color='white', + font_size=26, + row_width=20, + win_name='', + show=True, + fig_size=(15, 10), + wait_time=0, + out_file=None): + """Show image with extra infomation. + + Args: + img (str | ndarray): The image to be displayed. + infos (dict): Extra infos to display in the image. + text_color (:obj:`mmcv.Color`/str/tuple/int/ndarray): Extra infos + display color. Defaults to 'white'. + font_size (int): Extra infos display font size. Defaults to 26. + row_width (int): width between each row of results on the image. + win_name (str): The image title. Defaults to '' + show (bool): Whether to show the image. Defaults to True. + fig_size (tuple): Image show figure size. Defaults to (15, 10). + wait_time (int): Show time of image display. + out_file (Optional[str]): The filename to write the image. + Defaults to None. + + Returns: + np.ndarray: The image with extra infomations. + """ x, y = 3, row_width // 2 text_color = color_val_matplotlib(text_color) @@ -51,7 +71,7 @@ def imshow_cls_result(img, ax = plt.gca() ax.axis('off') - for k, v in result.items(): + for k, v in infos.items(): if isinstance(v, float): v = f'{v:.2f}' label_text = f'{k}: {v}' diff --git a/mmcls/models/classifiers/base.py b/mmcls/models/classifiers/base.py index 79900066d35..ae63f642763 100644 --- a/mmcls/models/classifiers/base.py +++ b/mmcls/models/classifiers/base.py @@ -7,7 +7,7 @@ import torch.distributed as dist from mmcv.runner import BaseModule -from mmcls.core.visualization import imshow_cls_result +from mmcls.core.visualization import imshow_infos # TODO import `auto_fp16` from mmcv and delete them from mmcls try: @@ -186,6 +186,7 @@ def show_result(self, row_width (int): width between each row of results on the image. show (bool): Whether to show the image. Default: False. + fig_size (tuple): Image show figure size. Defaults to (15, 10). win_name (str): The window name. wait_time (int): Value of waitKey param. Default: 0. @@ -193,12 +194,12 @@ def show_result(self, Default: None. Returns: - img (ndarray): Only if not `show` or `out_file` + img (ndarray): Image with overlayed results. """ img = mmcv.imread(img) img = img.copy() - img = imshow_cls_result( + img = imshow_infos( img, result, text_color=text_color, @@ -210,5 +211,4 @@ def show_result(self, wait_time=wait_time, out_file=out_file) - if not (show or out_file): - return img + return img diff --git a/tests/test_utils/test_visualization.py b/tests/test_utils/test_visualization.py index 340fb6c8766..b30c0089357 100644 --- a/tests/test_utils/test_visualization.py +++ b/tests/test_utils/test_visualization.py @@ -29,13 +29,13 @@ def test_color(): vis.color_val_matplotlib((0, 0, 500)) -def test_imshow_cls_results(): - tmp_dir = osp.join(tempfile.gettempdir(), 'cls_results_image') +def test_imshow_infos(): + tmp_dir = osp.join(tempfile.gettempdir(), 'infos_image') tmp_filename = osp.join(tmp_dir, 'image.jpg') image = np.ones((10, 10, 3), np.uint8) result = {'pred_label': 1, 'pred_class': 'bird', 'pred_score': 0.98} - out_image = vis.imshow_cls_result( + out_image = vis.imshow_infos( image, result, out_file=tmp_filename, show=False) assert osp.isfile(tmp_filename) assert image.shape == out_image.shape @@ -45,7 +45,7 @@ def test_imshow_cls_results(): # test grayscale images image = np.ones((10, 10), np.uint8) result = {'pred_label': 1, 'pred_class': 'bird', 'pred_score': 0.98} - out_image = vis.imshow_cls_result( + out_image = vis.imshow_infos( image, result, out_file=tmp_filename, show=False) assert osp.isfile(tmp_filename) assert image.shape == out_image.shape[:2] @@ -70,11 +70,11 @@ def save_args(*args, **kwargs): with patch('matplotlib.pyplot.show', save_args), \ patch('matplotlib.pyplot.pause', save_args): - vis.imshow_cls_result(image, result, show=True, wait_time=5) + vis.imshow_infos(image, result, show=True, wait_time=5) assert osp.exists(osp.join(tmp_dir, 'args_block-False')) assert osp.exists(osp.join(tmp_dir, 'args_5')) - vis.imshow_cls_result(image, result, show=True, wait_time=0) + vis.imshow_infos(image, result, show=True, wait_time=0) assert osp.exists(osp.join(tmp_dir, 'args')) # test adaptive dpi @@ -85,6 +85,6 @@ def mock_fig_manager(): with patch('matplotlib.pyplot.get_current_fig_manager', mock_fig_manager), patch('matplotlib.pyplot.show'): - vis.imshow_cls_result(image, result, show=True) + vis.imshow_infos(image, result, show=True) shutil.rmtree(tmp_dir) From c22e27b2e8b1a6e662c578c7383879fefcfc9424 Mon Sep 17 00:00:00 2001 From: mzr1996 Date: Thu, 26 Aug 2021 14:12:17 +0800 Subject: [PATCH 5/6] Support str in `imshow_infos` --- mmcls/core/visualization/image.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mmcls/core/visualization/image.py b/mmcls/core/visualization/image.py index 9ee9dca69d3..18c624d89b8 100644 --- a/mmcls/core/visualization/image.py +++ b/mmcls/core/visualization/image.py @@ -50,6 +50,8 @@ def imshow_infos(img, Returns: np.ndarray: The image with extra infomations. """ + img = mmcv.imread(img).astype(np.uint8) + x, y = 3, row_width // 2 text_color = color_val_matplotlib(text_color) From f0a129dce4a39add7a93e4b80d419a535ca40cb3 Mon Sep 17 00:00:00 2001 From: mzr1996 Date: Thu, 26 Aug 2021 14:28:24 +0800 Subject: [PATCH 6/6] Improve docstring. --- mmcls/apis/inference.py | 3 +++ mmcls/core/visualization/image.py | 2 +- mmcls/models/classifiers/base.py | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mmcls/apis/inference.py b/mmcls/apis/inference.py index e3f3fcf3274..13e8f7c634b 100644 --- a/mmcls/apis/inference.py +++ b/mmcls/apis/inference.py @@ -96,6 +96,9 @@ def show_result_pyplot(model, img, result, fig_size=(15, 10), wait_time=0): img (str or np.ndarray): Image filename or loaded image. result (list): The classification result. fig_size (tuple): Figure size of the pyplot figure. + Defaults to (15, 10). + wait_time (int): How many seconds to display the image. + Defaults to 0. """ if hasattr(model, 'module'): model = model.module diff --git a/mmcls/core/visualization/image.py b/mmcls/core/visualization/image.py index 18c624d89b8..9076eddb594 100644 --- a/mmcls/core/visualization/image.py +++ b/mmcls/core/visualization/image.py @@ -43,7 +43,7 @@ def imshow_infos(img, win_name (str): The image title. Defaults to '' show (bool): Whether to show the image. Defaults to True. fig_size (tuple): Image show figure size. Defaults to (15, 10). - wait_time (int): Show time of image display. + wait_time (int): How many seconds to display the image. Defaults to 0. out_file (Optional[str]): The filename to write the image. Defaults to None. diff --git a/mmcls/models/classifiers/base.py b/mmcls/models/classifiers/base.py index ae63f642763..68f884f88cd 100644 --- a/mmcls/models/classifiers/base.py +++ b/mmcls/models/classifiers/base.py @@ -188,8 +188,8 @@ def show_result(self, Default: False. fig_size (tuple): Image show figure size. Defaults to (15, 10). win_name (str): The window name. - wait_time (int): Value of waitKey param. - Default: 0. + wait_time (int): How many seconds to display the image. + Defaults to 0. out_file (str or None): The filename to write the image. Default: None.