-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmontage_manager.py
More file actions
167 lines (149 loc) · 6.28 KB
/
Copy pathmontage_manager.py
File metadata and controls
167 lines (149 loc) · 6.28 KB
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
155
156
157
158
159
160
161
162
163
164
165
166
"""@file montage_manager.py
@brief all functions needed to create the montage
@author: Mehrdad Yazdani (modified by Shiyun Qiu & Siwen Tang)
@date April 29, 2016
This class is given by Professor Yazdani. We modified this document slightly to
make the first functionality work. We commented out all the libraries that are unused
and also the main.
"""
import csv
#import operator
from my_montage_maker import *
import math
#import numpy as np
from PIL import Image#, ImageDraw
from operator import itemgetter
import os
#import sys
import heapq
class Montages:
'''Create and manage montages'''
def __init__(self):
self.photow = 75
self.photoh = 75
#self.photow = 12000
#self.photoh = 1000
self.image_type = (".jpg", ".JPG", ".PNG", ".png", ".tiff", ".TIFF", ".jpeg", ".JPEG")
def _return_rows(self, filename, file_encoding = 'rU'):
with open(filename, file_encoding) as f:
reader = csv.reader(f)
rowsInData = [row for row in reader]
return rowsInData
def _get_paths_from_dir(self, dir_path):
path_parents = []
for root, dirs, files in os.walk(dir_path):
path_parents.append([os.path.join(root, f) for f in files if f.endswith(self.image_type)])
return path_parents
def input_data(self, src_path, dest_path, image_src_path = ""):
self.src_path = src_path
self.dest_path = dest_path
self.image_src_path = image_src_path
def create_montage(self, image_paths, montage_filename = "", ncols = None, nrows = None):
filedim = math.sqrt(len(image_paths))
if ncols == None:
if (filedim%int(filedim) == 0): ncols, nrows = int(filedim),int(filedim)
else: ncols, nrows = int(filedim), int(filedim)+1
if ncols == 0:
ncols = 1
nrows = len(image_paths)
if nrows == 0:
nrows = 1
ncols = len(image_paths)
ncr = (ncols, nrows)
photo = (self.photow,self.photoh)
margins = [0,0,0,0]
padding = 0
inew = make_contact_sheet(image_paths,ncr,photo,margins,padding)
inew.save(self.dest_path + montage_filename + ".jpg")
def montages_from_directory(self):
'''create montages from given directory recursively'''
path_parents = self._get_paths_from_dir(self.src_path)
for path_parent in path_parents:
if len(path_parent) == 0: continue
path_split = path_parent[0].split(self.src_path)[1].split("/")[0]
montage_filename = path_split + "_montage"
self.create_montage(path_parent, montage_filename)
def montage_from_csv_binned(self, ncols = None, nrows = None):
rows = self._return_rows(self.src_path)
header = rows.pop(0)
bins = list(set([row[1] for row in rows]))
path_parents = {}
for bin in bins:
if len(header) > 2:
unsorted_list = [[self.image_src_path + row[0], float(row[-1])] for row in rows if row[1] == bin]
sorted_list = sorted(unsorted_list, key=itemgetter(1))
path_parents[bin] = [item[0] for item in sorted_list]
else:
path_parents[bin] = [self.image_src_path + row[0] for row in rows if row[1] == bin]
for bin in path_parents.keys():
montage_filename = "bin_" + bin
self.create_montage(path_parents[bin], montage_filename, ncols, nrows)
def create_image_hist(self):
#first opening the csv file to be read
f = open(self.src_path, 'rb')
data = csv.reader(f)
#initializing the heapq to be read into
# heap = []
#initializing the dict to be read into
bins = {}
#for loop to read through the csv file
for row in data:
#first read the bin into a string
try:
bin = int(row[1])
except:
continue
#check if this key already exists in the dict
if bin not in bins.keys():
#if not create a new list at that bin index
bins[bin] = []
#either way append the tuple to the list at the right bin
bins[int(bin)].append((int(row[2]), row[0]))
#pushing the value and path combination onto the heap
#heappush(heap, (int(row[2]), row[0])) bins
#have now finished reading in all the data, now must make all the lists, min heaps with heapq
#for loop to do this
height = 0
# index = 0
for key in bins:
#changing every list into a heapq
heapq.heapify(bins[key])
length = len(bins[key])
#getting the tallest height
if height<length:
height=length
#getting the total number of bins
NumBins = len(bins)
#size of each image
size = 75
size1 = size + 5
graphH = size1 * height
graphW = size1 * NumBins
#creating the background window
img = Image.new('RGB',(graphW,graphH),(255,255,255))
SIZES = size, size
#for loop to loop through each bin and paste
for key in bins:
theQ = bins[key]
#initializing the yCoord as the very bottom of the graph
yCoord = graphH
xCoord = key * size1
#while loop to loop through the heapq and paste the images one by one from bottom up
while len(theQ) != 0:
#getting the image path
popped = heapq.heappop(theQ)
path = popped[1]
im = Image.open(path)
im.thumbnail(SIZES, Image.ANTIALIAS)
img.paste(im,(xCoord,yCoord))
yCoord = yCoord - size1
#end of the for loop
#saving the img into a png image
print (self.dest_path)
img.save(self.dest_path + "hist.png" )
#if __name__ == "__main__":
# in_file = "/Users/myazdaniUCSD/Dropbox/Broadway_processed_data/processedData/dom_HSV_small_sample.csv"
# image_dir = "/Users/qiushiyun/Documents/Lily Shiyun/Spring 2016/PIC 10C/pyImagePlot-master/sample_data/Rothko_images/"
# out_file = "/Users/qiushiyun/Documents/Lily Shiyun/"
# a_montage = Montages()
# a_montage.intput_data(src_path = in_file, dest_path = out_file, image_src_path = image_dir)