Ignaciobfp commited on
Commit
4dc5014
1 Parent(s): bca6019

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +308 -0
app.py ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import from_pretrained_fastai
2
+ import gradio as gr
3
+ from fastai.vision.all import *
4
+ import PIL
5
+ import torchvision.transforms as transforms
6
+
7
+ ##Extras por si pudiera reconstruir la imagen en HF tambi茅n
8
+ import numpy as np
9
+ import os
10
+ import cv2
11
+
12
+ def extract_subimages(image : np.ndarray, wwidth, wheight, overlap_fraction):
13
+ """
14
+ Extracts subimages of the input image using a moving window of size (wwidth, wheight)
15
+ with the specified overlap fraction. Returns a tuple (subimages, coords) where subimages
16
+ is a list of subimages and coords is a list of tuples (x, y) indicating the top left corner
17
+ coordinates of each subimage in the input image.
18
+ """
19
+ subimages = []
20
+ coords = []
21
+ height, width, channels = image.shape
22
+ if channels > 3:
23
+ image = image[:,:,0:3]
24
+ channels = 3
25
+ overlap = int(max(0, min(overlap_fraction, 1)) * min(wwidth, wheight))
26
+ y = 0
27
+ while y + wheight <= height:
28
+ x = 0
29
+ while x + wwidth <= width:
30
+ subimage = image[y:y+wheight, x:x+wwidth, :]
31
+ subimages.append(subimage)
32
+ coords.append((x, y))
33
+ x += wwidth - overlap
34
+ y += wheight - overlap
35
+ if y < height:
36
+ y = height - wheight
37
+ x = 0
38
+ while x + wwidth <= width:
39
+ subimage = image[y:y+wheight, x:x+wwidth, :]
40
+ subimages.append(subimage)
41
+ coords.append((x, y))
42
+ x += wwidth - overlap
43
+ if x < width:
44
+ x = width - wwidth
45
+ subimage = image[y:y+wheight, x:x+wwidth, :]
46
+ subimages.append(subimage)
47
+ coords.append((x, y))
48
+ if x < width:
49
+ x = width - wwidth
50
+ y = 0
51
+ while y + wheight <= height:
52
+ subimage = image[y:y+wheight, x:x+wwidth, :]
53
+ subimages.append(subimage)
54
+ coords.append((x, y))
55
+ y += wheight - overlap
56
+ if y < height:
57
+ y = height - wheight
58
+ subimage = image[y:y+wheight, x:x+wwidth, :]
59
+ subimages.append(subimage)
60
+ coords.append((x, y))
61
+ return subimages, coords
62
+
63
+ # Si no hay archivos tif (labels) no se tratan, no hace falta considerarlo
64
+ def generate_and_save_subimages(path, output_dir_images, output_dir_labels = None):
65
+ if output_dir_labels:
66
+ if not os.path.exists(output_dir_labels):
67
+ os.makedirs(output_dir_labels)
68
+
69
+ if not os.path.exists(output_dir_images):
70
+ os.makedirs(output_dir_images)
71
+
72
+ for filename in os.listdir(path):
73
+ if filename.endswith(".png") or filename.endswith(".tif"):
74
+ filepath = os.path.join(path, filename)
75
+ image = cv2.imread(filepath)
76
+ subimages, coords = extract_subimages(image, 400, 400, 0.66)
77
+ for i, subimage in enumerate(subimages):
78
+ if filename.endswith(".png"):
79
+ output_filename = os.path.join(output_dir_images, f"{filename.rsplit('.', 1)[0]}_{coords[i][0]}_{coords[i][1]}.png")
80
+ cv2.imwrite(output_filename, subimage)
81
+ else:
82
+ if output_dir_labels:
83
+ output_filename = os.path.join(output_dir_labels, f"{filename.rsplit('.', 1)[0]}_{coords[i][0]}_{coords[i][1]}.tif")
84
+ cv2.imwrite(output_filename, subimage)
85
+
86
+ def generate_and_save_subimages_nolabel(path, output_dir_images, olverlap=0.0, imagesformat="png", split_in_dirs=True):
87
+ for entry in os.scandir(path):
88
+ if entry.is_file() and entry.name.lower().endswith(imagesformat):
89
+ filepath = entry.path
90
+ gss_single(filepath, output_dir_images, olverlap, imagesformat, split_in_dirs)
91
+
92
+ def gss_single(filepath, output_dir_images, olverlap=0.0, imagesformat="png", split_in_dirs=True):
93
+ image = cv2.imread(filepath)
94
+
95
+ if split_in_dirs:
96
+ dir_this_image = Path(output_dir_images)/filepath.rsplit('.', 1)[0]
97
+ os.makedirs(dir_this_image, exist_ok=True)
98
+ else:
99
+ os.makedirs(output_dir_images, exist_ok=True)
100
+
101
+ subimages, coords = extract_subimages(image, 400, 400, olverlap)
102
+ for i, subimage in enumerate(subimages):
103
+ if split_in_dirs:
104
+ output_filename = os.path.join(dir_this_image, f"{filepath.rsplit('.', 1)[0]}_{coords[i][0]}_{coords[i][1]}.png")
105
+ else:
106
+ output_filename = os.path.join(output_dir_images, f"{filepath.rsplit('.', 1)[0]}_{coords[i][0]}_{coords[i][1]}.png")
107
+ cv2.imwrite(output_filename, subimage)
108
+
109
+ def split_windows_in_folders(input_images_folder, output_images_folder):
110
+ for filename in os.listdir(input_images_folder):
111
+ dir_this_image = Path(output_images_folder)/filename.rsplit('.', 1)[0]
112
+ os.makedirs(dir_this_image, exist_ok=True)
113
+ if filename.endswith(".png"):
114
+ print(str(dir_this_image))
115
+ filepath = os.path.join(path, filename)
116
+ image = cv2.imread(filepath)
117
+ subimages, coords = extract_subimages(image, 400, 400, 0)
118
+ for i, subimage in enumerate(subimages):
119
+ output_filename = os.path.join(dir_this_image, f"{filename.rsplit('.', 1)[0]}_{coords[i][0]}_{coords[i][1]}.png")
120
+ cv2.imwrite(output_filename, subimage)
121
+
122
+
123
+ def subimages_from_directory(directorio):
124
+ # Define el directorio a recorrer
125
+ directorio = directorio
126
+
127
+ # Define la expresi贸n regular para buscar los n煤meros X e Y en el nombre de archivo
128
+ patron = re.compile(r"(.*)_(\d+)_(\d+)\.(png|jpg|tif)")
129
+
130
+ windowlist = []
131
+ coords = []
132
+
133
+ # Recorre el directorio en busca de im谩genes
134
+ for filename in os.listdir(directorio):
135
+ match = patron.search(filename)
136
+ if match:
137
+ origname = match.group(1)
138
+ x = int(match.group(2))
139
+ y = int(match.group(3))
140
+ #print(f"El archivo {filename} tiene los n煤meros X={x} e Y={y}")
141
+ img = cv2.imread(os.path.join(directorio, filename))
142
+ windowlist.append(img)
143
+ coords.append((x, y))
144
+
145
+ # Ordena las listas por coordenadas X e Y
146
+ windowlist, coords = zip(*sorted(zip(windowlist, coords), key=lambda pair: (pair[1][0], pair[1][1])))
147
+ wh, ww, chan = windowlist[0].shape
148
+ origsize = tuple(elem1 + elem2 for elem1, elem2 in zip(coords[-1], (wh,ww)))
149
+
150
+ return windowlist, coords, wh, ww, chan, origsize
151
+
152
+ def subimages_onlypath(directorio):
153
+ # Define el directorio a recorrer
154
+ directorio = directorio
155
+ pathlist = []
156
+
157
+ patron = re.compile(r"(.*)_(\d+)_(\d+)\.(png|jpg|tif)")
158
+
159
+ for filename in os.listdir(directorio):
160
+ match = patron.search(filename)
161
+ if match:
162
+ pathlist.append(os.path.join(directorio, filename))
163
+
164
+ return pathlist
165
+
166
+ def ReconstructFromMW(windowlist, coords, wh, ww, chan, origsize):
167
+ canvas = np.zeros((origsize[1], origsize[0], chan), dtype=np.uint8)
168
+ for idx, window in enumerate(windowlist):
169
+ canvas[coords[idx][1]:coords[idx][1]+wh, coords[idx][0]:coords[idx][0]+ww, :] = window
170
+ return canvas
171
+
172
+ def get_list_tp(path):
173
+ list_to_process = [] # Inicializar la lista que contendr谩 los nombres de los subdirectorios
174
+ list_names = []
175
+ # Recorrer los elementos del directorio
176
+ for element in os.scandir(path):
177
+ # Verificar si el elemento es un directorio
178
+ if element.is_dir():
179
+ # Agregar el nombre del subdirectorio a la lista
180
+ windowlist, coords, wh, ww, chan, origsize = subimages_from_directory(element)
181
+ list_to_process.append(ReconstructFromMW(windowlist, coords, wh, ww, chan, origsize))
182
+ list_names.append(element.name)
183
+ return list_to_process, list_names
184
+
185
+ def get_paths_tp(path):
186
+ list_to_process = [] # Inicializar la lista que contendr谩 los nombres de los subdirectorios
187
+ # Recorrer los elementos del directorio
188
+ for element in os.scandir(path):
189
+ # Verificar si el elemento es un directorio
190
+ if element.is_dir():
191
+ # Agregar el nombre del subdirectorio a la lista
192
+ list_to_process.append(subimages_onlypath(element))
193
+ return list_to_process
194
+
195
+ def process_multifolder(process_folders, result_folder):
196
+ for folder in process_folders:
197
+ folname = os.path.basename(os.path.dirname(folder[0]))
198
+ destname = Path(result_folder)/folname
199
+ os.makedirs(destname, exist_ok=True)
200
+ for subimagepath in folder:
201
+ img = PIL.Image.open(subimagepath)
202
+ image = transforms.Resize((400,400))(img)
203
+ tensor = transform_image(image=image)
204
+ with torch.no_grad():
205
+ outputs = model(tensor)
206
+ outputs = torch.argmax(outputs,1)
207
+ mask = np.array(outputs.cpu())
208
+ mask[mask==1]=255
209
+ mask=np.reshape(mask,(400,400))
210
+ mask_img = Image.fromarray(mask.astype('uint8'))
211
+
212
+ filename = os.path.basename(subimagepath)
213
+ new_image_path = os.path.join(result_folder, folname, filename)
214
+ mask_img.save(new_image_path)
215
+
216
+ def recombine_windows(results_folder_w, result_f_rec):
217
+ imgs, nombres = get_list_tp(results_folder_w)
218
+ os.makedirs(result_f_rec, exist_ok=True)
219
+
220
+ for idx, image in enumerate(imgs):
221
+ img = Image.fromarray(image)
222
+ new_image_path = os.path.join(result_f_rec, nombres[idx] + '.tif')
223
+ img.save(new_image_path, compression='tiff_lzw')
224
+ return new_image_path
225
+
226
+ def process_single_image(single_image_path, base_f, pro_f, rsw_f, rsd_f):
227
+ gss_single(single_image_path, pro_f, 0, "tif", True)
228
+ process_multifolder(get_paths_tp(pro_f),rsw_f)
229
+ pt = recombine_windows(rsw_f,rsd_f)
230
+ shutil.rmtree(pro_f)
231
+ shutil.rmtree(rsw_f)
232
+ #copiar_info_georref(single_image_path, pt)
233
+ return pt
234
+
235
+ # from osgeo import gdal, osr
236
+
237
+ # def copiar_info_georref(entrada, salida):
238
+ # try:
239
+ # # Abrir el archivo GeoTIFF original
240
+ # original_dataset = gdal.Open(entrada)
241
+
242
+ # # Obtener la informaci贸n de georreferenciaci贸n del archivo original
243
+ # original_projection = original_dataset.GetProjection()
244
+ # original_geotransform = original_dataset.GetGeoTransform()
245
+
246
+ # # Abrir la imagen resultado
247
+ # result_dataset = gdal.Open(salida, gdal.GA_Update)
248
+
249
+ # # Copiar la informaci贸n de georreferenciaci贸n del archivo original a la imagen resultado
250
+ # result_dataset.SetProjection(original_projection)
251
+ # result_dataset.SetGeoTransform(original_geotransform)
252
+
253
+ # # Cerrar los archivos
254
+ # original_dataset = None
255
+ # result_dataset = None
256
+
257
+ # except Exception as e:
258
+ # print("Error: ", e)
259
+
260
+ ###FIN de extras
261
+
262
+
263
+
264
+ #repo_id = "Ignaciobfp/segmentacion-dron-marras"
265
+ #learner = from_pretrained_fastai(repo_id)
266
+
267
+ device = torch.device("cpu")
268
+ #model = learner.model
269
+ model = torch.jit.load("modelo_marras.pth")
270
+ model = model.cpu()
271
+
272
+ def transform_image(image):
273
+ my_transforms = transforms.Compose([transforms.ToTensor(),
274
+ transforms.Normalize(
275
+ [0.485, 0.456, 0.406],
276
+ [0.229, 0.224, 0.225])])
277
+ image_aux = image
278
+ return my_transforms(image_aux).unsqueeze(0).to(device)
279
+
280
+
281
+ # Definimos una funci贸n que se encarga de llevar a cabo las predicciones
282
+ def predict(img):
283
+ img_pil = PIL.Image.fromarray(img, 'RGB')
284
+ image = transforms.Resize((400,400))(img_pil)
285
+ tensor = transform_image(image=image)
286
+ model.to(device)
287
+ with torch.no_grad():
288
+ outputs = model(tensor)
289
+ outputs = torch.argmax(outputs,1)
290
+ mask = np.array(outputs.cpu())
291
+ mask[mask==1]=255
292
+ mask=np.reshape(mask,(400,400))
293
+ return Image.fromarray(mask.astype('uint8'))
294
+
295
+ def predict_full(img):
296
+ single_image_path = "tmp.tif"
297
+ base_f = "."
298
+ pro_f = "processing"
299
+ rsw_f = "results_windows"
300
+ rsd_f = "results_together"
301
+ destpath = process_single_image(single_image_path, base_f, pro_f, rsw_f, rsd_f)
302
+ im = Image.open(destpath)
303
+ return im
304
+
305
+ # Creamos la interfaz y la lanzamos.
306
+ gr.Interface(fn=predict_full, inputs=gr.inputs.Image(), outputs=gr.outputs.Image(type="pil")).launch(share=False)
307
+
308
+