youssefkhalil320's picture
app.py
23e043c verified
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()