Skip to content

Commit dd73ba5

Browse files
committed
Added colored images
1 parent 8a20ca1 commit dd73ba5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+256
-3
lines changed

README.md

Lines changed: 17 additions & 3 deletions

c_data_generator.py

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#!/usr/bin/env python
2+
# coding: utf-8
3+
4+
# Script to generate colored image data. With the input arguments one can specify
5+
# how many gabor patches should be on the image, he image resolution as well as the
6+
# number of noise patches on the image. Furthermore one can add noise to the color
7+
# of the patch by defining the standard deviation of color_noise. The metadata of
8+
# the images are saved in a file named description.csv, containing the image name
9+
# together with the according orientations and color values.
10+
# Please note that the generation of the noise patches is quite slow and if somebody
11+
# comes up with a more efficient method, a pull request is highly appreciated.
12+
13+
import argparse
14+
15+
from PIL import Image
16+
import numpy as np
17+
import pandas as pd
18+
from pathlib import Path
19+
20+
21+
def get_args():
22+
parser = argparse.ArgumentParser()
23+
parser.add_argument('--n_gabor_patches', type=int, default=3,
24+
help="The number of gabor patches on the image")
25+
parser.add_argument('--n_noise_patches', type=int, default=24,
26+
help="The number of gaussian noise patches in the image")
27+
parser.add_argument('--color_noise', type=float, default=0,
28+
help="Standard deviation of the gaussian to add noise to the gabor patches (in degrees)")
29+
parser.add_argument('--image_height', type=int, default=250,
30+
help='Height of the image. The width will be n_gabor_patches time the height')
31+
parser.add_argument('--output_path', type=str, default='images/',
32+
help="Location for saving the images")
33+
parser.add_argument('--n_images', type=int, default=100,
34+
help="The number of images generated")
35+
return parser.parse_args()
36+
37+
38+
# this method is based on this stackoverflow post
39+
# https://stackoverflow.com/questions/19039674/how-can-i-expand-this-gabor-patch-to-the-size-of-the-bounding-box
40+
"""
41+
lambda_ : int
42+
Spatial frequency (px per cycle)
43+
44+
theta : int or float
45+
Grating orientation in degrees (0-180)
46+
47+
sigma : int or float
48+
gaussian standard deviation (in pixels)
49+
50+
phase : float
51+
phase offset of the grating, between 0 and 180
52+
53+
trim : float
54+
used to cut the gaussian at some point
55+
preventing it from continuing infinitely
56+
57+
color_trim : float
58+
defines the color border, compare to trim
59+
60+
color_std_dev : int or float
61+
if greater than 0, the given color is interpreted
62+
as the mean of a gaussian function and color_std_dev
63+
is the standard deviation, used to sample for every pixel
64+
"""
65+
66+
67+
def gabor_patch(size, color, lambda_, theta, sigma, phase, trim=.005,
68+
color_trim=.005, color_std_dev=20):
69+
X0 = (np.linspace(1, size, size) / size) - .5
70+
freq = size / float(lambda_)
71+
phaseRad = (phase / 180.) * np.pi
72+
Xm, Ym = np.meshgrid(X0, X0)
73+
thetaRad = (theta / 180.) * np.pi
74+
Xt = Xm * np.cos(thetaRad)
75+
Yt = Ym * np.sin(thetaRad)
76+
grating = np.sin(((Xt + Yt) * freq * 2 * np.pi) + phaseRad)
77+
gauss = np.exp(-((Xm ** 2) + (Ym ** 2)) / (2 * (sigma / float(size)) ** 2))
78+
gauss[gauss < trim] = 0
79+
mask = np.where(gauss < color_trim, True, False) # where should it be cut?
80+
color_pixel = color / 360 * 255
81+
color_std_dev_pixel = color_std_dev / 360 * 255
82+
v = (1 - (grating * gauss + 1) / 2) * 255
83+
h = np.ones(v.shape) * color_pixel
84+
if color_std_dev_pixel > 1e-3:
85+
h = np.random.normal(h, color_std_dev_pixel)
86+
s = np.clip(np.ones(v.shape) * gauss * 2, 0, 1) * 255
87+
h[mask] = 0
88+
s[mask] = 0
89+
v[gauss == 0] = 127
90+
img_data = np.transpose(np.array([h, s, v]))
91+
img_data = np.uint8(img_data)
92+
return Image.fromarray(img_data, "HSV").convert("RGB")
93+
94+
95+
def generate_image(orientations, colors, image_height,
96+
patch_size, color_std_dev):
97+
background_color = "#7f7f7f"
98+
n_gabor_patches = len(orientations)
99+
img = Image.new("RGB", (image_height * n_gabor_patches, image_height), background_color)
100+
lambda_ = 20
101+
sigma = 30
102+
for i, (o, c) in enumerate(zip(orientations, colors)):
103+
phase = np.random.uniform(0, 360)
104+
patch = gabor_patch(int(patch_size), c, lambda_, o, sigma, phase, color_std_dev=color_std_dev)
105+
img.paste(patch, (int((image_height - patch_size) / 2 + i * image_height), int((image_height - patch_size) / 2)))
106+
return img
107+
108+
109+
def generate_random_image(image_height, patches, patch_size, color_std_dev):
110+
orientations = []
111+
colors = []
112+
for _ in range(0, patches):
113+
orientation = np.random.uniform(0, 180)
114+
color = np.random.uniform(0, 360)
115+
orientations.append(orientation)
116+
colors.append(color)
117+
img = generate_image(orientations, colors, image_height, patch_size, color_std_dev)
118+
return img, orientations, colors
119+
120+
121+
def add_noise_patch(img, diameter=50, center=(None, None)):
122+
diam = round(diameter)
123+
radius = round(diameter / 2)
124+
img_width, img_height = img.size
125+
126+
center_x, center_y = center
127+
if center_x is None:
128+
center_x = round(np.random.uniform(0, img_width))
129+
if center_y is None:
130+
center_y = round(np.random.uniform(0, img_height))
131+
132+
h = np.random.uniform(0, 255, (diam, diam))
133+
s = np.clip((np.random.normal(loc=0.5, scale=0.1, size=(diam, diam))), 0, 1) * 255
134+
v = np.clip((np.random.normal(loc=0.5, scale=0.1, size=(diam, diam))), 0, 1) * 255
135+
136+
start_x = center_x - radius
137+
start_y = center_y - radius
138+
139+
for x in range(0, diam):
140+
for y in range(0, diam):
141+
coord_x = start_x + x
142+
coord_y = start_y + y
143+
if coord_x > 0 and coord_x < img_width and coord_y > 0 and coord_y < img_height and (
144+
(x - radius) ** 2 + (y - radius) ** 2) < radius ** 2:
145+
img.putpixel((coord_x, coord_y), (int(h[x, y]), int(s[x, y]), int(v[x, y])))
146+
return img
147+
148+
149+
def add_noise_patches(img, number=5, max_diameter=70, min_diameter_scale=0.8):
150+
for _ in range(0, number):
151+
img = add_noise_patch(img, diameter=max_diameter * np.random.uniform(min_diameter_scale, 1))
152+
return img
153+
154+
155+
def generate_noisy_image(n_gabor_patches, n_noise_patches, image_height, color_std_dev):
156+
patch_size = image_height * 0.8
157+
img, orientations, colors = generate_random_image(image_height, n_gabor_patches, patch_size, color_std_dev)
158+
noisy_img = add_noise_patches(img.convert("HSV"), n_noise_patches, patch_size / 3).convert("RGB")
159+
return noisy_img, orientations, colors
160+
161+
162+
if __name__ == '__main__':
163+
FLAGS = get_args()
164+
number_images = FLAGS.n_images
165+
n_gabor_patches = FLAGS.n_gabor_patches
166+
n_noise_patches = FLAGS.n_noise_patches
167+
color_std_dev = FLAGS.color_noise
168+
output_path = FLAGS.output_path
169+
image_height = FLAGS.image_height
170+
171+
Path(output_path).mkdir(parents=True, exist_ok=True)
172+
173+
columns = ["image_name"]
174+
for i in range(0, n_gabor_patches):
175+
columns.append("orientation_%d" % i)
176+
for i in range(0, n_gabor_patches):
177+
columns.append("color_%d" % i)
178+
df = pd.DataFrame(columns=columns)
179+
180+
for i in range(0, number_images):
181+
img, orientations, colors = generate_noisy_image(n_gabor_patches, n_noise_patches, image_height, color_std_dev)
182+
img_name = ("gabor%d_%06d.png" % (n_gabor_patches, i))
183+
row = [img_name] # just a list
184+
row.extend(orientations)
185+
row.extend(colors)
186+
df = df.append(pd.Series(row, index=columns), ignore_index=True)
187+
img.save(output_path + img_name)
188+
df.to_csv(output_path + "description.csv")

images/color/description.csv

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
,image_name,orientation_0,orientation_1,orientation_2,color_0,color_1,color_2
2+
0,gabor3_000000.png,54.09938980315551,149.3666594841039,163.10031969865162,218.56366198859885,253.32872119051797,257.7066606931126
3+
1,gabor3_000001.png,27.836726110205888,67.28394856911657,173.636935864515,305.94598374252234,177.9401866099616,323.26028354044263
4+
2,gabor3_000002.png,34.919315307170876,172.91356830604883,76.4433804739416,189.68375930482458,212.47059924224908,352.6899594797381
5+
3,gabor3_000003.png,12.267483553992275,165.79877262058852,39.21062497411004,87.83977144047353,61.6793194663622,100.2218087708559
6+
4,gabor3_000004.png,135.06230139798348,170.67292748125507,54.2026351486343,18.372442081744545,182.91285621109404,42.23079937054499
7+
5,gabor3_000005.png,71.08760206366082,112.64947592028594,89.75903478563043,136.55858632118327,42.03690543896509,256.33882746154256
8+
6,gabor3_000006.png,88.5659595294739,83.37759637474484,149.23016477443912,51.65126462946691,36.333541781617946,336.8332957155109
9+
7,gabor3_000007.png,75.83866726283492,81.71397421593053,8.736476760909529,109.57260574342206,128.042280625044,230.33188910137974
10+
8,gabor3_000008.png,99.51046095940018,144.6950855017139,112.1734797610958,336.12230760342317,135.84281397838836,27.89277523297285
11+
9,gabor3_000009.png,140.76086102848055,94.54106488954099,13.134428978471917,13.96204549802377,245.9754396056784,302.0696255913907
12+
10,gabor3_000010.png,144.6246043821979,173.64754792783276,54.712463439972495,168.4099646034069,359.4377656806148,130.32559403738844
13+
11,gabor3_000011.png,71.65974470374348,110.1810524919847,123.7678650631249,126.15503975413135,80.6443880279179,256.78104076159605
14+
12,gabor3_000012.png,10.839011709245698,2.2444099513724813,108.42412744850957,66.48798096946501,136.08707125590462,72.63448212385921
15+
13,gabor3_000013.png,47.605775364701806,2.824886517624725,129.05681239647046,4.157963768103259,285.0327360613872,352.841237139436
16+
14,gabor3_000014.png,74.6048706241529,3.5765465472252633,46.733480953101065,299.61803788335214,215.30239498910163,118.68749789861646
17+
15,gabor3_000015.png,78.3325395332049,17.13287708731422,148.24573082724615,200.37355126983636,243.2195574635118,237.63261786045945
18+
16,gabor3_000016.png,55.81713459524819,14.824872692963327,122.15608998245271,143.71782135863765,136.59487946405676,244.61541268815992
19+
17,gabor3_000017.png,88.16675356400619,64.34800883621129,126.63420183842229,141.8017210774053,353.7926656815415,134.82786822977155
20+
18,gabor3_000018.png,95.2403286168749,38.5666574555487,97.54046646222614,98.76595821650857,241.42322387519712,65.3323015680956
21+
19,gabor3_000019.png,89.14509371584398,131.54539922810903,119.9676995124858,248.95286876685037,77.24284823966573,168.08302915161508
22+
20,gabor3_000020.png,164.71115600955878,7.717780871207632,104.77247695931092,2.5788506347666074,257.8130746347827,153.64554880284928
23+
21,gabor3_000021.png,114.93783543764557,17.161765170862406,63.34362537014935,24.38959037416554,49.94849284153159,158.03285429573555
24+
22,gabor3_000022.png,64.67566725919693,132.82524393116128,141.36445204919488,244.01121967475854,196.0754527464855,174.1564383987106
25+
23,gabor3_000023.png,89.02586340386647,89.22996051251145,131.74700354725678,77.13271072819425,267.57597977226703,89.23155774534395
26+
24,gabor3_000024.png,98.83585318880401,42.22288448273999,48.08653747420612,353.96995633475376,182.00961850364766,58.352898539361334
27+
25,gabor3_000025.png,107.04350635483289,4.13163288702743,41.05176731503266,12.501757831898637,304.15466864839897,74.8589445145877
28+
26,gabor3_000026.png,121.0736696783587,164.09922994570567,132.1669713666377,278.6295304375286,295.9574001221908,30.239658569600195
29+
27,gabor3_000027.png,39.01699527086221,100.75916772828437,98.05840617390321,355.0970512148306,55.8837455290835,4.555496129082961
30+
28,gabor3_000028.png,31.05435251312717,175.47273604624638,63.162474509989536,149.6764607768488,8.86761942638504,181.9733250979067
31+
29,gabor3_000029.png,111.7276485883609,73.34751055191248,76.97717882853266,357.71008105196626,313.6308542423017,315.7330925815767
32+
30,gabor3_000030.png,68.81142042165096,104.52188611704665,174.63529600813527,17.658002603328967,12.43592432189947,144.41457405345798
33+
31,gabor3_000031.png,142.10752117788283,125.47889156495336,52.101631315006486,213.21124448659356,141.74089748765698,249.5939855008186
34+
32,gabor3_000032.png,46.57665761418324,32.35441311040135,162.23836253160744,168.97678284093644,247.8106430101444,258.8747836519495
35+
33,gabor3_000033.png,36.1586800870615,133.9422513863286,131.97914179911757,231.97616905802087,338.9661080306589,255.62960966532253
36+
34,gabor3_000034.png,97.17105895109806,143.21014171623818,160.80042786103613,339.9469442178193,149.8860676347679,77.77932658903973
37+
35,gabor3_000035.png,160.3034899191648,18.88072764227358,28.43284200508241,347.82788880827206,209.21586187887266,24.20272935104216
38+
36,gabor3_000036.png,85.60376582084156,143.27746282595612,120.900067666131,2.844876960323326,343.64606805952957,172.4129602752417
39+
37,gabor3_000037.png,117.88661215324326,92.61246405909837,128.06716885604067,175.65895361946943,313.08790373609185,304.48654576398985
40+
38,gabor3_000038.png,75.4448324812453,150.90853470381336,51.39188992739756,334.4976468416573,14.656023650828907,325.40885520850924
41+
39,gabor3_000039.png,137.9232415014839,116.94702603385355,145.56166709660926,238.7318449283638,16.100775090806138,336.15128124882597
42+
40,gabor3_000040.png,164.16804415934072,41.989971360317,3.488071006757363,69.04985561707602,288.54549461466934,332.32078255956407
43+
41,gabor3_000041.png,6.907355656433289,175.87887790233313,39.39509061782933,289.6006181152133,354.9730832066536,196.56715275792857
44+
42,gabor3_000042.png,140.22522731386036,139.2639361168361,50.8980201852067,121.3685853474521,102.88124375576379,70.76333117993116
45+
43,gabor3_000043.png,80.5482246254811,11.268712913136842,151.3581436262383,32.62150115964758,359.36765052213406,347.9867286926628
46+
44,gabor3_000044.png,92.2327508987772,144.90477616506962,2.9374797957697307,83.33674165048066,218.38118075239518,245.40163996433537
47+
45,gabor3_000045.png,113.43162789628823,153.80221475769866,130.4051212230468,343.11292703637616,249.0471726407375,121.92071679841322
48+
46,gabor3_000046.png,177.47129105082968,5.517100945202649,177.83903587547752,163.47763206469313,226.38382253911504,294.8306804954895
49+
47,gabor3_000047.png,162.05584513893785,49.76005881347516,134.01574277159847,184.06930289232537,106.34183097813369,145.79802595080895
50+
48,gabor3_000048.png,138.03422185134642,169.46082143219257,17.468426428053935,165.05209531357514,65.77268289929006,356.27613172009876
51+
49,gabor3_000049.png,155.200847155102,109.94261190221647,114.18048860673656,268.32398932864885,345.1765637407457,7.843551007528706

images/color/gabor3_000000.png

278 KB

images/color/gabor3_000001.png

273 KB

images/color/gabor3_000002.png

283 KB

images/color/gabor3_000003.png

267 KB

images/color/gabor3_000004.png

273 KB

images/color/gabor3_000005.png

263 KB

images/color/gabor3_000006.png

290 KB

0 commit comments

Comments
 (0)