gokaygokay commited on
Commit
2bff9bb
Β·
1 Parent(s): 7eaec10
Files changed (4) hide show
  1. app.py +2 -4
  2. lut_processor.py +1 -1
  3. requirements.txt +2 -1
  4. sharpen_processor.py +166 -0
app.py CHANGED
@@ -1,16 +1,14 @@
1
  import gradio as gr
2
  from pixelize_processor import create_pixelize_tab
3
  from lut_processor import create_lut_tab
 
4
 
5
- # Create main Gradio interface
6
  with gr.Blocks(title="Image Processing Suite") as demo:
7
  gr.Markdown("# Image Processing Suite")
8
 
9
- # Create tabs for different processing functions
10
  create_pixelize_tab()
11
  create_lut_tab()
12
- # Add more tabs as needed
13
 
14
- # Launch the interface
15
  if __name__ == "__main__":
16
  demo.launch(share=True)
 
1
  import gradio as gr
2
  from pixelize_processor import create_pixelize_tab
3
  from lut_processor import create_lut_tab
4
+ from sharpen_processor import create_sharpen_tab
5
 
 
6
  with gr.Blocks(title="Image Processing Suite") as demo:
7
  gr.Markdown("# Image Processing Suite")
8
 
 
9
  create_pixelize_tab()
10
  create_lut_tab()
11
+ create_sharpen_tab()
12
 
 
13
  if __name__ == "__main__":
14
  demo.launch(share=True)
lut_processor.py CHANGED
@@ -87,7 +87,7 @@ def apply_lut(image, lut_name, gamma_correction=True, clip_values=True, strength
87
  def create_lut_tab():
88
  available_luts = get_available_luts()
89
 
90
- with gr.Tab("LUT Processing"):
91
  with gr.Row():
92
  with gr.Column():
93
  input_image = gr.Image(label="Input Image")
 
87
  def create_lut_tab():
88
  available_luts = get_available_luts()
89
 
90
+ with gr.Tab("LUT"):
91
  with gr.Row():
92
  with gr.Column():
93
  input_image = gr.Image(label="Input Image")
requirements.txt CHANGED
@@ -2,4 +2,5 @@ pixeloe
2
  torch
3
  torchvision
4
  numpy==1.26.4
5
- colour-science
 
 
2
  torch
3
  torchvision
4
  numpy==1.26.4
5
+ colour-science
6
+ kornia
sharpen_processor.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import torch.nn.functional as F
4
+ import cv2
5
+ import kornia
6
+ import numpy as np
7
+
8
+ def min_(items):
9
+ current = items[0]
10
+ for item in items[1:]:
11
+ current = torch.minimum(current, item)
12
+ return current
13
+
14
+ def max_(items):
15
+ current = items[0]
16
+ for item in items[1:]:
17
+ current = torch.maximum(current, item)
18
+ return current
19
+
20
+ def apply_cas(image, amount):
21
+ if image is None:
22
+ return None
23
+
24
+ # Convert to torch tensor and normalize
25
+ image = torch.from_numpy(image).float() / 255.0
26
+
27
+ # Add batch dimension and rearrange to BCHW
28
+ image = image.unsqueeze(0).permute(0, 3, 1, 2)
29
+
30
+ epsilon = 1e-5
31
+ img = F.pad(image, pad=(1, 1, 1, 1))
32
+
33
+ a = img[..., :-2, :-2]
34
+ b = img[..., :-2, 1:-1]
35
+ c = img[..., :-2, 2:]
36
+ d = img[..., 1:-1, :-2]
37
+ e = img[..., 1:-1, 1:-1]
38
+ f = img[..., 1:-1, 2:]
39
+ g = img[..., 2:, :-2]
40
+ h = img[..., 2:, 1:-1]
41
+ i = img[..., 2:, 2:]
42
+
43
+ cross = (b, d, e, f, h)
44
+ mn = min_(cross)
45
+ mx = max_(cross)
46
+
47
+ diag = (a, c, g, i)
48
+ mn2 = min_(diag)
49
+ mx2 = max_(diag)
50
+ mx = mx + mx2
51
+ mn = mn + mn2
52
+
53
+ inv_mx = torch.reciprocal(mx + epsilon)
54
+ amp = inv_mx * torch.minimum(mn, (2 - mx))
55
+
56
+ amp = torch.sqrt(amp)
57
+ w = - amp * (amount * (1/5 - 1/8) + 1/8)
58
+ div = torch.reciprocal(1 + 4*w)
59
+
60
+ output = ((b + d + f + h)*w + e) * div
61
+ output = output.clamp(0, 1)
62
+
63
+ # Convert back to HWC format and to uint8
64
+ output = output.squeeze(0).permute(1, 2, 0)
65
+ output = (output.numpy() * 255).astype(np.uint8)
66
+
67
+ return output
68
+
69
+ def apply_smart_sharpen(image, noise_radius, preserve_edges, sharpen, ratio):
70
+ if image is None:
71
+ return None
72
+
73
+ # Convert to torch tensor and normalize
74
+ image = torch.from_numpy(image).float() / 255.0
75
+
76
+ if preserve_edges > 0:
77
+ preserve_edges = max(1 - preserve_edges, 0.05)
78
+
79
+ # Apply bilateral filter for noise reduction
80
+ if noise_radius > 1:
81
+ sigma = 0.3 * ((noise_radius - 1) * 0.5 - 1) + 0.8
82
+ blurred = cv2.bilateralFilter(image.numpy(), noise_radius, preserve_edges, sigma)
83
+ blurred = torch.from_numpy(blurred)
84
+ else:
85
+ blurred = image
86
+
87
+ # Apply sharpening
88
+ if sharpen > 0:
89
+ img_chw = image.permute(2, 0, 1).unsqueeze(0) # Add batch dimension
90
+ sharpened = kornia.enhance.sharpness(img_chw, sharpen).squeeze(0).permute(1, 2, 0)
91
+ else:
92
+ sharpened = image
93
+
94
+ # Blend results
95
+ result = ratio * sharpened + (1 - ratio) * blurred
96
+ result = torch.clamp(result, 0, 1)
97
+
98
+ # Convert back to uint8
99
+ output = (result.numpy() * 255).astype(np.uint8)
100
+
101
+ return output
102
+
103
+ def create_sharpen_tab():
104
+ with gr.Tab("Sharpening"):
105
+ gr.Markdown("Choose between Contrast Adaptive Sharpening (CAS) or Smart Sharpening")
106
+
107
+ with gr.Row():
108
+ with gr.Column():
109
+ input_image = gr.Image(label="Input Image")
110
+
111
+ with gr.Tabs():
112
+ with gr.Tab("CAS"):
113
+ cas_amount = gr.Slider(
114
+ minimum=0.0,
115
+ maximum=1.0,
116
+ value=0.8,
117
+ step=0.05,
118
+ label="Amount"
119
+ )
120
+ cas_btn = gr.Button("Apply CAS")
121
+
122
+ with gr.Tab("Smart Sharpen"):
123
+ noise_radius = gr.Slider(
124
+ minimum=1,
125
+ maximum=25,
126
+ value=7,
127
+ step=1,
128
+ label="Noise Radius"
129
+ )
130
+ preserve_edges = gr.Slider(
131
+ minimum=0.0,
132
+ maximum=1.0,
133
+ value=0.75,
134
+ step=0.05,
135
+ label="Preserve Edges"
136
+ )
137
+ sharpen = gr.Slider(
138
+ minimum=0.0,
139
+ maximum=25.0,
140
+ value=5.0,
141
+ step=0.5,
142
+ label="Sharpen Amount"
143
+ )
144
+ ratio = gr.Slider(
145
+ minimum=0.0,
146
+ maximum=1.0,
147
+ value=0.5,
148
+ step=0.1,
149
+ label="Blend Ratio"
150
+ )
151
+ smart_btn = gr.Button("Apply Smart Sharpen")
152
+
153
+ with gr.Column():
154
+ output_image = gr.Image(label="Sharpened Image")
155
+
156
+ cas_btn.click(
157
+ fn=apply_cas,
158
+ inputs=[input_image, cas_amount],
159
+ outputs=output_image
160
+ )
161
+
162
+ smart_btn.click(
163
+ fn=apply_smart_sharpen,
164
+ inputs=[input_image, noise_radius, preserve_edges, sharpen, ratio],
165
+ outputs=output_image
166
+ )