forked from microsoft/computervision-recipes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplot.py
158 lines (126 loc) · 4.91 KB
/
plot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
import os
from typing import List, Tuple
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image, ImageOps
from utils_cv.similarity.data import ComparativeSet
from utils_cv.similarity.metrics import recall_at_k
def plot_distances(
distances: list,
num_rows: int,
num_cols: int,
figsize: Tuple[int, int] = None,
im_info_font_size: int = None,
):
"""Displays the images which paths are provided as input
Args:
distances: List of tuples (image path, distance to the query_image)
num_rows: Number of rows on which to display the images
num_cols: Number of columns on which to display the images
figsize: Figure width and height in inches
im_info_font_size: Size of image titles
Returns: Nothing, but generates a plot
"""
distanceVals = [d for (im, d) in distances]
sortOrder = np.argsort(distanceVals)
plt.subplots(num_rows, num_cols, figsize=figsize)
for num, index in enumerate(sortOrder[: num_rows * num_cols]):
image, distance = distances[index]
plt.subplot(num_rows, num_cols, num + 1)
plt.subplots_adjust(hspace=0.2)
plt.axis("off")
title_color = "black"
im_name = os.path.basename(image)
title = f"{im_name}\nrank: {num}\ndist: {distance:0.2f}"
img = Image.open(image)
if num == 0 and distance < 0.01:
title_color = "orange"
img = ImageOps.expand(img, border=15, fill=title_color)
title = f"Reference:\n{im_name}"
plt.title(title, fontsize=im_info_font_size, color=title_color)
plt.imshow(img)
plt.figsize = (1, 1)
def plot_comparative_set(
cs: ComparativeSet,
num_cols: int = 5,
figsize: Tuple[int, int] = None,
im_info_font_size: int = None,
):
"""Displays the reference image, the associated positive example,
and the negative examples of a specified comparative set.
Args:
comparative_set: Comparative set to display
num_cols: Number of comparative images to display
figsize: Figure width and height in inches
im_info_font_size: Size of image titles
Returns: Nothing but generates a plot
"""
plt.subplots(figsize=figsize)
# plot query image
plt.subplot(1, num_cols, 1)
plt.axis("off")
im = Image.open(cs.query_im_path)
im = ImageOps.expand(im, border=18, fill="orange")
title = f"Query:\n{cs.pos_label}: {os.path.basename(cs.query_im_path)}"
plt.title(title, fontsize=im_info_font_size, color="orange")
plt.imshow(im)
# plot query image
plt.subplot(1, num_cols, 2)
plt.axis("off")
im = Image.open(cs.pos_im_path)
im = ImageOps.expand(im, border=18, fill="green")
title = f"Positive:\n{cs.pos_label}: {os.path.basename(cs.query_im_path)}"
plt.title(title, fontsize=im_info_font_size, color="green")
plt.imshow(im)
# plot negative image
for num, neg_im_path in enumerate(cs.neg_im_paths[: num_cols - 2]):
plt.subplot(1, num_cols, num + 3)
plt.axis("off")
im = Image.open(neg_im_path)
title = (
f"Negative:\n{cs.pos_label}: {os.path.basename(cs.query_im_path)}"
)
plt.title(title, fontsize=im_info_font_size, color="black")
plt.imshow(im)
def plot_recalls(ranks: List[int], figsize: Tuple[int, int] = None):
"""Display recall at various values of k.
Args:
ranks: List of ranks of the positive example across comparative sets
figsize: Figure width and height in inches
Returns: Nothing but generates a plot
"""
plt.subplots(figsize=figsize)
k_vec = range(1, max(ranks) + 1)
recalls = [recall_at_k(ranks, k) for k in k_vec]
plt.plot(k_vec, recalls, color="darkorange", lw=2)
plt.xlim([0.0, max(k_vec)])
plt.ylim([0.0, 101])
plt.ylabel("Recall")
plt.xlabel("Top-K")
plt.title("Recall@k curve")
def plot_ranks_distribution(
ranks: List[int],
x_axis_max: int = None,
figsize: Tuple[int, int] = (15, 6),
):
"""Displays the distribution of rank of the positive image
across comparative sets.
If show_set_size == True, also displays the distribution of
number of comparative images in each set.
Args:
ranks: List of ranks of the positive example across comparative sets
sets_sizes: List of size of the comparative sets
figsize: Figure width and height in inches
Returns: Nothing but generates a plot
"""
plt.subplots(figsize=figsize)
if x_axis_max is None:
x_axis_max = max(ranks) + 1
bins = np.arange(1, x_axis_max + 2, 1) - 0.5
plt.hist(ranks, bins=bins, alpha=0.5, label="Positive example rank")
plt.xticks(bins + 0.5)
plt.ylabel("Number of comparative sets")
plt.xlabel("Rank of positive example")
plt.title("Distribution of positive example rank across comparative sets")