-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
154 lines (129 loc) · 4.16 KB
/
utils.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
from PIL import Image, ImageTk, ImageDraw
import numpy as np
import os
from collections import OrderedDict
from PIL.ExifTags import TAGS
ROI_TYPES = (
"Overstory",
"Understory",
"In Between",
"Openland",
)
ROI_COLORS = {
"Overstory":"red",
"Understory":"blue",
"In Between":"black",
"Openland":"green"
}
CANVAS_SIZE = {
"width":1600,
"height":1200,
}
STATS = ("R", "G", "B", "VI", "coord")
class myImage(object):
'''
Represents and Image object.
Parameters
----------
imfile: path to the image file
'''
def __init__(self, imfile):
# path variables
self.imfile = imfile
self.name = os.path.basename(imfile)
self.directory = os.path.dirname(imfile)
self.camera_id = ""
self.date
# ROI
self.coords = OrderedDict()
self.new_ROI = False # True: if detect point; False: if clear_ROI
self.clear_roi()
def clear_roi(self):
""" clear coordinates for all ROI
"""
for roi in ROI_TYPES:
self.coords[roi] = []
self.new_ROI = False
@property
def date(self):
if hasattr(self, "_date"):
return self._date
img = Image.open(self.imfile)
info = img._getexif()
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
if decoded == "DateTimeOriginal":
date = value
break
img.close()
self._date = date
return date
@property
def stats(self):
"""
calculate stats for each ROI
returns
----------
dict: dictionary with <ROI>_<STAT> as key
"""
with Image.open(self.imfile) as img:
R,G,B = img.split()
stats = {
'overall_R':np.array(R).mean(),
'overall_G':np.array(G).mean(),
'overall_B':np.array(B).mean()
}
for roi in ROI_TYPES:
# generate polygon from coordinates
polygon = [tuple(coord) for coord in self.coords[roi]]
# mask everything
maskIm = Image.new('L', (R.width, R.height), 1)
if len(polygon) > 2:
# unmask region
ImageDraw.Draw(maskIm).polygon(polygon, outline=0, fill=0)
# channels masked with ROI
R_masked = np.ma.array(R, mask=maskIm)
G_masked = np.ma.array(G, mask=maskIm)
B_masked = np.ma.array(B, mask=maskIm)
# calculate statistics
stats['_'.join([roi,'coord'])] = polygon
if R_masked.count() != 0:
stats['_'.join([roi,'R'])] = R_masked.mean()
stats['_'.join([roi,'G'])] = G_masked.mean()
stats['_'.join([roi,'B'])] = B_masked.mean()
stats['_'.join([roi,'VI'])] = 2*G_masked.mean()-R_masked.mean()-B_masked.mean()
else:
stats['_'.join([roi,'R'])] = None
stats['_'.join([roi,'G'])] = None
stats['_'.join([roi,'B'])] = None
stats['_'.join([roi,'VI'])] = None
stats["new_ROI"] = self.new_ROI
return(stats)
@property
def metadata(self):
"""
Get method for the image metadata
returns
----------
dictionary of metadata
"""
if hasattr(self, "_metadata"):
self._metadata['Camera_id'] = self.camera_id
return self._metadata
meta = {}
meta['Directory'] = self.directory
meta['Image_Name'] = self.name
# TODO: code to set Camera_id and Date taken
meta['Camera_id'] = self.camera_id
meta["Date"] = self.date
self._metadata = meta
return meta
def main():
''' for debugging '''
directory = '/home/younghoon/data/phenology/BROW022/00430/20161028141801'
imfiles = [os.path.join(directory, f) for f in os.listdir(directory)]
for imfile in imfiles:
img = myImage(imfile)
pass
if __name__=="__main__":
main()