Commit 55baf374 authored by Yuxin Wu's avatar Yuxin Wu

[MaskRCNN] improve visualization palette

parent f42036ac
...@@ -18,14 +18,16 @@ feel free to delete everything in this template. ...@@ -18,14 +18,16 @@ feel free to delete everything in this template.
(3) **If not using examples, tell us what you did:** (3) **If not using examples, tell us what you did:**
Note that we may not be able to investigate it if there is no reproducible code. It's always better to copy-paste what you did than to describe them.
It's always better to paste what you did instead of describing them.
Please try to provide enough information to let other __reproduce__ your issues.
Without reproducing the issue, we may not be able to investigate it.
### 2. What you observed: ### 2. What you observed:
(1) **Include the ENTIRE logs here:** (1) **Include the ENTIRE logs here:**
It's always better to paste what you observed instead of describing them. It's always better to copy-paste what you observed instead of describing them.
It's always better to paste **as much as possible**, although sometimes a partial log is OK. It's always better to paste **as much as possible**, although sometimes a partial log is OK.
...@@ -42,11 +44,11 @@ If you expect higher speed, please read ...@@ -42,11 +44,11 @@ If you expect higher speed, please read
http://tensorpack.readthedocs.io/tutorial/performance-tuning.html http://tensorpack.readthedocs.io/tutorial/performance-tuning.html
before posting. before posting.
If you expect higher accuracy, only in one of the two conditions can we help with it: If you expect certain accuracy, only in one of the two conditions can we help with it:
(1) You're unable to match the accuracy documented in tensorpack examples. (1) You're unable to match the accuracy documented in tensorpack examples.
(2) It appears to be a tensorpack bug. (2) It appears to be a tensorpack bug.
Otherwise, how to get high accuracy is a machine learning question and is Otherwise, how to train a model to certain accuracy is a machine learning question and is
not our responsibility to figure out. not our responsibility to figure out.
### 4. Your environment: ### 4. Your environment:
......
...@@ -4,7 +4,7 @@ about: More general questions about Tensorpack. ...@@ -4,7 +4,7 @@ about: More general questions about Tensorpack.
--- ---
+ If you did something with tensorpack and it failed, please use the "Unexpected Problems / + If you did something with tensorpack and it failed, PLEASE STOP HERE and use the "Unexpected Problems /
Bugs" category. Bugs" category.
+ Your question is probably answered in [tutorials](http://tensorpack.readthedocs.io/tutorial/index.html#user-tutorials). Read it first. + Your question is probably answered in [tutorials](http://tensorpack.readthedocs.io/tutorial/index.html#user-tutorials). Read it first.
...@@ -23,6 +23,7 @@ Some typical questions that we DO NOT answer: ...@@ -23,6 +23,7 @@ Some typical questions that we DO NOT answer:
We have no plans to do so. We don't consider feature We have no plans to do so. We don't consider feature
requests for examples or implement a paper for you. requests for examples or implement a paper for you.
If you don't know how to do something yourself, you may ask a usage question. If you don't know how to do something yourself, you may ask a usage question.
+ "The examples do not perform as expected after I change the models/dataset/parameters/etc.": + "The examples do not perform as expected after I change the models/dataset/parameters/etc.":
Tensorpack maintainers make sure the examples perform well without modifications. Tensorpack maintainers make sure the examples perform well without modifications.
......
...@@ -63,7 +63,7 @@ Some reasonable configurations are listed in the table below. ...@@ -63,7 +63,7 @@ Some reasonable configurations are listed in the table below.
To predict on an image (needs DISPLAY to show the outputs): To predict on an image (needs DISPLAY to show the outputs):
``` ```
./train.py --predict input.jpg --load /path/to/Trained-Model-Checkpoint --config SAME-AS-TRAINING ./train.py --predict input1.jpg input2.jpg --load /path/to/Trained-Model-Checkpoint --config SAME-AS-TRAINING
``` ```
To evaluate the performance of a model on COCO: To evaluate the performance of a model on COCO:
......
...@@ -201,7 +201,7 @@ _C.TEST.FRCNN_NMS_THRESH = 0.5 ...@@ -201,7 +201,7 @@ _C.TEST.FRCNN_NMS_THRESH = 0.5
# Smaller threshold value gives significantly better mAP. But we use 0.05 for consistency with Detectron. # Smaller threshold value gives significantly better mAP. But we use 0.05 for consistency with Detectron.
# mAP with 1e-4 threshold can be found at https://github.com/tensorpack/tensorpack/commit/26321ae58120af2568bdbf2269f32aa708d425a8#diff-61085c48abee915b584027e1085e1043 # noqa # mAP with 1e-4 threshold can be found at https://github.com/tensorpack/tensorpack/commit/26321ae58120af2568bdbf2269f32aa708d425a8#diff-61085c48abee915b584027e1085e1043 # noqa
_C.TEST.RESULT_SCORE_THRESH = 0.05 _C.TEST.RESULT_SCORE_THRESH = 0.05
_C.TEST.RESULT_SCORE_THRESH_VIS = 0.3 # only visualize confident results _C.TEST.RESULT_SCORE_THRESH_VIS = 0.5 # only visualize confident results
_C.TEST.RESULTS_PER_IM = 100 _C.TEST.RESULTS_PER_IM = 100
_C.freeze() # avoid typo / wrong config keys _C.freeze() # avoid typo / wrong config keys
......
...@@ -393,7 +393,7 @@ def do_predict(pred_func, input_file): ...@@ -393,7 +393,7 @@ def do_predict(pred_func, input_file):
final = draw_final_outputs(img, results) final = draw_final_outputs(img, results)
viz = np.concatenate((img, final), axis=1) viz = np.concatenate((img, final), axis=1)
cv2.imwrite("output.png", viz) cv2.imwrite("output.png", viz)
logger.info("Inference output written to output.png") logger.info("Inference output for {} written to output.png".format(input_file))
tpviz.interactive_imshow(viz) tpviz.interactive_imshow(viz)
...@@ -405,7 +405,7 @@ if __name__ == '__main__': ...@@ -405,7 +405,7 @@ if __name__ == '__main__':
parser.add_argument('--evaluate', help="Run evaluation. " parser.add_argument('--evaluate', help="Run evaluation. "
"This argument is the path to the output json evaluation file") "This argument is the path to the output json evaluation file")
parser.add_argument('--predict', help="Run prediction on a given image. " parser.add_argument('--predict', help="Run prediction on a given image. "
"This argument is the path to the input image file") "This argument is the path to the input image file", nargs='+')
parser.add_argument('--config', help="A list of KEY=VALUE to overwrite those defined in config.py", parser.add_argument('--config', help="A list of KEY=VALUE to overwrite those defined in config.py",
nargs='+') nargs='+')
...@@ -440,7 +440,9 @@ if __name__ == '__main__': ...@@ -440,7 +440,9 @@ if __name__ == '__main__':
input_names=MODEL.get_inference_tensor_names()[0], input_names=MODEL.get_inference_tensor_names()[0],
output_names=MODEL.get_inference_tensor_names()[1]) output_names=MODEL.get_inference_tensor_names()[1])
if args.predict: if args.predict:
do_predict(OfflinePredictor(predcfg), args.predict) predictor = OfflinePredictor(predcfg)
for image_file in args.predict:
do_predict(predictor, image_file)
elif args.evaluate: elif args.evaluate:
assert args.evaluate.endswith('.json'), args.evaluate assert args.evaluate.endswith('.json'), args.evaluate
do_evaluate(predcfg, args.evaluate) do_evaluate(predcfg, args.evaluate)
......
...@@ -9,6 +9,7 @@ from tensorpack.utils.palette import PALETTE_RGB ...@@ -9,6 +9,7 @@ from tensorpack.utils.palette import PALETTE_RGB
from config import config as cfg from config import config as cfg
from utils.np_box_ops import iou as np_iou from utils.np_box_ops import iou as np_iou
from utils.np_box_ops import area as np_area
def draw_annotation(img, boxes, klass, is_crowd=None): def draw_annotation(img, boxes, klass, is_crowd=None):
...@@ -70,14 +71,19 @@ def draw_final_outputs(img, results): ...@@ -70,14 +71,19 @@ def draw_final_outputs(img, results):
if len(results) == 0: if len(results) == 0:
return img return img
# Display in largest to smallest order to reduce occlusion
boxes = np.asarray([r.box for r in results])
areas = np_area(boxes)
sorted_inds = np.argsort(-areas)
tags = [] tags = []
for r in results: for r in results:
tags.append( tags.append(
"{},{:.2f}".format(cfg.DATA.CLASS_NAMES[r.class_id], r.score)) "{},{:.2f}".format(cfg.DATA.CLASS_NAMES[r.class_id], r.score))
boxes = np.asarray([r.box for r in results])
ret = viz.draw_boxes(img, boxes, tags) ret = viz.draw_boxes(img, boxes, tags)
for r in results: for result_id in sorted_inds:
r = results[result_id]
if r.mask is not None: if r.mask is not None:
ret = draw_mask(ret, r.mask) ret = draw_mask(ret, r.mask)
return ret return ret
......
...@@ -5,7 +5,7 @@ import numpy as np ...@@ -5,7 +5,7 @@ import numpy as np
__all__ = ['PALETTE_RGB'] __all__ = ['PALETTE_RGB']
# copied from https://stackoverflow.com/questions/2328339/how-to-generate-n-different-colors-for-any-natural-number-n # Copied from https://stackoverflow.com/questions/2328339/how-to-generate-n-different-colors-for-any-natural-number-n
PALETTE_HEX = [ PALETTE_HEX = [
"#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059", "#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
"#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87", "#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
...@@ -26,6 +26,92 @@ PALETTE_HEX = [ ...@@ -26,6 +26,92 @@ PALETTE_HEX = [
"#7ED379", "#012C58"] "#7ED379", "#012C58"]
# Copied from https://github.com/facebookresearch/Detectron/blob/master/detectron/utils/colormap.py
DETECTRON_PALETTE = np.array(
[
0.000, 0.447, 0.741,
0.850, 0.325, 0.098,
0.929, 0.694, 0.125,
0.494, 0.184, 0.556,
0.466, 0.674, 0.188,
0.301, 0.745, 0.933,
0.635, 0.078, 0.184,
0.300, 0.300, 0.300,
0.600, 0.600, 0.600,
1.000, 0.000, 0.000,
1.000, 0.500, 0.000,
0.749, 0.749, 0.000,
0.000, 1.000, 0.000,
0.000, 0.000, 1.000,
0.667, 0.000, 1.000,
0.333, 0.333, 0.000,
0.333, 0.667, 0.000,
0.333, 1.000, 0.000,
0.667, 0.333, 0.000,
0.667, 0.667, 0.000,
0.667, 1.000, 0.000,
1.000, 0.333, 0.000,
1.000, 0.667, 0.000,
1.000, 1.000, 0.000,
0.000, 0.333, 0.500,
0.000, 0.667, 0.500,
0.000, 1.000, 0.500,
0.333, 0.000, 0.500,
0.333, 0.333, 0.500,
0.333, 0.667, 0.500,
0.333, 1.000, 0.500,
0.667, 0.000, 0.500,
0.667, 0.333, 0.500,
0.667, 0.667, 0.500,
0.667, 1.000, 0.500,
1.000, 0.000, 0.500,
1.000, 0.333, 0.500,
1.000, 0.667, 0.500,
1.000, 1.000, 0.500,
0.000, 0.333, 1.000,
0.000, 0.667, 1.000,
0.000, 1.000, 1.000,
0.333, 0.000, 1.000,
0.333, 0.333, 1.000,
0.333, 0.667, 1.000,
0.333, 1.000, 1.000,
0.667, 0.000, 1.000,
0.667, 0.333, 1.000,
0.667, 0.667, 1.000,
0.667, 1.000, 1.000,
1.000, 0.000, 1.000,
1.000, 0.333, 1.000,
1.000, 0.667, 1.000,
0.167, 0.000, 0.000,
0.333, 0.000, 0.000,
0.500, 0.000, 0.000,
0.667, 0.000, 0.000,
0.833, 0.000, 0.000,
1.000, 0.000, 0.000,
0.000, 0.167, 0.000,
0.000, 0.333, 0.000,
0.000, 0.500, 0.000,
0.000, 0.667, 0.000,
0.000, 0.833, 0.000,
0.000, 1.000, 0.000,
0.000, 0.000, 0.167,
0.000, 0.000, 0.333,
0.000, 0.000, 0.500,
0.000, 0.000, 0.667,
0.000, 0.000, 0.833,
0.000, 0.000, 1.000,
0.000, 0.000, 0.000,
0.143, 0.143, 0.143,
0.286, 0.286, 0.286,
0.429, 0.429, 0.429,
0.571, 0.571, 0.571,
0.714, 0.714, 0.714,
0.857, 0.857, 0.857,
1.000, 1.000, 1.000
]
).astype(np.float32).reshape(-1, 3) * 255
def _parse_hex_color(s): def _parse_hex_color(s):
r = int(s[1:3], 16) r = int(s[1:3], 16)
g = int(s[3:5], 16) g = int(s[3:5], 16)
...@@ -33,6 +119,9 @@ def _parse_hex_color(s): ...@@ -33,6 +119,9 @@ def _parse_hex_color(s):
return (r, g, b) return (r, g, b)
PALETTE_RGB = np.asarray( # PALETTE_RGB = np.asarray(
list(map(_parse_hex_color, PALETTE_HEX)), # list(map(_parse_hex_color, PALETTE_HEX)),
dtype='int32') # dtype='int32')
# This seems more beautiful
PALETTE_RGB = DETECTRON_PALETTE
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment