146 lines
5.2 KiB
Python
146 lines
5.2 KiB
Python
|
from imagen import Image
|
||
|
import numpy as np
|
||
|
|
||
|
def adjust_brightness(image, factor):
|
||
|
"""
|
||
|
Factor es un valor > 0 que ajusta el brillo de la imagen
|
||
|
( < 1 = menos brillo, > 1 = mas brillo )
|
||
|
"""
|
||
|
x_pixels, y_pixels, num_channels = image.array.shape
|
||
|
# creación de imagen vacía, para no modificar la original
|
||
|
new_im = Image(x_pixels=x_pixels, y_pixels=y_pixels, num_channels=num_channels)
|
||
|
|
||
|
# (no vectorizado, itera por cada pixel y valor de canal)
|
||
|
#for x in range(x_pixels):
|
||
|
# for y in range(y_pixels):
|
||
|
# for c in range(num_channels):
|
||
|
# new_im.array[x, y, c] = image.array[x, y, c] * factor
|
||
|
|
||
|
# vectorizado
|
||
|
new_im.array = image.array * factor
|
||
|
|
||
|
return new_im
|
||
|
|
||
|
def adjust_contrast(image, factor, mid=0.5):
|
||
|
"""
|
||
|
Ajuste de contraste imcrementando la diferencia desde un punto medio
|
||
|
predefinido por el usuario a otro valor, factor
|
||
|
"""
|
||
|
x_pixels, y_pixels, num_channels = image.array.shape
|
||
|
new_im = Image(x_pixels=x_pixels, y_pixels=y_pixels, num_channels=num_channels)
|
||
|
|
||
|
# no vectorizado
|
||
|
for x in range(x_pixels):
|
||
|
for y in range(y_pixels):
|
||
|
for c in range(num_channels):
|
||
|
new_im.array[x, y, c] = (image.array[x, y, c] - mid) * factor + mid
|
||
|
|
||
|
# vectorizado
|
||
|
#new_im.array = (image.array - mid) * factor + mid
|
||
|
|
||
|
return new_im
|
||
|
|
||
|
def blur(image, kernel_size):
|
||
|
"""
|
||
|
kernel_size es el número de pixeles a tener en cuenta al aplicar efecto blur
|
||
|
kernel_size deber ser un número impar
|
||
|
"""
|
||
|
x_pixels, y_pixels, num_channels = image.array.shape
|
||
|
new_im = Image(x_pixels=x_pixels, y_pixels=y_pixels, num_channels=num_channels)
|
||
|
|
||
|
neighbor_range = kernel_size // 2 # cuantos piexeles cercanos a un lado
|
||
|
|
||
|
for x in range(x_pixels):
|
||
|
for y in range(y_pixels):
|
||
|
for c in range(num_channels):
|
||
|
# implementación de iteración simple
|
||
|
total = 0
|
||
|
for x_i in range(max(0, x - neighbor_range), min(x_pixels - 1, x + neighbor_range) + 1):
|
||
|
for y_i in range(max(0, y - neighbor_range), min(y_pixels - 1, y + neighbor_range) + 1):
|
||
|
total += image.array[x_i, y_i, c]
|
||
|
new_im.array[x, y, c] = total / (kernel_size ** 2) # promedio
|
||
|
|
||
|
return new_im
|
||
|
|
||
|
def apply_kernel(image, kernel):
|
||
|
"""
|
||
|
El kernel debe ser un numpy array 2D que represente el kernel a usar
|
||
|
"""
|
||
|
x_pixels, y_pixels, num_channels = image.array.shape
|
||
|
new_im = Image(x_pixels=x_pixels, y_pixels=y_pixels, num_channels=num_channels)
|
||
|
|
||
|
kernel_size = kernel.shape[0]
|
||
|
neighbor_range = kernel_size // 2 # cuantos piexeles cercanos a un lado
|
||
|
|
||
|
for x in range(x_pixels):
|
||
|
for y in range(y_pixels):
|
||
|
for c in range(num_channels):
|
||
|
total = 0
|
||
|
for x_i in range(max(0, x - neighbor_range), min(x_pixels - 1, x + neighbor_range) + 1):
|
||
|
for y_i in range(max(0, y - neighbor_range), min(y_pixels - 1, y + neighbor_range) + 1):
|
||
|
# encontrar a que valor del kernel corresponde
|
||
|
x_k = x_i + neighbor_range - x
|
||
|
y_k = y_i + neighbor_range - y
|
||
|
kernel_val = kernel[x_k, y_k]
|
||
|
total += image.array[x_i, y_i, c] * kernel_val
|
||
|
new_im.array[x, y, c] = total
|
||
|
|
||
|
return new_im
|
||
|
|
||
|
def combine_images(image1, image2):
|
||
|
"""
|
||
|
El tamaño de os arreglos que representan las imagenenes deben ser identicos.
|
||
|
"""
|
||
|
x_pixels, y_pixels, num_channels = image1.array.shape
|
||
|
new_im = Image(x_pixels=x_pixels, y_pixels=y_pixels, num_channels=num_channels)
|
||
|
|
||
|
for x in range(x_pixels):
|
||
|
for y in range(y_pixels):
|
||
|
for c in range(num_channels):
|
||
|
new_im.array[x, y, c] = (image1.array[x, y, c]**2 + image2.array[x, y, c]**2)**0.5
|
||
|
return new_im
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
lake = Image(filename='lake.png')
|
||
|
city = Image(filename='city.png')
|
||
|
|
||
|
# aumentar brillo de lake
|
||
|
#brightened_im = adjust_brightness(lake, 1.7)
|
||
|
#brightened_im.write_image('brightened_lake.png')
|
||
|
# oscurecer lake
|
||
|
#darkened_im = adjust_brightness(lake, 0.3)
|
||
|
#darkened_im.write_image('darkened_lake.png')
|
||
|
|
||
|
# aumentar contraste de lake
|
||
|
#incr_contrast = adjust_contrast(lake, 2, 0.5)
|
||
|
#incr_contrast.write_image('increased_contrast_lake.png')
|
||
|
# disminuis contraste de lake
|
||
|
#incr_contrast = adjust_contrast(lake, 0.5, 0.5)
|
||
|
#incr_contrast.write_image('decreased_contrast_lake.png')
|
||
|
|
||
|
# blur con kernel 3
|
||
|
#blur_3 = blur(city, 3)
|
||
|
#blur_3.write_image('blur_k3.png')
|
||
|
# blur con kernel 15
|
||
|
#blur_15 = blur(city, 15)
|
||
|
#blur_15.write_image('blur_k15.png')
|
||
|
|
||
|
## filtro de detecion de bordes, kernel en ejes x e y
|
||
|
sobel_x_kernel = np.array([
|
||
|
[ 1, 2, 1],
|
||
|
[ 0, 0, 0],
|
||
|
[-1,-2,-1]
|
||
|
])
|
||
|
sobel_y_kernel = np.array([
|
||
|
[ 1, 0,-1],
|
||
|
[ 2, 0,-2],
|
||
|
[ 1, 0,-1]
|
||
|
])
|
||
|
sobel_x = apply_kernel(city, sobel_x_kernel)
|
||
|
#sobel_x.write_image('edge_x.png')
|
||
|
sobel_y = apply_kernel(city, sobel_y_kernel)
|
||
|
#sobel_y.write_image('edge_y.png')
|
||
|
sobel_xy = combine_images(sobel_x, sobel_y)
|
||
|
sobel_xy.write_image('edge_xy.png')
|