T.Masuda commited on
Commit
9692d43
1 Parent(s): 75bb6e1

create app

Browse files
Files changed (4) hide show
  1. app.py +41 -0
  2. equalize.py +133 -0
  3. examples/example1.jpg +0 -0
  4. requirements.txt +2 -0
app.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from equalize import Equalize
3
+
4
+ def set_levels(image):
5
+ if image is None:
6
+ return 0, 0, 0
7
+ eq = Equalize(0, 0, 0)
8
+ eq.set_level(image)
9
+ return round(eq.level[Equalize.R], 2), round(eq.level[Equalize.G], 2), round(eq.level[Equalize.B], 2)
10
+
11
+ def equalize(image, level_r, level_g, level_b):
12
+ eq = Equalize(level_r, level_g, level_b)
13
+ dest = eq.filter(image)
14
+ return dest
15
+
16
+ with gr.Blocks(title='image color equalizer') as app:
17
+ gr.Markdown('# Image Color Equalizer')
18
+
19
+ with gr.Row():
20
+ with gr.Column():
21
+ image = gr.Image(type='pil')
22
+ level_r = gr.Slider(maximum=1.0, value=0.0, step=0.01, label='R level')
23
+ level_g = gr.Slider(maximum=1.0, value=0.0, step=0.01, label='G level')
24
+ level_b = gr.Slider(maximum=1.0, value=0.0, step=0.01, label='B level')
25
+ inputs = [image, level_r, level_g, level_b]
26
+ clear = gr.ClearButton([image, level_r, level_g, level_b])
27
+ btn = gr.Button(value='Submit')
28
+ with gr.Column():
29
+ outputs = [gr.Image(label='output', type='pil')]
30
+
31
+ clear.add(inputs + outputs)
32
+ btn.click(equalize, inputs=inputs, outputs=outputs, concurrency_limit=20)
33
+ image.change(set_levels, inputs=[image], outputs=[level_r, level_g, level_b], concurrency_limit=20)
34
+
35
+ gr.Examples(
36
+ [['examples/example1.jpg']],
37
+ [image],
38
+ #cache_examples=True
39
+ )
40
+
41
+ app.launch()
equalize.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Self
2
+ from PIL import Image
3
+
4
+ class Equalize:
5
+ MIN_LEVEL = 0.0
6
+ MAX_LEVEL = 1.0
7
+ R = 0
8
+ G = 1
9
+ B = 2
10
+
11
+ @property
12
+ def level(self):
13
+ return self._level
14
+
15
+ @property
16
+ def level_b(self) -> float:
17
+ return self._level[Equalize.B]
18
+
19
+ @property
20
+ def level_g(self) -> float:
21
+ return self._level[Equalize.G]
22
+
23
+ @property
24
+ def level_r(self) -> float:
25
+ return self._level[Equalize.R]
26
+
27
+ def __init__(self, level_b: float, level_g: float, level_r: float) -> None:
28
+ if level_b < Equalize.MIN_LEVEL or level_b > Equalize.MAX_LEVEL:
29
+ raise ValueError('level_b')
30
+ if level_g < Equalize.MIN_LEVEL or level_g > Equalize.MAX_LEVEL:
31
+ raise ValueError('level_g')
32
+ if level_r < Equalize.MIN_LEVEL or level_r > Equalize.MAX_LEVEL:
33
+ raise ValueError('level_r')
34
+ self._level = [level_b, level_g, level_r]
35
+
36
+ @staticmethod
37
+ def from_level(level: float) -> Self:
38
+ return Equalize(level, level, level)
39
+
40
+ def set_level(self, image: Image) -> Image:
41
+ src = image.convert('RGB')
42
+ dest = Image.new('RGB', src.size)
43
+ width, height = src.size
44
+ histogram = [[0 for _ in range(256)], [0 for _ in range(256)], [0 for _ in range(256)]]
45
+ src_bytes = src.tobytes()
46
+ dest_bytes = bytearray(0 for _ in range(width * 3 * height))
47
+ for y in range(height):
48
+ for x in range(width):
49
+ i = y * width * 3 + x * 3
50
+ histogram[Equalize.R][src_bytes[i]] += 1
51
+ histogram[Equalize.G][src_bytes[i + 1]] += 1
52
+ histogram[Equalize.B][src_bytes[i + 2]] += 1
53
+ self._level = self._get_auto_level(histogram)
54
+
55
+ def filter(self, image: Image) -> Image:
56
+ src = image.convert('RGB')
57
+ dest = Image.new('RGB', src.size)
58
+ width, height = src.size
59
+ histogram = [[0 for _ in range(256)], [0 for _ in range(256)], [0 for _ in range(256)]]
60
+ src_bytes = src.tobytes()
61
+ dest_bytes = bytearray(0 for _ in range(width * 3 * height))
62
+ for y in range(height):
63
+ for x in range(width):
64
+ i = y * width * 3 + x * 3
65
+ histogram[Equalize.R][src_bytes[i]] += 1
66
+ histogram[Equalize.G][src_bytes[i + 1]] += 1
67
+ histogram[Equalize.B][src_bytes[i + 2]] += 1
68
+ eqmap = [[0 for _ in range(256)], [0 for _ in range(256)], [0 for _ in range(256)]]
69
+ self._create_map(histogram, eqmap)
70
+ for y in range(height):
71
+ for x in range(width):
72
+ i = y * width * 3 + x * 3
73
+ dest_bytes[i] = eqmap[Equalize.R][src_bytes[i]]
74
+ dest_bytes[i + 1] = eqmap[Equalize.G][src_bytes[i + 1]]
75
+ dest_bytes[i + 2] = eqmap[Equalize.B][src_bytes[i + 2]]
76
+ dest.frombytes(dest_bytes)
77
+ return dest
78
+
79
+ def _get_auto_level(self, histogram: [[int]]) -> [float, float, float]:
80
+ mapbgr = [[0 for _ in range(256)], [0 for _ in range(256)], [0 for _ in range(256)]]
81
+ b = 0
82
+ g = 0
83
+ r = 0
84
+ for i in range(256):
85
+ b += histogram[Equalize.B][i]
86
+ mapbgr[Equalize.B][i] = b
87
+ g += histogram[Equalize.G][i]
88
+ mapbgr[Equalize.G][i] = g
89
+ r += histogram[Equalize.R][i]
90
+ mapbgr[Equalize.R][i] = r
91
+
92
+ threshold = 64
93
+ level = [1.0, 1.0, 1.0]
94
+ for color in range(3):
95
+ map = mapbgr[color]
96
+ low = map[0]
97
+ high = map[255]
98
+ max_diff = 0
99
+ for i in range(256):
100
+ diff = abs(int((map[i] - low) * 255 / max(high - low, 1)) - i)
101
+ if diff > max_diff:
102
+ max_diff = diff
103
+ if max_diff > threshold:
104
+ level[color] = threshold / max_diff
105
+ return level
106
+
107
+ def _create_map(self, histogram: [[int]], eqmap: [[int]]) -> None:
108
+ mapbgr = [[0 for _ in range(256)], [0 for _ in range(256)], [0 for _ in range(256)]]
109
+ b = 0
110
+ g = 0
111
+ r = 0
112
+ for i in range(256):
113
+ b += histogram[Equalize.B][i]
114
+ mapbgr[Equalize.B][i] = b
115
+ g += histogram[Equalize.G][i]
116
+ mapbgr[Equalize.G][i] = g
117
+ r += histogram[Equalize.R][i]
118
+ mapbgr[Equalize.R][i] = r
119
+
120
+ for color in range(3):
121
+ map = mapbgr[color]
122
+ low = map[0]
123
+ high = map[255]
124
+ level = self.level[color]
125
+ for i in range(256):
126
+ c = i
127
+ if level > Equalize.MIN_LEVEL:
128
+ value = int((map[i] - low) * 255 / max(high - low, 1))
129
+ if level == Equalize.MAX_LEVEL:
130
+ c = value
131
+ else:
132
+ c = i + int((value - i) * level)
133
+ eqmap[color][i] = c
examples/example1.jpg ADDED
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ pillow