Spaces:
Runtime error
Runtime error
Jose Pablo Navarro
commited on
Commit
•
f039b6d
1
Parent(s):
7747e17
utils
Browse files- utils/.DS_Store +0 -0
- utils/Generator.py +77 -0
- utils/utils.py +280 -0
utils/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
utils/Generator.py
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch.nn as nn
|
2 |
+
import torch
|
3 |
+
|
4 |
+
class Generator(torch.nn.Module):
|
5 |
+
def __init__(self, nc_input=1, nc_output=1, ndf=128, nz=128, ngf=128, dropout_rate = 0.5 ):
|
6 |
+
super(Generator, self).__init__()
|
7 |
+
|
8 |
+
self.encoder = nn.Sequential(
|
9 |
+
nn.Dropout(0.05),
|
10 |
+
# input is (nc) x 64 x 64
|
11 |
+
nn.Conv2d(nc_input, ndf, 4, 2, 1, bias=False),
|
12 |
+
nn.LeakyReLU(0.2, inplace=True),
|
13 |
+
# state size. (ndf) x 32 x 32
|
14 |
+
nn.Conv2d(ndf, ndf * 2, 4, 2, 1, bias=False),
|
15 |
+
nn.BatchNorm2d(ndf * 2),
|
16 |
+
nn.LeakyReLU(0.2, inplace=True),
|
17 |
+
# state size. (ndf*2) x 16 x 16
|
18 |
+
nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False),
|
19 |
+
nn.BatchNorm2d(ndf * 4),
|
20 |
+
nn.LeakyReLU(0.2, inplace=True),
|
21 |
+
# state size. (ndf*4) x 8 x 8
|
22 |
+
nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
|
23 |
+
nn.BatchNorm2d(ndf * 8),
|
24 |
+
nn.LeakyReLU(0.2, inplace=True),
|
25 |
+
# state size. (ndf*8) x 4 x 4
|
26 |
+
nn.Conv2d(ndf * 8, 1, 1, 1, 0, bias=False),
|
27 |
+
##nn.Conv2d(1, 1, 5, 1, 0, bias=False),
|
28 |
+
##nn.Sigmoid()
|
29 |
+
)
|
30 |
+
|
31 |
+
self.linearEncoder = nn.Sequential(
|
32 |
+
nn.Linear(64, 128)
|
33 |
+
)
|
34 |
+
|
35 |
+
self.decoder = nn.Sequential(
|
36 |
+
# input is Z, going into a convolution
|
37 |
+
nn.Dropout(0.05),
|
38 |
+
nn.ConvTranspose2d(nz, ngf * 8, 4, 1, 0, bias=False),
|
39 |
+
nn.BatchNorm2d(ngf * 8),
|
40 |
+
nn.ReLU(True),
|
41 |
+
nn.Dropout(dropout_rate),
|
42 |
+
# state size. (ngf*8) x 4 x 4 == 1024 x 4 x 4
|
43 |
+
nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False),
|
44 |
+
nn.BatchNorm2d(ngf * 4),
|
45 |
+
nn.ReLU(True),
|
46 |
+
nn.Dropout(dropout_rate), # state size. (ngf*4) x 8 x 8 == 512 x 4 x 4
|
47 |
+
nn.ConvTranspose2d(ngf * 4, ngf * 2, 4, 2, 1, bias=False),
|
48 |
+
nn.BatchNorm2d(ngf * 2),
|
49 |
+
nn.ReLU(True),
|
50 |
+
nn.Dropout(dropout_rate), # state size. (ngf*2) x 16 x 16 == 256 x 4 x 4
|
51 |
+
nn.ConvTranspose2d(ngf * 2, ngf, 4, 2, 1, bias=False),
|
52 |
+
nn.BatchNorm2d(ngf),
|
53 |
+
nn.ReLU(True),
|
54 |
+
nn.Dropout(dropout_rate), # state size. (ngf) x 32 x 32 == 128 x 4 x 4
|
55 |
+
nn.ConvTranspose2d(ngf, ngf, 4, 2, 1, bias=False),
|
56 |
+
nn.BatchNorm2d(ngf),
|
57 |
+
nn.ReLU(True),
|
58 |
+
nn.ConvTranspose2d( ngf, nc_output, 4, 2, 1, bias=False),
|
59 |
+
nn.Sigmoid()
|
60 |
+
# state size. (nc) x 64 x 64
|
61 |
+
)
|
62 |
+
|
63 |
+
|
64 |
+
def forward(self, x):
|
65 |
+
encoded = self.forward_encoder(x)
|
66 |
+
decoded = self.forward_decoder(encoded)
|
67 |
+
return decoded
|
68 |
+
|
69 |
+
def forward_encoder(self, x):
|
70 |
+
encoded = self.encoder(x).reshape(-1, 64)
|
71 |
+
return self.linearEncoder(encoded).unsqueeze(2).unsqueeze(2)
|
72 |
+
|
73 |
+
def forward_decoder(self, encoded):
|
74 |
+
decoded = self.decoder(encoded)
|
75 |
+
return decoded
|
76 |
+
|
77 |
+
|
utils/utils.py
ADDED
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
from torch import randperm, utils
|
3 |
+
from torch._utils import _accumulate
|
4 |
+
import numpy as np
|
5 |
+
import matplotlib.pyplot as plt
|
6 |
+
from matplotlib import offsetbox
|
7 |
+
from PIL import Image
|
8 |
+
|
9 |
+
class Subset(utils.data.Dataset):
|
10 |
+
"""
|
11 |
+
Subset of a dataset at specified indices.
|
12 |
+
|
13 |
+
Arguments:
|
14 |
+
dataset (Dataset): The whole Dataset
|
15 |
+
indices (sequence): Indices in the whole set selected for subset
|
16 |
+
"""
|
17 |
+
def __init__(self, dataset, indices):
|
18 |
+
self.dataset = dataset
|
19 |
+
self.indices = indices
|
20 |
+
|
21 |
+
def __getitem__(self, idx):
|
22 |
+
return self.dataset[self.indices[idx]]
|
23 |
+
|
24 |
+
def __len__(self):
|
25 |
+
return len(self.indices)
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
def random_split(dataset, lengths):
|
30 |
+
"""
|
31 |
+
Randomly split a dataset into non-overlapping new datasets of given lengths.
|
32 |
+
|
33 |
+
Arguments:
|
34 |
+
dataset (Dataset): Dataset to be split
|
35 |
+
lengths (sequence): lengths of splits to be produced
|
36 |
+
"""
|
37 |
+
if sum(lengths) != len(dataset):
|
38 |
+
raise ValueError("Sum of input lengths does not equal the length of the input dataset!")
|
39 |
+
|
40 |
+
indices = randperm(sum(lengths))
|
41 |
+
return [Subset(dataset, indices[offset - length:offset]) for offset, length in zip(_accumulate(lengths), lengths)]
|
42 |
+
|
43 |
+
# Quizas deberia eliminar 3d o limpiar
|
44 |
+
def plot_embedding(X, merged, title = None, classes=11., showimage=True, distPl=0.006, onlyRoman=False):
|
45 |
+
x_min, x_max = np.min(X, 0), np.max(X, 0)
|
46 |
+
X = (X - x_min) / (x_max - x_min)
|
47 |
+
|
48 |
+
plt.figure()
|
49 |
+
ax = plt.subplot(111)
|
50 |
+
ax.set_facecolor('xkcd:white')
|
51 |
+
"""
|
52 |
+
for i in range(X.shape[0]):
|
53 |
+
plt.text(X[i, 0], X[i, 1], str(merged.iloc[i][1]),
|
54 |
+
color=plt.cm.Set1(int(merged.iloc[i][1]) / float(classes)),
|
55 |
+
fontdict={'weight': 'bold', 'size': 9})
|
56 |
+
"""
|
57 |
+
"""
|
58 |
+
for i in range(X.shape[0]):
|
59 |
+
if int(merged.iloc[i][1]) == 22:
|
60 |
+
plt.plot([X[i, 0]], [X[i, 1]], 'X', c="black", markersize=10)
|
61 |
+
plt.plot([X[i, 0]], [X[i, 1]], 'X', c='black', markersize=8)
|
62 |
+
else:
|
63 |
+
plt.plot([X[i, 0]], [X[i, 1]], 'o', c="black", markersize=6)
|
64 |
+
plt.plot([X[i, 0]], [X[i, 1]], 'o',c=plt.cm.Set3(int(merged.iloc[i][1])), markersize=4)
|
65 |
+
"""
|
66 |
+
|
67 |
+
|
68 |
+
if showimage and hasattr(offsetbox, 'AnnotationBbox'):
|
69 |
+
shown_images = np.array([[1., 1.]])
|
70 |
+
for i in range(merged.shape[0]):
|
71 |
+
dist = np.sum((X[i] - shown_images) ** 2, 1)
|
72 |
+
|
73 |
+
|
74 |
+
if np.min(dist) < distPl: #6e-4:
|
75 |
+
# don't show points that are too close
|
76 |
+
continue
|
77 |
+
|
78 |
+
shown_images = np.r_[shown_images, [X[i]]]
|
79 |
+
image = Image.open(merged.iloc[i][0])
|
80 |
+
inverted_image = image #PIL.ImageOps.invert(image)
|
81 |
+
inverted_image.thumbnail((40, 40), Image.ANTIALIAS)
|
82 |
+
|
83 |
+
props = dict(facecolor=plt.cm.Set3(int(merged.iloc[i][1])), alpha=1, lw=1)
|
84 |
+
imagebox = offsetbox.AnnotationBbox(
|
85 |
+
offsetbox.OffsetImage(inverted_image, cmap=plt.cm.gray),
|
86 |
+
X[i]+0.030, bboxprops=props)
|
87 |
+
ax.add_artist(imagebox)
|
88 |
+
plt.xticks([]), plt.yticks([])
|
89 |
+
#cbar = plt.colorbar()
|
90 |
+
if title is not None:
|
91 |
+
plt.title(title)
|
92 |
+
|
93 |
+
|
94 |
+
import numpy as np
|
95 |
+
import cv2
|
96 |
+
from skimage import measure
|
97 |
+
def landmarks(img_grey, N = 50):
|
98 |
+
thresh = 200
|
99 |
+
ret,img = cv2.threshold(img_grey, thresh, 255, cv2.THRESH_BINARY)
|
100 |
+
if img.ndim == 2:
|
101 |
+
img_s = np.ones((img.shape[0] + 100, img.shape[0] + 100)) * 255
|
102 |
+
img_s[50:-50, 50:-50] = img
|
103 |
+
img = img_s
|
104 |
+
contours = measure.find_contours(img, 0.5)
|
105 |
+
#fig = plt.figure(figsize=(7, 7))
|
106 |
+
#ax = fig.add_subplot(111)
|
107 |
+
#ax.imshow(img, interpolation='nearest', cmap=plt.cm.gray)
|
108 |
+
|
109 |
+
# for n, contour in enumerate(contours):
|
110 |
+
#print(contours[0].shape)
|
111 |
+
contour = contours[0]
|
112 |
+
#ax.plot(contour[:, 1], contour[:, 0], linewidth=5)
|
113 |
+
# resample_contour = contour[np.random.choice(contour.shape[0], 150, replace=False), :]
|
114 |
+
resample_contour = interpcurve(N, contour[:, 0], contour[:, 1])
|
115 |
+
# print(resample_contour[:4, 0], resample_contour[:4, 1], resample_contour[:4].ravel())
|
116 |
+
#df_semilandmarks.loc[index] = [id_name, classe_name] + list(resample_contour.ravel())
|
117 |
+
#ax.plot(resample_contour[:, 1], resample_contour[:, 0], 'om', linewidth=5)
|
118 |
+
#plt.savefig('output/landmarked_'+id_name)
|
119 |
+
#plt.show()
|
120 |
+
return resample_contour
|
121 |
+
|
122 |
+
def interpcurve(N, pX, pY):
|
123 |
+
#equally spaced in arclength
|
124 |
+
N = np.transpose(np.linspace(0, 1, N))
|
125 |
+
#how many points will be uniformly interpolated?
|
126 |
+
nt = N.size
|
127 |
+
|
128 |
+
#number of points on the curve
|
129 |
+
n = pX.size
|
130 |
+
pxy = np.array((pX, pY)).T
|
131 |
+
p1 = pxy[0,:]
|
132 |
+
pend = pxy[-1,:]
|
133 |
+
last_segment = np.linalg.norm(np.subtract(p1, pend))
|
134 |
+
epsilon= 10 * np.finfo(float).eps
|
135 |
+
|
136 |
+
#IF the two end points are not close enough lets close the curve
|
137 |
+
if last_segment > epsilon * np.linalg.norm(np.amax(abs(pxy), axis=0)):
|
138 |
+
pxy = np.vstack((pxy, p1))
|
139 |
+
nt = nt + 1
|
140 |
+
|
141 |
+
pt = np.zeros((nt, 2))
|
142 |
+
|
143 |
+
#Compute the chordal arclength of each segment.
|
144 |
+
chordlen = (np.sum(np.diff(pxy, axis=0) ** 2, axis=1)) ** (1 / 2)
|
145 |
+
#Normalize the arclengths to a unit total
|
146 |
+
chordlen = chordlen / np.sum(chordlen)
|
147 |
+
#cumulative arclength
|
148 |
+
cumarc = np.append(0, np.cumsum(chordlen))
|
149 |
+
|
150 |
+
tbins= np.digitize(N, cumarc) # bin index in which each N is in
|
151 |
+
|
152 |
+
#catch any problems at the ends
|
153 |
+
tbins[np.where(tbins<=0 | (N<=0))]=1
|
154 |
+
tbins[np.where(tbins >= n | (N >= 1))] = n - 1
|
155 |
+
|
156 |
+
s = np.divide((N - cumarc[tbins]), chordlen[tbins-1])
|
157 |
+
pt = pxy[tbins,:] + np.multiply((pxy[tbins,:] - pxy[tbins-1,:]), (np.vstack([s]*2)).T)
|
158 |
+
|
159 |
+
return pt
|
160 |
+
|
161 |
+
|
162 |
+
|
163 |
+
def segmentation(img, vertical):
|
164 |
+
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
165 |
+
#plt.imshow(img, cmap=plt.cm.gray)
|
166 |
+
if vertical:
|
167 |
+
background_0 = np.ones((img.shape)) + 254
|
168 |
+
background_0[img.shape[0]//2:, :] = img[img.shape[0]//2:,:]
|
169 |
+
#plt.imshow(background_0, cmap=plt.cm.gray)
|
170 |
+
#fig = plt.figure()
|
171 |
+
|
172 |
+
background_1 = np.ones((img.shape)) + 254
|
173 |
+
background_1[:img.shape[0]//2, :] = img[:img.shape[0]//2,:]
|
174 |
+
#plt.imshow(background_1, cmap=plt.cm.gray)
|
175 |
+
#fig = plt.figure()
|
176 |
+
|
177 |
+
|
178 |
+
else:
|
179 |
+
background_1 = np.ones((img.shape)) + 254
|
180 |
+
background_1[:, :img.shape[0]//2] = img[:,:img.shape[0]//2]
|
181 |
+
#plt.imshow(background_0, cmap=plt.cm.gray)
|
182 |
+
#fig = plt.figure()
|
183 |
+
|
184 |
+
|
185 |
+
background_0 = np.ones((img.shape)) + 254
|
186 |
+
background_0[:, img.shape[0]//2:] = img[:,img.shape[0]//2:]
|
187 |
+
#plt.imshow(background_1, cmap=plt.cm.gray)
|
188 |
+
#fig = plt.figure()
|
189 |
+
|
190 |
+
return background_0, background_1
|
191 |
+
|
192 |
+
def plotTwoImages(img_1, img_2, title):
|
193 |
+
plt.figure(figsize=(12,5))
|
194 |
+
plt.subplot(1, 2, 1)
|
195 |
+
|
196 |
+
plt.imshow(img_1)
|
197 |
+
plt.title(title[0])
|
198 |
+
plt.xticks([])
|
199 |
+
plt.yticks([])
|
200 |
+
plt.subplot(1, 2, 2)
|
201 |
+
|
202 |
+
plt.imshow(img_2)
|
203 |
+
plt.xticks([])
|
204 |
+
plt.yticks([])
|
205 |
+
plt.title(title[1])
|
206 |
+
|
207 |
+
def plotLandmarks(landmarks_img_1_part_2, landmarks_img_2_part_2, title, comparateShow=True):
|
208 |
+
plt.figure(figsize=(12,5))
|
209 |
+
size = (1, 2)
|
210 |
+
if comparateShow:
|
211 |
+
size = (1, 3)
|
212 |
+
plt.subplot( size[0], size[1], 1)
|
213 |
+
plt.plot(landmarks_img_1_part_2[:,0], landmarks_img_1_part_2[:,1], '-o')
|
214 |
+
plt.fill(landmarks_img_1_part_2[:, 0] , landmarks_img_1_part_2[:, 1], 'k')
|
215 |
+
plt.title(title[0])
|
216 |
+
plt.xticks([])
|
217 |
+
plt.yticks([])
|
218 |
+
|
219 |
+
|
220 |
+
plt.subplot(size[0], size[1], 2)
|
221 |
+
plt.plot(landmarks_img_2_part_2[:,0], landmarks_img_2_part_2[:,1], '-o')
|
222 |
+
plt.fill(landmarks_img_2_part_2[:, 0] , landmarks_img_2_part_2[:, 1], 'k')
|
223 |
+
plt.title(title[1])
|
224 |
+
plt.xticks([])
|
225 |
+
plt.yticks([])
|
226 |
+
|
227 |
+
|
228 |
+
if comparateShow:
|
229 |
+
plt.subplot(size[0], size[1], 3)
|
230 |
+
plt.plot(landmarks_img_1_part_2[:,0], landmarks_img_1_part_2[:,1], '-o')
|
231 |
+
plt.plot(landmarks_img_2_part_2[:,0], landmarks_img_2_part_2[:,1], '-o')
|
232 |
+
plt.title(title[2])
|
233 |
+
plt.xticks([])
|
234 |
+
plt.yticks([])
|
235 |
+
|
236 |
+
def plotLandmarks2(landmarks_img_1_part_2, landmarks_img_2_part_2, title, comparateShow=True):
|
237 |
+
plt.figure(figsize=(12,5))
|
238 |
+
fig, (ax1) = plt.subplots(1, 1, figsize=(12,5))
|
239 |
+
ax1.axis("off")
|
240 |
+
landmarks_img_1_part_2 = landmarks_img_1_part_2 * -1
|
241 |
+
landmarks_img_2_part_2 = landmarks_img_2_part_2 * -1
|
242 |
+
ax1.plot(landmarks_img_1_part_2[:,1], landmarks_img_1_part_2[:,0], '-o')
|
243 |
+
ax1.plot(landmarks_img_2_part_2[:,1], landmarks_img_2_part_2[:,0], '-o')
|
244 |
+
plt.title(title[2])
|
245 |
+
ax1.set_aspect(2)
|
246 |
+
plt.xticks([])
|
247 |
+
plt.yticks([])
|
248 |
+
|
249 |
+
|
250 |
+
def plotLandmarksItem(fig, ax1, landmarks_img_1_part_2, landmarks_img_2_part_2, title, comparateShow=True):
|
251 |
+
ax1.axis("off")
|
252 |
+
landmarks_img_1_part_2 = landmarks_img_1_part_2 * -1
|
253 |
+
landmarks_img_2_part_2 = landmarks_img_2_part_2 * -1
|
254 |
+
ax1.plot(landmarks_img_1_part_2[:,1], landmarks_img_1_part_2[:,0], '-o')
|
255 |
+
ax1.plot(landmarks_img_2_part_2[:,1], landmarks_img_2_part_2[:,0], '-o')
|
256 |
+
ax1.set_title(title)
|
257 |
+
ax1.set_aspect(1)
|
258 |
+
|
259 |
+
|
260 |
+
def plotLandmarksALL(img_0, img_1, landmarks_img_1_part_1, landmarks_img_2_part_1, landmarks_img_1_part_2, landmarks_img_2_part_2, title):
|
261 |
+
plt.figure(figsize=(12,5))
|
262 |
+
fig, (ax0, ax1, ax2, ax3) = plt.subplots(1, 4, figsize=(12,5))
|
263 |
+
ax0.axis("off")
|
264 |
+
ax0.set_title('INPUT')
|
265 |
+
ax3.axis("off")
|
266 |
+
ax3.set_title('OUTPUT')
|
267 |
+
plt.xticks([])
|
268 |
+
plt.yticks([])
|
269 |
+
ax0.imshow(img_0)
|
270 |
+
plotLandmarksItem(fig, ax1, landmarks_img_1_part_1, landmarks_img_2_part_1, title[0])
|
271 |
+
plotLandmarksItem(fig, ax2, landmarks_img_1_part_2, landmarks_img_2_part_2, title[1])
|
272 |
+
ax3.imshow(img_1)
|
273 |
+
plt.xticks([])
|
274 |
+
plt.yticks([])
|
275 |
+
|
276 |
+
|
277 |
+
|
278 |
+
|
279 |
+
if __name__ == "__main__":
|
280 |
+
pass
|