-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspotstats.py
123 lines (107 loc) · 4.45 KB
/
spotstats.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
import os, os.path
import numpy as np
import scipy as sp
import pandas as pd
from skimage import (io, measure)
import click
def region_stats(region, nrows, ncols):
position = region.label
row = (position - 1)/ncols # 0 indexed row
col = position - (row * ncols)
row = row + 1 # update row so 1 indexed
centroid_r = region.centroid[0]
centroid_c = region.centroid[1]
area = region.area
perimeter = region.perimeter
major_axis_length = region.major_axis_length
minor_axis_length = region.minor_axis_length
eccentricity = region.eccentricity
equiv_diameter = region.equivalent_diameter
mean_intensity = region.mean_intensity
solidity = region.solidity
convex_area = region.convex_area
bbox_minr, bbox_minc, bbox_maxr, bbox_maxc = region.bbox
return [position, row, col, centroid_r, centroid_c, area, perimeter,
major_axis_length, minor_axis_length, eccentricity, equiv_diameter,
mean_intensity, solidity, convex_area,
bbox_minr, bbox_minc, bbox_maxr, bbox_maxc]
def colony_stats(regions, nrows, ncols):
npos = nrows * ncols
posdict = dict(zip(range(1, npos+1),[None]*npos))
for region in regions:
posdict[region.label] = region_stats(region, nrows, ncols)
header = ["label", "row", "col", "centroid_r", "centroid_c", "area",
"perimeter", "major_axis_length", "minor_axis_length",
"eccentricity", "equiv_diameter", "mean_intensity",
"solidity", "convex_area",
"bbox_minr", "bbox_minc", "bbox_maxr", "bbox_maxc"]
tbl = []
for i in range(1, npos+1):
if posdict[i] is None:
row = [i] + (["NA"] * (len(header) - 1)) # fill with NA
else:
row = posdict[i]
tbl.append(row)
return pd.DataFrame(tbl, columns=header)
#-------------------------------------------------------------------------------
@click.command()
@click.argument("imgfiles",
type = click.Path(exists = True, dir_okay = False),
nargs = -1)
@click.argument("maskdir",
type = click.Path(exists = True,
file_okay = False,
dir_okay = True))
@click.argument("outdir",
type = click.Path(exists = True,
file_okay = False,
dir_okay = True))
@click.option("-p", "--prefix",
help = "Prefix for output CSV files",
type = str,
default = "STATS",
show_default = True)
@click.option("-m", "--mask-prefix",
help = "Prefix for Mask files.",
type = str,
default = "MASK",
show_default = True)
@click.option("-r", "--rows",
help = "Number of rows in grid",
type = int,
default = 8,
show_default = True)
@click.option("-c", "--cols",
help = "Number of cols in grid",
type = int,
default = 12,
show_default = True)
# @click.option("--alpha-rows/--alpha-cols",
# help = "Whether to label rows (or cols) alphabetically",
# default = True,
# show_default = True)
# @click.option("--alpha-increasing/--alpha-decreasing",
# help = "Whether alphabetical indexing increases or decreases.",
# default = True,
# show_default = True)
# @click.option("--numeric-increasing/--numeric-decreasing",
# help = "Whether the numberical indexing increases or decreases.",
# default = True,
# show_default = True)
def main(imgfiles, maskdir, outdir, prefix, mask_prefix, rows, cols):
"""Extract statistics from labeled objects in an image.
"""
for imgfile in imgfiles:
img = np.squeeze(io.imread(imgfile))
basename = os.path.basename(imgfile)
root, _ = os.path.splitext(basename)
outfile = os.path.join(outdir, "{}-{}.csv".format(prefix, root))
mask_file = os.path.join(maskdir, "{}-{}.npz".format(mask_prefix, root))
if not os.path.exists(mask_file):
continue
labeled_img = sp.sparse.load_npz(mask_file).toarray()
regions = measure.regionprops(labeled_img, intensity_image = img)
stats_df = colony_stats(regions, rows, cols)
stats_df.to_csv(outfile, index = False)
if __name__ == "__main__":
main()