Apuntes_Python/05_diez_proyectos/09-photo_manipulation/transformar.py
2022-12-24 22:41:20 -03:00

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')