Lewislou commited on
Commit
2f17f86
1 Parent(s): ed9e0be

Upload overlay.py

Browse files
Files changed (1) hide show
  1. overlay.py +116 -0
overlay.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ ###overlay
5
+ import cv2
6
+ import math
7
+ import random
8
+ import colorsys
9
+ import numpy as np
10
+ import itertools
11
+ import matplotlib.pyplot as plt
12
+ from matplotlib import cm
13
+ import os
14
+ import scipy.io as io
15
+ def get_bounding_box(img):
16
+ """Get bounding box coordinate information."""
17
+ rows = np.any(img, axis=1)
18
+ cols = np.any(img, axis=0)
19
+ rmin, rmax = np.where(rows)[0][[0, -1]]
20
+ cmin, cmax = np.where(cols)[0][[0, -1]]
21
+ # due to python indexing, need to add 1 to max
22
+ # else accessing will be 1px in the box, not out
23
+ rmax += 1
24
+ cmax += 1
25
+ return [rmin, rmax, cmin, cmax]
26
+ ####
27
+ def colorize(ch, vmin, vmax):
28
+ """Will clamp value value outside the provided range to vmax and vmin."""
29
+ cmap = plt.get_cmap("jet")
30
+ ch = np.squeeze(ch.astype("float32"))
31
+ vmin = vmin if vmin is not None else ch.min()
32
+ vmax = vmax if vmax is not None else ch.max()
33
+ ch[ch > vmax] = vmax # clamp value
34
+ ch[ch < vmin] = vmin
35
+ ch = (ch - vmin) / (vmax - vmin + 1.0e-16)
36
+ # take RGB from RGBA heat map
37
+ ch_cmap = (cmap(ch)[..., :3] * 255).astype("uint8")
38
+ return ch_cmap
39
+
40
+
41
+ ####
42
+ def random_colors(N, bright=True):
43
+ """Generate random colors.
44
+
45
+ To get visually distinct colors, generate them in HSV space then
46
+ convert to RGB.
47
+ """
48
+ brightness = 1.0 if bright else 0.7
49
+ hsv = [(i / N, 1, brightness) for i in range(N)]
50
+ colors = list(map(lambda c: colorsys.hsv_to_rgb(*c), hsv))
51
+ random.shuffle(colors)
52
+ return colors
53
+
54
+
55
+ ####
56
+ def visualize_instances_map(
57
+ input_image, inst_map, type_map=None, type_colour=None, line_thickness=2
58
+ ):
59
+ """Overlays segmentation results on image as contours.
60
+
61
+ Args:
62
+ input_image: input image
63
+ inst_map: instance mask with unique value for every object
64
+ type_map: type mask with unique value for every class
65
+ type_colour: a dict of {type : colour} , `type` is from 0-N
66
+ and `colour` is a tuple of (R, G, B)
67
+ line_thickness: line thickness of contours
68
+
69
+ Returns:
70
+ overlay: output image with segmentation overlay as contours
71
+ """
72
+ overlay = np.copy((input_image).astype(np.uint8))
73
+
74
+ inst_list = list(np.unique(inst_map)) # get list of instances
75
+ inst_list.remove(0) # remove background
76
+
77
+ inst_rng_colors = random_colors(len(inst_list))
78
+ inst_rng_colors = np.array(inst_rng_colors) * 255
79
+ inst_rng_colors = inst_rng_colors.astype(np.uint8)
80
+
81
+ for inst_idx, inst_id in enumerate(inst_list):
82
+ inst_map_mask = np.array(inst_map == inst_id, np.uint8) # get single object
83
+ y1, y2, x1, x2 = get_bounding_box(inst_map_mask)
84
+ y1 = y1 - 2 if y1 - 2 >= 0 else y1
85
+ x1 = x1 - 2 if x1 - 2 >= 0 else x1
86
+ x2 = x2 + 2 if x2 + 2 <= inst_map.shape[1] - 1 else x2
87
+ y2 = y2 + 2 if y2 + 2 <= inst_map.shape[0] - 1 else y2
88
+ inst_map_crop = inst_map_mask[y1:y2, x1:x2]
89
+ contours_crop = cv2.findContours(
90
+ inst_map_crop, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE
91
+ )
92
+ # only has 1 instance per map, no need to check #contour detected by opencv
93
+ #print(contours_crop)
94
+ contours_crop = np.squeeze(
95
+ contours_crop[0][0].astype("int32")
96
+ ) # * opencv protocol format may break
97
+
98
+ if len(contours_crop.shape) == 1:
99
+ contours_crop = contours_crop.reshape(1,-1)
100
+ #print(contours_crop.shape)
101
+ contours_crop += np.asarray([[x1, y1]]) # index correction
102
+ if type_map is not None:
103
+ type_map_crop = type_map[y1:y2, x1:x2]
104
+ type_id = np.unique(type_map_crop).max() # non-zero
105
+ inst_colour = type_colour[type_id]
106
+ else:
107
+ inst_colour = (inst_rng_colors[inst_idx]).tolist()
108
+ cv2.drawContours(overlay, [contours_crop], -1, inst_colour, line_thickness)
109
+ return overlay
110
+
111
+
112
+ # In[ ]:
113
+
114
+
115
+
116
+