-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmosaic.py
129 lines (112 loc) · 5.04 KB
/
mosaic.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
import cv2
import numpy as np
import os
import glob2
import tqdm
import argparse
import time
import sys
ap = argparse.ArgumentParser(description="Create Image Mosaic")
ap.add_argument("-i", "--image", default="me.jpg",
help="Path to the content image")
ap.add_argument("-d", "--datasets", default="images",
help="Path to the images datasets")
ap.add_argument("-r", "--division", default=16, type=int,
help="Divides the image n division. Default is 32. Higher value leads to better mosaic but it takes more time. ")
ap.add_argument("-s", "--size", nargs='+', default=None, type=int,
help="Output size of the image")
ap.add_argument('-o', '--output', default="output.jpg",
help="Path to save the image with filename ")
args = vars(ap.parse_args())
WEIGHT = 0.7
class Mosaic:
def __init__(self, contentPath, dataPath='images', division=32, contentSize=None):
'''Create photo mosaic with content image'''
self.contentPath = contentPath
self.imagesPath = dataPath
self.content = None
self.H = None
self.W = None
self.C = None
self.colors = {}
self.division = division
self.contentSize = contentSize
self.loadContent()
self.initDatasets()
def initDatasets(self):
'''Load the datasets/images and set their RGB values in colors dictionary '''
types = ('*.png', '*.jpg', '*.jpeg') # the tuple of file types
images = []
for files in types:
images.extend(glob2.glob(self.imagesPath+'/'+files))
print("Loading Images dataset")
start = time.time()
if(len(self.colors) == 0):
for imgPath in tqdm.tqdm(images):
img = cv2.imread(imgPath)
img = cv2.resize(
img, (self.W//self.division, self.H//self.division))
mean = np.mean(img, axis=(0, 1))
mean = np.asarray(mean, dtype=np.uint8)
name = os.path.basename(imgPath)
self.colors[name] = mean
print('Loading Images dataset.... Done')
print("Total ", time.time()-start)
def loadAndResize(self, path, size):
img = cv2.imread(path)
img = cv2.resize(img, size)
return img
def loadContent(self, ):
'''Load and resize content Image'''
self.content = cv2.imread(self.contentPath)
if self.contentSize is not None:
self.content = cv2.resize(self.content, self.contentSize)
self.H, self.W, self.C = self.content.shape
return self.content
def mosaicify(self):
pixelHeight, pixelWidth = self.H//self.division, self.W//self.division
print("Creating Mosaics.. This may take a while")
dynamicMean = {}
start = time.time()
for row in tqdm.tqdm(range(0, self.H, pixelHeight)):
for col in tqdm.tqdm(range(0, self.W, pixelWidth)):
roi = self.content[row:row + pixelHeight, col:col+pixelWidth]
mean = np.mean(roi, axis=(0, 1))
mean = np.asarray(mean, dtype=np.float32)/255.0
dynamicAverage = np.mean(mean*255.0).astype(np.uint8)
minDistance = 10
fileName = ''
if(dynamicAverage in dynamicMean.keys()):
fileName = dynamicMean[dynamicAverage]
minImage = self.loadAndResize(
os.path.join(self.imagesPath, fileName), (roi.shape[1], roi.shape[0]))
self.content[row:row + pixelHeight,
col:col+pixelWidth] = cv2.addWeighted(minImage, WEIGHT, roi, (1-WEIGHT), 1)
continue
for name, value in self.colors.items():
value = value / 255.0
dist = np.linalg.norm(
mean-value)
if(dist < minDistance):
fileName = name
minDistance = dist
if(fileName != ''):
dynamicMean[dynamicAverage] = fileName
minImage = self.loadAndResize(
os.path.join(self.imagesPath, fileName), (roi.shape[1], roi.shape[0]))
self.content[row:row + pixelHeight,
col:col+pixelWidth] = cv2.addWeighted(minImage, WEIGHT, roi, (1-WEIGHT), 1)
# self.content[row:row + pixelHeight,
# col:col+pixelWidth] = minImage
print("Mosaic Creating Complete... Saving image")
cv2.imwrite(args['output'], self.content)
print("Image Saved..." + args['output'])
print("Total Time taken : ", time.time()-start, 'secs')
return self.content
if __name__ == '__main__':
mosaic = Mosaic(args['image'], args['datasets'],
division=args['division'], contentSize=None if args['size'] is None else tuple(args['size']))
cv2.imshow('Output', mosaic.mosaicify())
cv2.waitKey(0)
cv2.destroyAllWindows()
sys.exit(1)