File size: 13,404 Bytes
23e043c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
import gradio as gr
import cv2
import numpy as np
#from imagesFunctions import *

# Define preprocessing functions
def grayscale(image):
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    return gray_image

def blur(image):
    blurred_image = cv2.GaussianBlur(image, (15, 15), 0)
    return blurred_image

def edge_detection(image):
    edges = cv2.Canny(image, 100, 200)
    return edges

def invert_colors(image):
    inverted_image = cv2.bitwise_not(image)
    return inverted_image

def threshold(image):
    _, thresh_image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)
    return thresh_image

def gray_level_transform(image, alpha=1.0, beta=0.0):
    """
    Apply a simple gray level transformation to the image.
    Formula: new_intensity = alpha * old_intensity + beta
    """
    transformed_image = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
    return transformed_image

def negative_transform(image):
    """
    Apply a negative transformation to the image.
    """
    negative_image = 255 - image  # Invert pixel values
    return negative_image

def log_transform(image, c=1):
    """
    Apply a logarithmic transformation to the image.
    """
    log_image = np.log1p(c * image)  # Apply log transformation
    # Scale the values to the range [0, 255]
    log_image = (log_image / np.max(log_image)) * 255
    log_image = np.uint8(log_image)
    return log_image

def power_law_transform(image, gamma=1.0):
    """
    Apply a power law transformation (gamma correction) to the image.
    """
    # Apply gamma correction
    power_law_image = np.power(image / 255.0, gamma)
    # Scale the values back to the range [0, 255]
    power_law_image = np.uint8(power_law_image * 255)
    return power_law_image

def contrast_stretching(image, low=0, high=255):
    """
    Stretch the contrast of an image by mapping pixel values to a new range.

    Args:
        image: A numpy array representing the image.
        low: The minimum value in the output image (default: 0).
        high: The maximum value in the output image (default: 255).

    Returns:
        A numpy array representing the contrast-stretched image.
    """
    # Find the minimum and maximum values in the image
    min_val = np.amin(image)
    max_val = np.amax(image)

    # Check if min and max are the same (no stretch needed)
    if min_val == max_val:
        return image

    # Normalize the pixel values to the range [0, 1]
    normalized = (image - min_val) / (max_val - min_val)

    # Stretch the normalized values to the new range [low, high]
    stretched = normalized * (high - low) + low

    # Convert the stretched values back to the original data type (uint8 for images)
    return np.uint8(stretched * 255)


def intensity_slicing(image, threshold):
    """
    Perform intensity slicing on an image to create a binary image.

    Args:
        image: A numpy array representing the image.
        threshold: The intensity threshold for binarization (default: 128).

    Returns:
        A numpy array representing the binary image after intensity slicing.
    """
    # Create a copy of the image to avoid modifying the original
    sliced_image = image.copy()

    # Apply thresholding
    sliced_image[sliced_image > threshold] = 255  # Set values above threshold to white (255)
    sliced_image[sliced_image <= threshold] = 0  # Set values below or equal to threshold to black (0)

    return sliced_image

def histogram_equalization(image):
    """
    Perform histogram equalization on an image to enhance its contrast.

    Args:
        image: A numpy array representing the image.

    Returns:
        A numpy array representing the image after histogram equalization.
    """
    # Compute histogram of the input image
    hist, _ = np.histogram(image.flatten(), bins=256, range=(0,256))

    # Compute cumulative distribution function (CDF)
    cdf = hist.cumsum()

    # Normalize CDF
    cdf_normalized = cdf * hist.max() / cdf.max()

    # Perform histogram equalization
    equalized_image = np.interp(image.flatten(), range(256), cdf_normalized).reshape(image.shape)

    return equalized_image.astype(np.uint8)


def mean_filter(image, kernel_size=3):
    """
    Apply a mean filter (averaging filter) to the image.

    Args:
        image: A numpy array representing the input image.
        kernel_size: The size of the square kernel (default: 3).

    Returns:
        A numpy array representing the image after applying the mean filter.
    """
    # Define the kernel
    kernel = np.ones((kernel_size, kernel_size)) / (kernel_size ** 2)

    # Apply convolution with the kernel using OpenCV's filter2D function
    filtered_image = cv2.filter2D(image, -1, kernel)

    return filtered_image

def gaussian_filter(image, kernel_size=3, sigma=1):
    """
    Apply a Gaussian filter to the image.

    Args:
        image: A numpy array representing the input image.
        kernel_size: The size of the square kernel (default: 3).
        sigma: The standard deviation of the Gaussian distribution (default: 1).

    Returns:
        A numpy array representing the image after applying the Gaussian filter.
    """
    # Generate Gaussian kernel
    kernel = cv2.getGaussianKernel(kernel_size, sigma)
    kernel = np.outer(kernel, kernel.transpose())

    # Apply convolution with the kernel using OpenCV's filter2D function
    filtered_image = cv2.filter2D(image, -1, kernel)

    return filtered_image

def sobel_filter(image):
    """
    Apply the Sobel filter to the image for edge detection.

    Args:
        image: A numpy array representing the input image.

    Returns:
        A numpy array representing the image after applying the Sobel filter.
    """
    # Apply Sobel filter for horizontal gradient
    sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
    
    # Apply Sobel filter for vertical gradient
    sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)

    # Combine horizontal and vertical gradients to get the gradient magnitude
    gradient_magnitude = np.sqrt(sobel_x**2 + sobel_y**2)

    # Normalize the gradient magnitude to the range [0, 255]
    gradient_magnitude = cv2.normalize(gradient_magnitude, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)

    return gradient_magnitude

def convert_to_grayscale(image):
    """
    Converts an image to grayscale.

    Args:
        image: A NumPy array representing the image (BGR or RGB format).

    Returns:
        A NumPy array representing the grayscale image.
    """
    # Check if image is already grayscale
    if len(image.shape) == 2:
        return image  # Already grayscale

    # Convert the image to grayscale using OpenCV's BGR2GRAY conversion
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    return gray_image


def laplacian_filter(image):
    """
    Apply the Laplacian filter to the grayscale image for edge detection.

    Args:
        image: A numpy array representing the input image.

    Returns:
        A numpy array representing the image after applying the Laplacian filter.
    """
    # Convert the input image to grayscale
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Apply Laplacian filter using OpenCV's Laplacian function
    laplacian = cv2.Laplacian(gray_image, cv2.CV_64F)

    # Convert the output to uint8 and scale to [0, 255]
    laplacian = cv2.normalize(laplacian, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)

    return laplacian

def min_max_filter(image, kernel_size=3, mode='min'):
    """
    Apply the min-max filter to the image.

    Args:
        image: A numpy array representing the input image.
        kernel_size: The size of the square kernel (default: 3).
        mode: The mode of the filter ('min' or 'max') (default: 'min').

    Returns:
        A numpy array representing the image after applying the min-max filter.
    """
    # Define the kernel
    kernel = np.ones((kernel_size, kernel_size))

    # Apply minimum or maximum filter
    if mode == 'min':
        filtered_image = cv2.erode(image, kernel)
    elif mode == 'max':
        filtered_image = cv2.dilate(image, kernel)
    else:
        raise ValueError("Invalid mode. Mode must be 'min' or 'max'.")

    return filtered_image

def median_filter(image, kernel_size=3):
    """
    Apply the median filter to the image.

    Args:
        image: A numpy array representing the input image.
        kernel_size: The size of the square kernel (default: 3).

    Returns:
        A numpy array representing the image after applying the median filter.
    """
    # Ensure that kernel_size is odd
    if kernel_size % 2 == 0:
        kernel_size += 1

    # Apply median filter using OpenCV's medianBlur function
    filtered_image = cv2.medianBlur(image, kernel_size)

    return filtered_image

# Define preprocessing function choices (must be before using in Dropdown)
preprocessing_functions = [
    ("Grayscale", grayscale),
    ("Blur", blur),
    ("Edge Detection", edge_detection),
    ("Invert Colors", invert_colors),
    ("Threshold", threshold),
    ("Gray Level Transform", gray_level_transform),
    ("Negative Transform", negative_transform),
    ("Log Transform", log_transform),
    ("Power Law Transform", power_law_transform),
    ("Contrast Stretching", contrast_stretching),
    ("intensity slicing", intensity_slicing),
    ("histogram equalization", histogram_equalization),
    ("mean filter", mean_filter),
    ("gaussian filter", gaussian_filter),
    ("sobel filter", sobel_filter),
    ("laplacian filter", laplacian_filter),
    ("min max filter", min_max_filter), 
    ("median filter", median_filter),
]

input_image = gr.components.Image(label="Upload Image")
function_selector = gr.components.Dropdown(choices=[func[0] for func in preprocessing_functions], label="Select Preprocessing Function")

# Define slider for alpha value
alpha_slider = gr.components.Slider(minimum=-100, maximum=100, label="alpha")
alpha_slider.default = 0  # Set default value for alpha

# Define slider for beta value
beta_slider = gr.components.Slider(minimum=0.1, maximum=3.0, label="beta")
beta_slider.default = 1.0  # Set default value for beta

# Define slider for c_log value
c_log_slider = gr.components.Slider(minimum=0.1, maximum=3.0, label="c_log")
c_log_slider.default = 1.0  # Set default value for c_log

# Define slider for gamma value
gamma_slider = gr.components.Slider(minimum=0.1, maximum=3.0, label="gamma")
gamma_slider.default = 1.0  # Set default value for gamma

# Define slider for slicing_threshold value
slicing_threshold_slider = gr.components.Slider(minimum=0, maximum=255, label="slicing threshold")
slicing_threshold_slider.default = 125.0  # Set default value for slicing_threshold

# Define slider for kernel size value
kernel_size_slider = gr.components.Slider(minimum=2, maximum=5, label="kernel size")
kernel_size_slider.default = 3  # Set default value for kernel size

# Define slider for kernel size value
sigma_slider = gr.components.Slider(minimum=2, maximum=5, label="sigma")
sigma_slider.default = 1  # Set default value for kernel size

def apply_preprocessing(image, selected_function, alpha, beta, c_log, gamma, slicing_threshold, kernel_size, sigma):
    # Find the actual function based on the user-friendly name
    selected_function_obj = None
    for func_name, func_obj in preprocessing_functions:
        if func_name == selected_function:
            selected_function_obj = func_obj
            break
    if selected_function_obj is None:
        raise ValueError("Selected function not found.")
    # For gray level transformation, pass beta and gamma values
    if selected_function == "Gray Level Transform":
        processed_image = selected_function_obj(image, alpha=alpha, beta=beta)
    elif selected_function == "Log Transform":
        processed_image = selected_function_obj(image, c=c_log)    
    elif selected_function == "Power Law Transform":
        processed_image = selected_function_obj(image, gamma=gamma)     
    elif selected_function == "intensity slicing":
        processed_image = selected_function_obj(image, threshold=slicing_threshold)
    elif selected_function == "mean filter":
        processed_image = selected_function_obj(image, kernel_size=kernel_size)
    elif selected_function == "gaussian filter":
        processed_image = selected_function_obj(image, kernel_size=kernel_size, sigma=sigma)  
    elif selected_function == "gaussian filter":
        processed_image = selected_function_obj(image, kernel_size=kernel_size, sigma=sigma)
    elif selected_function == "min max filter":
        processed_image = selected_function_obj(image, kernel_size=kernel_size)
    elif selected_function == "median filter":
        processed_image = selected_function_obj(image, kernel_size=kernel_size)                    
    else:
        print(selected_function_obj)
        processed_image = selected_function_obj(image)
    return processed_image

output_image = gr.components.Image(label="Processed Image")

# Create Gradio interface
gr.Interface(
    fn=apply_preprocessing,
    inputs=[input_image, function_selector, alpha_slider, beta_slider, c_log_slider, gamma_slider, slicing_threshold_slider, kernel_size_slider, sigma_slider],
    outputs=output_image,
    title="Elza3ama studio",
    description="Upload an image and select a preprocessing function."
).launch()