-
Notifications
You must be signed in to change notification settings - Fork 27
/
make_patches_for_embed.py
127 lines (98 loc) · 4.27 KB
/
make_patches_for_embed.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
# ---
# jupyter:
# jupytext:
# formats: ipynb,py:light
# text_representation:
# extension: .py
# format_name: light
# format_version: '1.4'
# jupytext_version: 1.1.7
# kernelspec:
# display_name: Python 3
# language: python
# name: python3
# ---
import os
import cv2
import glob
import argparse
import traceback
import sys
import json
import numpy as np
import sklearn.feature_extraction.image
try:
# +
parser = argparse.ArgumentParser(description='Convert image and mask into non-overlapping patches')
parser.add_argument('-p', '--patchsize', help="Patchsize, default 256", default=256, type=int)
parser.add_argument('-o', '--outdir', help="Target output directory", default="./", type=str)
parser.add_argument('-m', '--mask', action="store_true", help="Treat files like _mask.png as masks")
parser.add_argument('-b', '--bgremoved', action="store_true", help="Don't save patches which are considered background, useful for TMAs")
parser.add_argument('input_pattern',
help="Input filename pattern (try: *.png), or txt file containing list of files",
nargs="*")
#todo: add in random sampling
#args = parser.parse_args(["-m","-opatches","*.png"])
args = parser.parse_args()
print(f"args: {args}")
print(f"USER: Starting make patches for {args.outdir}", flush=True)
# +
patch_size = args.patchsize
outdir = args.outdir + os.sep if len(args.outdir) > 0 else "" # if the user supplied a different basepath, make sure it ends with an os.sep
domask = args.mask
if not os.path.isdir(f"{outdir}"):
os.mkdir(f"{outdir}")
if domask and not os.path.isdir(f"{outdir}/mask"):
os.mkdir(f"{outdir}/mask")
# +
fnames = []
if len(args.input_pattern) > 1: # bash has sent us a list of files
fnames = args.input_pattern
elif args.input_pattern[0].endswith("txt"): # user sent us an input file
with open(args.input_pattern[0], 'r') as f:
for line in f:
fnames.append(line.strip())
else: # user sent us a wildcard, need to use glob to find files
fnames = glob.glob(args.input_pattern[0])
# +
print("--------------------------", flush=True)
print(fnames)
nimages=len(fnames)
print(f"USER: Identified {nimages} images", flush=True)
for ii,fname in enumerate(fnames):
print(fname, flush=True)
print(f"PROGRESS: {ii+1}/{nimages}", flush=True)
fnamebase = os.path.splitext(os.path.basename(fname))[0]
if(domask and fname.find("_mask.png")>0):
print(f"Treating {fname} as mask")
ismask=True
fnamebase=fnamebase.replace("_mask","")
else:
ismask=False
image = cv2.imread(fname) #NOTE: this image is in BGR not RGB format
if(ismask):
image=np.dstack([(image[:,:,0]==0)*255,
(image[:,:,0]>0)*255,
np.ones(image.shape[0:2])*255])
idxs=np.asarray(range(image.shape[0]*image.shape[1])).reshape(image.shape[0:2])
patch_out = sklearn.feature_extraction.image._extract_patches(image,(patch_size,patch_size,3),patch_size)
patch_out = patch_out.reshape(-1,patch_size,patch_size,3)
idx_out = sklearn.feature_extraction.image._extract_patches(idxs,(patch_size,patch_size),patch_size)
idx_out=idx_out[:,:,0,0]
idx_out=idx_out.reshape(-1)
rs,cs=np.unravel_index(idx_out,idxs.shape)
for r,c,patch in zip(rs,cs,patch_out):
gpatch = cv2.cvtColor(patch, cv2.COLOR_BGR2GRAY)
if(args.bgremoved and gpatch.mean()>240):
continue
cv2.imwrite(f"{outdir}/{'mask' if ismask else ''}/{fnamebase}_{c}_{r}{'_mask' if ismask else ''}.png",patch) #writing in BGR not RGB format...as intended
# -
print(f"USER: Done making patches for {outdir}!", flush=True)
number_of_patches = len(glob.glob(os.path.join(outdir,"*.png")))
print(f"USER: Total number of patches = {number_of_patches}.", flush=True)
print(f"RETVAL: {json.dumps({'image_list': fnames})}", flush=True)
except:
track = traceback.format_exc()
track = track.replace("\n","\t")
print(f"ERROR: {track}", flush=True)
sys.exit(1)