-
Notifications
You must be signed in to change notification settings - Fork 0
/
image_interactive.py
134 lines (104 loc) · 4.75 KB
/
image_interactive.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
import argparse
from matplotlib import pyplot as plt
import cv2 as cv
import mpldatacursor
import numpy as np
import matplotlib.patches as patches
import tkinter as tk
from tkinter import messagebox
import os.path
import matplotlib
matplotlib.use('TkAgg')
parser = argparse.ArgumentParser()
parser.add_argument("--input", required=True, help="path to input image")
parser.add_argument("--ratio", required=True, help="rescaling ratio (eg 0.2 - 20% of original resolution)")
parser.add_argument("--label", default=False, choices=["True", "False"], help="use this if you want to see information about label image or prediction image (5-color greyscale images)")
parser.add_argument("--output", required=True, help="path to txt file where you want to save problematic tile numbers by right-clicking on the tile")
a = parser.parse_args()
image_name=os.path.basename(a.input)
image_name=(image_name.split("_")[0]+"_"+image_name.split("_")[1]) #Input file name is expected to be in the format *_*_*, like T35VLF_20200529T120441_im_scl.png
#Read in and resize the image
img=cv.imread(a.input)
height, width, channels = img.shape
ratio=float(a.ratio)
img=cv.resize(img,dsize=(int(width*ratio),int(height*ratio)))
#Open the image interactively in matplotlib
fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(img)
#Create a rectangle to show the border of individual tile
rect = patches.Rectangle((0,0),512*ratio,512*ratio,linewidth=1,edgecolor='r',facecolor='none')
ax.add_patch(rect)
color_to_label = {
tuple([255, 255,255]): "True cloud",
tuple([0, 0,0]): "True clear",
tuple([190, 190, 190]): "True cloudshadow",
tuple([100,100,100]): "True semitransparent",
tuple([0,255,255]): " Cloud instead of clear",
tuple([0,0,255]): " Cloud instead of cloud shadow",
tuple([135,206,235]): "Cloud instead of semitransparent cloud",
tuple([0,255,0]): "Clear instead of cloud",
tuple([240,230,140]): "Clear instead of cloudshadow",
tuple([60,179,113]): "Clear instead of semitransparent",
tuple([255, 201, 0]): "Shadow instead of cloud",
tuple([255,255,0]): "Shadow instead of clear",
tuple([204,204,0]): "Shadow instead of semitransparent",
tuple([240,128,128]): "Semitransparent instead of cloud",
tuple([255,0,0]): "Semitransparent instead of clear",
tuple([220,20,60]): "Semitransparent instead of shadow",
tuple([255,0,255]): "True undefined",
tuple([238,130,238]): "Undefined predicted instead of sth else",
tuple([153,50,204]): "Predicted something else instead of undefined"
}
if(a.label):
color_to_label = {
tuple([3,3,3]): "Undefined",
tuple([66,66,66]): "Clear",
tuple([129,129,129]): "Cloud shadow",
tuple([192,192,192]): "Semitransparent cloud",
tuple([255,255,255]): "Cloud",
}
#All the possible coordinates of individual tiles
vertical_lines_locations=np.arange(512*ratio/2,ratio*width,512*ratio)
horizontal_lines_locations=np.arange(512*ratio/2,ratio*height,512*ratio)
#Draw rectangle according to cursor position
def on_mouse_move(event):
if None not in (event.xdata, event.ydata):
x=int(min(vertical_lines_locations, key=lambda x:abs(x-event.xdata))-512*ratio/2) #This picks the right coordinate for the rectangle
y=int(min(horizontal_lines_locations, key=lambda x:abs(x-event.ydata))-512*ratio/2)
rect.set_xy((x,y))
fig.canvas.draw()
#Confirmation message when saving the tile
def confirm(label):
MsgBox = tk.messagebox.askquestion ('Confirm decision',"Save "+label+" to file "+str(a.output)+" ?",icon = 'warning')
if MsgBox == 'yes':
output = open(a.output, 'a')
output.write(label+"\n")
output.close()
def onclick(event):
if None not in (event.xdata, event.ydata):
if(event.button == 3):
i=int(event.xdata) #x-koord
j=int(event.ydata) #y-koord
tile_x=int(i*(1/ratio)/512)
tile_y=int(j*(1/ratio)/512)
label=image_name+"_"+str(tile_x)+"_"+str(tile_y)
button1 = tk.Button(command=confirm(label))
fig.canvas.mpl_connect('button_press_event', onclick)
fig.canvas.mpl_connect('motion_notify_event', on_mouse_move)
#Display the label and tile info as the cursor moves
def myformatter(**kwarg):
label = '{x:.0f},{y:.0f}'.format(**kwarg)
i=int(label.split(",")[0]) #x-koord
j=int(label.split(",")[1]) #y-koord
RGB=tuple(img[j, i])
label=color_to_label.get(RGB)
tile_x=int(i*(1/ratio)/512)
tile_y=int(j*(1/ratio)/512)
label="tile_"+str(tile_x)+"_"+str(tile_y)+"\n"+str(label)
return label
mpldatacursor.datacursor(hover=True, bbox=dict(alpha=1, fc='w'),formatter=myformatter)
mng = plt.get_current_fig_manager()
mng.resize(*mng.window.maxsize())
ax.axis('off')
plt.show()