Skip to content

Commit 10b6a55

Browse files
authored
GradMix Method for SONNET
1 parent f71cf41 commit 10b6a55

File tree

1 file changed

+354
-0
lines changed

1 file changed

+354
-0
lines changed

synthesize_image.py

+354
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
from multiprocessing import pool
2+
from operator import index
3+
import numpy as np
4+
import matplotlib.pyplot as plt
5+
import scipy.io as sio
6+
import cv2
7+
from matplotlib import cm
8+
from torch_cluster import neighbor_sampler
9+
import xlsxwriter
10+
import glob
11+
import os
12+
import math
13+
import pyheal
14+
import skimage.filters
15+
from scipy.ndimage.morphology import binary_dilation
16+
from scipy.ndimage.morphology import (distance_transform_cdt,
17+
distance_transform_edt)
18+
import skimage.filters
19+
from skimage.morphology import disk
20+
import time
21+
from matplotlib.colors import ListedColormap
22+
import random
23+
# from imgaug import augmenters as iaa
24+
# import imgaug as ia
25+
# from imgaug.augmentables.segmaps import SegmentationMapsOnImage
26+
# ia.seed(4)
27+
'''
28+
Tumor: 60
29+
EBV: 173
30+
Benign: 157
31+
'''
32+
33+
####
34+
def bounding_box(img):
35+
rows = np.any(img, axis=1)
36+
cols = np.any(img, axis=0)
37+
rmin, rmax = np.where(rows)[0][[0, -1]]
38+
cmin, cmax = np.where(cols)[0][[0, -1]]
39+
# due to python indexing, need to add 1 to max
40+
# else accessing will be 1px in the box, not out
41+
rmax += 1
42+
cmax += 1
43+
return [rmin, rmax, cmin, cmax]
44+
45+
46+
def rotate(image, angle, center=None, scale=1.0):
47+
h, w = image.shape[:2]
48+
if center is None:
49+
center = (w/2, h/2)
50+
M = cv2.getRotationMatrix2D(center, angle, scale)
51+
rotated = cv2.warpAffine(image, M, (w, h))
52+
return rotated
53+
54+
def size_calculate(major_id, inst_map):
55+
size_1 = np.sum((inst_map == (major_id + 1))>0)
56+
return size_1
57+
58+
def pick_minor_index(pool_minor, size_1, major_id=0):
59+
if major_id == 234:
60+
ann_2 = sio.loadmat('/media/tandoan/data2/Gastric_Cancer/Train/Labels/DB-0003_tumor_1.mat')
61+
basename = 'DB-0003_tumor_1'
62+
minor_class_id = 357
63+
return basename, ann_2, minor_class_id, pool_minor
64+
elif major_id == 29:
65+
ann_2 = sio.loadmat('/media/tandoan/data2/Gastric_Cancer/Train/Labels/DB-0017_3.mat')
66+
basename = 'DB-0017_3'
67+
minor_class_id = 281
68+
return basename, ann_2, minor_class_id, pool_minor
69+
70+
for basename, minor_class_list in pool_minor.items():
71+
ann_2 = sio.loadmat('/media/tandoan/data2/Gastric_Cancer/Train/Labels/' + basename + '.mat')
72+
inst_map_2 = ann_2['inst_map']
73+
for minor_class_id in minor_class_list:
74+
mask_2 = (inst_map_2 == (minor_class_id+1)).astype(np.uint8)
75+
size_2 = np.sum(mask_2>0)
76+
# if size_1 >= 2.3*size_2:
77+
if size_1 >= 2.3 * size_2:
78+
pool_minor[basename].remove(minor_class_id)
79+
return basename, ann_2, minor_class_id, pool_minor
80+
81+
# file_1_list = glob.glob('/media/tandoan/data2/Gastric_Cancer/Train/Images/*.tif')
82+
# file_1_list.remove('/media/tandoan/data2/Gastric_Cancer/Train/Images/DB-0003_tumor_1.tif')
83+
# for file_1 in file_1_list:
84+
# print(file_1)
85+
file_1 = '/media/tandoan/data2/Gastric_Cancer/Train/Images/DB-0003_tumor_1.tif'
86+
eps = 5
87+
img_list = glob.glob('/media/tandoan/data2/Gastric_Cancer/Train/Images/*.tif')
88+
random.shuffle(img_list)
89+
img_list.remove(file_1)
90+
91+
file_name = os.path.basename(file_1)
92+
basename = file_name.split('.')[0]
93+
img = cv2.imread('/media/tandoan/data2/Gastric_Cancer/Train/Images/' + file_name)
94+
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
95+
96+
ann = sio.loadmat('/media/tandoan/data2/Gastric_Cancer/Train/Labels/' + basename + '.mat')
97+
inst_map = ann['inst_map']
98+
inst_map_out = inst_map.copy()
99+
type_map = ann['type_map']
100+
class_arr = np.squeeze(ann['inst_type'])
101+
class_arr[(class_arr == 1) | (class_arr == 2) | (class_arr == 9) | (class_arr == 10)] = 1
102+
class_arr[(class_arr == 4) | (class_arr == 5) | (class_arr == 6) | (class_arr == 7)] = 2
103+
class_arr[(class_arr == 8) | (class_arr == 3)] = 3
104+
# class_arr[(class_arr == 3) | (class_arr == 4)] = 3
105+
# class_arr[(class_arr == 5) | (class_arr == 6) | (class_arr == 7)] = 4
106+
class_arr_copy = class_arr.copy()
107+
# bbox_ann = ann['bbox'] # [y1, y2, x1, x2]
108+
cent_ann = ann['inst_centroid'] # x, y
109+
for i, cent in enumerate(cent_ann): # old_value = 30
110+
if ((cent[1] < 30) or
111+
(cent[1] > (inst_map.shape[0]-30)) or
112+
(cent[0] < 30) or
113+
(cent[0] > (inst_map.shape[1]-30))):
114+
class_arr_copy[i] = 0
115+
nuc_color = img * (inst_map[...,np.newaxis] > 0)
116+
avg_color_1 = [
117+
np.sum(nuc_color[...,0]) / np.sum(nuc_color[...,0]>0),
118+
np.sum(nuc_color[...,1]) / np.sum(nuc_color[...,1]>0),
119+
np.sum(nuc_color[...,2]) / np.sum(nuc_color[...,2]>0)
120+
]
121+
122+
major_class_idx = list(np.where(class_arr_copy == 2)[0]) + list(np.where(class_arr_copy == 3)[0])
123+
# list(np.where(class_arr_copy == 4)[0])
124+
picked_major_class = list(np.random.choice(major_class_idx, int(0.4 * len(major_class_idx)), replace=False))
125+
picked_major_class = sorted(picked_major_class, key=lambda x: size_calculate(x, inst_map))
126+
try:
127+
picked_major_class.remove(234)
128+
except ValueError:
129+
pass
130+
try:
131+
picked_major_class.remove(29)
132+
except ValueError:
133+
pass
134+
picked_major_class.insert(0, 234)
135+
picked_major_class.insert(0, 29)
136+
137+
final = img.copy()
138+
inpainted = img.copy()
139+
140+
pool_minor = {}
141+
class_arr_2 = class_arr_copy.copy()
142+
cent_ann_2 = cent_ann.copy()
143+
minor_class_idx = list(np.where(class_arr_2 == 1)[0])
144+
145+
pool_minor[basename] = minor_class_idx
146+
for file in img_list:
147+
file_name = os.path.basename(file)
148+
basename_1 = file_name.split('.')[0]
149+
ann_2 = sio.loadmat('/media/tandoan/data2/Gastric_Cancer/Train/Labels/' + basename_1 + '.mat')
150+
inst_map_2 = ann['inst_map']
151+
class_arr_2 = np.squeeze(ann_2['inst_type'])
152+
class_arr_2[(class_arr_2 == 1) | (class_arr_2 == 2) | (class_arr_2 == 9) | (class_arr_2 == 10)] = 1
153+
class_arr_2[(class_arr_2 == 4) | (class_arr_2 == 5) | (class_arr_2 == 6) | (class_arr_2 == 7)] = 2
154+
class_arr_2[(class_arr_2 == 8) | (class_arr_2 == 3)] = 3
155+
# class_arr[(class_arr == 3) | (class_arr == 4)] = 3
156+
# class_arr[(class_arr == 5) | (class_arr == 6) | (class_arr == 7)] = 4
157+
cent_ann_2 = ann_2['inst_centroid']
158+
for i, cent in enumerate(cent_ann_2):
159+
if ((cent[1] < 30) or
160+
(cent[1] > (inst_map_2.shape[0]-30)) or
161+
(cent[0] < 30) or
162+
(cent[0] > (inst_map_2.shape[1]-30))):
163+
class_arr_2[i] = 0
164+
minor_class_idx = list(np.where(class_arr_2 == 1)[0])
165+
pool_minor[basename_1] = minor_class_idx
166+
167+
# mask_inpaint = np.zeros_like(inst_map)
168+
# for major_class_idx in picked_major_class:
169+
# mask_inpaint += (inst_map == (major_class_idx+1)).astype(np.uint8)
170+
# mask_inpaint = binary_dilation(mask_inpaint, iterations=2).astype(np.uint8)
171+
# pyheal.inpaint(final, mask_inpaint, eps)
172+
# pyheal.inpaint(inpainted, mask_inpaint, eps)
173+
174+
for major_class_idx in picked_major_class:
175+
mask_0 = (inst_map == (major_class_idx+1)).astype(np.uint8)
176+
177+
mask = binary_dilation(mask_0, iterations=2).astype(np.uint8)
178+
cent1 = cent_ann[major_class_idx]
179+
bbox1 = bounding_box(mask)
180+
h1, w1 = bbox1[1] - bbox1[0], bbox1[3] - bbox1[2]
181+
size_1 = np.sum(mask>0)
182+
183+
# try:
184+
basename_2, ann_2, index_2, pool_minor = pick_minor_index(pool_minor, size_1, major_id=major_class_idx)
185+
# except TypeError:
186+
# continue
187+
img_2_ori = cv2.imread('/media/tandoan/data2/Gastric_Cancer/Train/Images/' + basename_2 + '.tif')
188+
img_2_ori = cv2.cvtColor(img_2_ori, cv2.COLOR_BGR2RGB)
189+
img_2 = img_2_ori.copy()
190+
inst_map_2 = ann_2['inst_map']
191+
mask_2 = (inst_map_2 == (index_2+1)).astype(np.uint8)
192+
cent_ann_2 = ann_2['inst_centroid']
193+
cent_2 = cent_ann_2[index_2]
194+
bbox2 = bounding_box(mask_2)
195+
h2, w2 = bbox2[1] - bbox2[0], bbox2[3] - bbox2[2]
196+
197+
img_2[...,0][mask_2 > 0] = (img_2_ori[...,0][mask_2 > 0] + avg_color_1[0]) / 2
198+
img_2[...,1][mask_2 > 0] = (img_2_ori[...,1][mask_2 > 0] + avg_color_1[1]) / 2
199+
img_2[...,2][mask_2 > 0] = (img_2_ori[...,2][mask_2 > 0] + avg_color_1[2]) / 2
200+
201+
class_arr[major_class_idx] = 1
202+
pyheal.inpaint(final, mask, eps)
203+
pyheal.inpaint(inpainted, mask, eps)
204+
inst_map_out[inst_map == (major_class_idx+1)] = 0
205+
206+
img_copy = img.copy()
207+
img_copy[bbox1[0]:bbox1[1], bbox1[2]:bbox1[3], :] = img_2[
208+
int(np.round(cent_2[1])-h1/2):int(np.round(cent_2[1])+h1/2),
209+
int(np.round(cent_2[0])-w1/2):int(np.round(cent_2[0])+w1/2),
210+
:
211+
]
212+
mask_translated = np.zeros_like(mask)
213+
mask_translated[int(np.round(cent1[1])-h2/2):int(np.round(cent1[1])+h2/2),
214+
int(np.round(cent1[0])-w2/2):int(np.round(cent1[0])+w2/2)] = mask_2[bbox2[0]:bbox2[1], bbox2[2]:bbox2[3]]
215+
inst_map_out[mask_translated > 0] = major_class_idx + 1
216+
mask = ((mask + mask_translated)>0).astype(np.uint8)
217+
mask_substract = mask - mask_translated
218+
cdt_map = distance_transform_cdt(1 - mask_translated).astype('float32')
219+
cdt_map[mask==0] = 0
220+
cdt_map[mask_substract>0] -= 1
221+
cdt_map[mask_substract>0] /= np.amax(cdt_map[mask_substract>0])
222+
cdt_map[mask_substract>0] = 1 - cdt_map[mask_substract>0]
223+
cdt_map[mask_translated > 0] = 1
224+
plt.figure(dpi=400, figsize=(8.0, 8.0))
225+
plt.gca().set_axis_off()
226+
plt.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0)
227+
plt.margins(0,0)
228+
plt.gca().xaxis.set_major_locator(plt.NullLocator())
229+
plt.gca().yaxis.set_major_locator(plt.NullLocator())
230+
plt.tight_layout()
231+
jet = cm.get_cmap('viridis', 255)
232+
jet = jet(np.linspace(0, 1, 255))
233+
jet[0, :] = np.array([0/256, 0/256, 0/256, 1])
234+
# jet[1, :] = np.array([255/256, 0/256, 0/256, 1])
235+
jet = ListedColormap(jet)
236+
plt.imshow(cdt_map[659:659+100, 1:1+100], cmap=jet)
237+
plt.savefig("/media/tandoan/data2/Gastric_Cancer/Train/Synthesized_Overlay/_zoom_cdt_1.tif", bbox_inches = 'tight', pad_inches = 0)
238+
plt.show()
239+
# final = final*(1-mask[...,np.newaxis]) + img_copy*mask_translated[...,np.newaxis] + (img_copy*(cdt_map*mask_substract)[...,np.newaxis]).astype(np.uint8) + (final*((1-cdt_map)*mask_substract)[...,np.newaxis]).astype(np.uint8)
240+
final = (img_copy * cdt_map[...,np.newaxis]).astype(np.uint8) + (final * (1 - cdt_map)[...,np.newaxis]).astype(np.uint8)
241+
# smooth_synth = skimage.filters.gaussian(final, sigma=(2.0, 2.0), truncate=3.5, multichannel=True, preserve_range=True).astype(np.uint8)
242+
final_smooth = np.stack([skimage.filters.median(final[...,0], disk(1)), skimage.filters.median(final[...,1], disk(1)), skimage.filters.median(final[...,2], disk(5))], axis=2)
243+
final = (final * (1 - mask_substract[...,np.newaxis])).astype(np.uint8) + (final_smooth.astype(np.float32) * mask_substract[...,np.newaxis]).astype(np.uint8)
244+
245+
final = cv2.cvtColor(final, cv2.COLOR_RGB2BGR)
246+
inpainted = cv2.cvtColor(inpainted, cv2.COLOR_BGR2RGB)
247+
type_map = np.zeros_like(type_map)
248+
inst_list = list(np.unique(inst_map_out))
249+
inst_type = []
250+
inst_list.remove(0)
251+
for inst_id in inst_list:
252+
type_map[inst_map_out == int(inst_id)] = class_arr[int(inst_id) - 1]
253+
inst_type.append(class_arr[int(inst_id-1)])
254+
# cv2.imwrite('/media/tandoan/data2/Gastric_Cancer/Train/Synthesized_Images/' + basename + '_synthesized.tif', final)
255+
# cv2.imwrite('/media/tandoan/data2/Gastric_Cancer/Train/Inpainted/' + basename + '_inpainted.tif', inpainted)
256+
# sio.savemat('/media/tandoan/data2/Gastric_Cancer/Train/Synthesized_Labels/' + basename + '_synthesized.mat',
257+
# {'inst_map' : inst_map_out,
258+
# 'type_map' : type_map,
259+
# 'inst_type' : np.array(class_arr[:, None]),
260+
# 'inst_centroid' : cent_ann,
261+
# })
262+
263+
264+
# major_class_len = len(picked_major_class) - int(0.6*len(picked_major_class))
265+
# j = 0
266+
# count = 0
267+
# while j < major_class_len:
268+
# count += 1
269+
# major_class_idx = picked_major_class[int(0.6*len(picked_major_class))+j]
270+
# mask_0 = (inst_map == (major_class_idx + 1)).astype(np.uint8)
271+
272+
273+
# mask = binary_dilation(mask_0, iterations=2).astype(np.uint8)
274+
# cent1 = cent_ann[major_class_idx]
275+
# bbox1 = bounding_box(mask)
276+
# h1, w1 = bbox1[1] - bbox1[0], bbox1[3] - bbox1[2]
277+
278+
# img_2_path = np.random.choice(img_list, 1)[0]
279+
# while img_2_path == file:
280+
# img_2_path = np.random.choice(img_list, 1)[0]
281+
# file_name_2 = os.path.basename(img_2_path)
282+
# basename_2 = file_name_2.split('.')[0]
283+
# img_2_ori = cv2.imread(img_2_path)
284+
# img_2_ori = cv2.cvtColor(img_2_ori, cv2.COLOR_BGR2RGB)
285+
# img_2 = img_2_ori.copy()
286+
# img_2[...,0] = (img_2_ori[...,0] + avg_color_1[0]) / 2
287+
# img_2[...,1] = (img_2_ori[...,1] + avg_color_1[1]) / 2
288+
# img_2[...,2] = (img_2_ori[...,2] + avg_color_1[2]) / 2
289+
# ann_2 = sio.loadmat('/media/tandoan/data2/Gastric_Cancer/Train/Labels/' + basename_2 + '.mat')
290+
# inst_map_2 = ann_2['inst_map']
291+
# class_arr_2 = np.squeeze(ann_2['inst_type'])
292+
# class_arr_2[(class_arr_2 == 1) | (class_arr_2 == 2) | (class_arr_2 == 9) | (class_arr_2 == 10)] = 1
293+
# class_arr_2[(class_arr_2 == 4) | (class_arr_2 == 5) | (class_arr_2 == 6) | (class_arr_2 == 7)] = 2
294+
# class_arr_2[(class_arr_2 == 8) | (class_arr_2 == 3)] = 3
295+
# cent_ann_2 = ann_2['inst_centroid']
296+
# for i, cent in enumerate(cent_ann_2):
297+
# if ((cent[1] < 30) or
298+
# (cent[1] > (inst_map_2.shape[0]-30)) or
299+
# (cent[0] < 30) or
300+
# (cent[0] > (inst_map_2.shape[1]-30))):
301+
# class_arr_2[i] = 0
302+
# minor_class_idx = list(np.where(class_arr_2 == 1)[0])
303+
# index_2 = np.random.choice(minor_class_idx, 1)[0]
304+
# mask_2 = (inst_map_2 == (index_2 + 1)).astype(np.uint8)
305+
# cent_2 = cent_ann_2[index_2]
306+
# bbox2 = bounding_box(mask_2)
307+
# h2, w2 = bbox2[1] - bbox2[0], bbox2[3] - bbox2[2]
308+
309+
# size_1 = np.sum(mask>0)
310+
# size_2 = np.sum(mask_2>0)
311+
# if count > 7:
312+
# j += 1
313+
# continue
314+
# if size_1 < 2.3*size_2:
315+
# continue
316+
# class_arr[major_class_idx] = 1
317+
# inst_map_out[inst_map == (major_class_idx+1)] = 0
318+
# pyheal.inpaint(final, mask, eps)
319+
# j += 1
320+
# count = 0
321+
# img_copy = img.copy()
322+
# img_copy[bbox1[0]:bbox1[1], bbox1[2]:bbox1[3], :] = img_2[
323+
# int(np.round(cent_2[1])-h1/2):int(np.round(cent_2[1])+h1/2),
324+
# int(np.round(cent_2[0])-w1/2):int(np.round(cent_2[0])+w1/2),
325+
# :
326+
# ]
327+
# mask_translated = np.full_like(mask, 0)
328+
# mask_translated[int(np.round(cent1[1])-h2/2):int(np.round(cent1[1])+h2/2),
329+
# int(np.round(cent1[0])-w2/2):int(np.round(cent1[0])+w2/2)] = mask_2[bbox2[0]:bbox2[1], bbox2[2]:bbox2[3]]
330+
# inst_map_out[mask_translated > 0] = major_class_idx + 1
331+
# mask_substract = mask - mask_translated
332+
# cdt_map = distance_transform_cdt(mask).astype('float32')
333+
# cdt_map = cdt_map / np.amax(cdt_map)
334+
# final = final*(1-mask[...,np.newaxis]) + img_copy*mask_translated[...,np.newaxis] + (img_copy*(cdt_map*mask_substract)[...,np.newaxis]).astype(np.uint8) + (final*((1-cdt_map)*mask_substract)[...,np.newaxis]).astype(np.uint8)
335+
336+
# final = cv2.cvtColor(final, cv2.COLOR_RGB2BGR)
337+
# cv2.imwrite('/media/tandoan/data2/Gastric_Cancer/Train/Synthesized_Images/' + basename + '_synthesized.tif', final)
338+
# type_map = np.zeros_like(type_map)
339+
# inst_list = list(np.unique(inst_map_out))
340+
# inst_type = []
341+
# inst_list.remove(0)
342+
# for inst_id in inst_list:
343+
# type_map[inst_map_out == inst_id] = class_arr[inst_id - 1]
344+
# inst_type.append(class_arr[inst_id-1])
345+
346+
# sio.savemat('/media/tandoan/data2/Gastric_Cancer/Train/Synthesized_Labels/' + basename + '_synthesized.mat',
347+
# {'inst_map' : inst_map_out,
348+
# 'type_map' : type_map,
349+
# 'inst_type' : np.array(class_arr[:, None]),
350+
# 'inst_centroid' : cent_ann,
351+
# })
352+
353+
354+

0 commit comments

Comments
 (0)