MAT281 - Tarea N°01: Procesamiento de Imágenes y Análisis de Datos¶
Objetivos de la Tarea¶
Esta tarea integra las herramientas de la primera mitad del curso. En la Parte I trabajarás el modelo de color RGB manipulando imágenes como arreglos de NumPy (esteganografía simple: ocultar y descifrar imágenes). En la Parte II aplicarás pandas y visualización para analizar un conjunto de datos real, el World Happiness Report.
Objetivos específicos¶
- Representar y manipular imágenes como arreglos de NumPy (modelo RGB).
- Aplicar operaciones vectorizadas, indexación y
reshape/concatenate/split. - Cargar, consolidar y limpiar datos de múltiples archivos con
pandas. - Resumir datos con
groupby,pivot_tabley filtrado condicional. - Construir visualizaciones efectivas y comunicar conclusiones.
Instrucciones¶
Completa tus datos personales en la celda correspondiente:
- Nombre:
- Rol USM:
Este archivo debe ser actualizado con tus respuestas y luego subido a tu repositorio personal del curso. Asegúrate de incluir todos los archivos necesarios para su ejecución (datos, imágenes, scripts, etc.).
La evaluación de la tarea considerará los siguientes aspectos:
- Desarrollo correcto de las soluciones solicitadas.
- Claridad, legibilidad y calidad del código.
- Calidad de las interpretaciones y conclusiones escritas.
- Reproducibilidad: al ejecutar
Kernel → Restart Kernel and Run All Cells, el notebook debe correr sin errores.
Nota: cada vez que veas una celda con
# FIXME, reemplázala por tu solución. Cada vez que se pida una interpretación, responde en la celda de texto indicada.
Datos personales¶
- Nombre:
- Rol USM:
I.- Imagenception¶
Desde Wikipedia, RGB (red, green, blue) es un modelo de color basado en la síntesis aditiva: cada color se representa por la mezcla de tres colores primarios de luz. Cada componente se mide habitualmente en una escala de 0 a 255 (1 byte).
Para efectos prácticos, una imagen de $n \times m$ píxeles se representa como un
arreglo de NumPy de dimensión $(n, m, 3)$, donde la última dimensión son las capas
R, G y B. En Python usaremos la librería Pillow (PIL).
🖼️ Sugerencia de imagen — Modelo RGB: busca "modelo de color RGB cubo aditivo" (Google Imágenes / Unsplash / Wikimedia) y pega una imagen aquí para reforzar la idea de esta sección. Descárgala en la carpeta
images/y reemplaza el marcador siguiente:

import numpy as np
from PIL import Image
Abrir y visualizar una imagen es tan simple como:
gatito = Image.open("images/gatito.png")
gatito
Para obtener su representación como arreglo usamos np.array. Observa que el resultado tiene 3 dimensiones (alto, ancho, canales).
gatito_np = np.array(gatito)
print(f"Dimensión: {gatito_np.shape}")
print(f"Tipo de dato: {gatito_np.dtype}")
1.- Encontrando la imagen oculta¶
La imagen gatito esconde otra imagen en la paridad de sus píxeles. Vamos a
descifrarla.
1.1 Crea una lista vacía llamada secret_list.
secret_list = # FIXME
1.2 Itera por cada canal RGB (gatito_np.shape[2]). En cada iteración:
- Crea un arreglo
secret_aux(2D, mismas dimensiones de píxeles) con valor0si el píxel del canal es par y1si es impar (usa el operador módulo%, sin iterar por filas/columnas). - Escala
secret_auxa valores0y255. - Cambia su
dtypeanp.uint8(.astype(np.uint8)). - Agrégalo a
secret_list.
Al finalizar, secret_list debe tener tres arreglos.
for channel in # FIXME
secret_aux = # FIXME
secret_aux = # FIXME
secret_aux = # FIXME
secret_list.append(secret_aux)
print(f"secret_list tiene {len(secret_list)} elementos")
1.3 Crea secret_np concatenando horizontalmente los elementos de secret_list (np.concatenate o np.hstack).
secret_np = # FIXME
secret_np.shape
1.4 Crea secret_img con Image.fromarray, asegurando dtype np.uint8 y usando mode="L" (escala de grises). Visualízala.
secret_img = Image.fromarray(# FIXME, mode="L")
secret_img
2.- Escondiendo una nueva imagen¶
Ahora tú esconderás una imagen.
2.1 Selecciona una imagen en blanco y negro de 2160 × 3840 px (en
images/ se incluye black_and_white_example.jpg) y cárgala en my_img con
Image.open().
🖼️ Sugerencia de imagen — Esteganografía: busca "esteganografia ocultar imagen en imagen" (Google Imágenes / Unsplash / Wikimedia) y pega una imagen aquí para reforzar la idea de esta sección. Descárgala en la carpeta
images/y reemplaza el marcador siguiente:

my_img = Image.open(# FIXME)
2.2 Crea my_img_np con np.array(my_img). Verifica que su shape sea (2160, 3840) (2D, por ser blanco y negro).
my_img_np = np.array(my_img)
print(my_img_np.shape)
2.3 Crea my_img_np_aux aplicando un umbral:
1si el píxel es mayor al umbral,0si es menor o igual.dtype=np.uint8. Parablack_and_white_example.jpgun umbral de20funciona bien.
umbral = 20
my_img_np_aux = # FIXME
Image.fromarray(my_img_np_aux * 255) # vista previa
2.4 Divide la imagen en tres arreglos de tamaño (2160, 1280) y guárdalos en la lista my_img_split (np.split / np.hsplit).
my_img_split = # FIXME
for img_array in my_img_split:
print(img_array.shape)
2.5 La imagen portadora es images/gatito_original.png (2160 × 1280). Cárgala en cat y crea cat_np; verifica cat_np.shape == (2160, 1280, 3).
cat = Image.open(# FIXME)
cat_np = # FIXME
print(cat_np.shape)
2.6 Convierte todos los valores de cat_np a pares (suma 1 a los impares). 2.7 Itera por canal RGB y suma a cada capa uno de los arreglos de my_img_split.
# 2.6
cat_np = # FIXME
# 2.7
for channel in # FIXME
cat_np[# FIXME] += # FIXME
2.8 Crea cat_secret_im con Image.fromarray(cat_np) y guárdala como images/my_secret.png.
cat_secret_im = Image.fromarray(# FIXME)
cat_secret_im.save(# FIXME)
2.9 Escribe una función imagenception(filepath) que reciba la ruta de una imagen y descifre la imagen oculta (reutiliza los pasos de la Parte 1). Pruébala con images/my_secret.png.
def imagenception(filepath):
# FIXME
return secret_img
my_secret_img = imagenception("images/my_secret.png")
my_secret_img
🖼️ Sugerencia de imagen — World Happiness: busca "world happiness report mapa felicidad" (Google Imágenes / Unsplash / Wikimedia) y pega una imagen aquí para reforzar la idea de esta sección. Descárgala en la carpeta
images/y reemplaza el marcador siguiente:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
pd.set_option("display.max_columns", 999)
sns.set_theme(style="whitegrid")
2.1 Lectura y consolidación¶
Los tres reportes no tienen las mismas columnas (p. ej. 2017 no trae
Region). Una buena práctica es leer una cantidad variable de archivos.
Tu tarea:
- Carga los tres archivos en
df15,df16,df17. - Agrega a cada uno una columna
Yeary consolida un conjunto de columnas común en un único DataFramedfconpd.concat.
base = "https://raw.githubusercontent.com/fralfaro/MAT281/main/docs/homeworks/data/world-happiness"
df15 = pd.read_csv(f"{base}/2015.csv")
df16 = pd.read_csv(f"{base}/2016.csv")
df17 = pd.read_csv(f"{base}/2017.csv")
# FIXME
2.2 Procesado y corrección¶
Tu tarea:
- El reporte 2017 perdió la columna
Region: recupérala usando 2015/2016 (mergeomappaís → región). Reporta los países sin región. - Revisa tipos de datos, valores nulos y países duplicados dentro de un año.
# FIXME
2.3 Análisis¶
Tu tarea:
Happiness Scorepromedio por región (ordenado).- Tabla wide con
pivot_table: filas = región, columnas = año. - Top 10 países más felices y menos felices en 2017.
- Interpreta: ¿qué región es consistentemente más feliz? ¿qué variable correlaciona más con la felicidad?
# FIXME
Interpretación (2.3): (escribe aquí)
2.4 Visualización¶
Tu tarea: construye al menos cuatro gráficos con su respectiva lectura:
- Histograma/KDE del
Happiness Score(2017). - Heatmap de correlaciones.
- Scatter de
Economy (GDP per Capita)vsHappiness Score, coloreado por región. - Boxplot del score por región.
🖼️ Sugerencia de imagen — Tipos de gráficos: busca "data visualization chart types cheat sheet" (Google Imágenes / Unsplash / Wikimedia) y pega una imagen aquí para reforzar la idea de esta sección. Descárgala en la carpeta
images/y reemplaza el marcador siguiente:

# FIXME
III.- Conclusiones¶
Redacta 3 a 5 conclusiones respaldadas por tu análisis: ¿qué factores se asocian con países más felices? ¿qué patrones regionales y temporales observaste? ¿qué limitaciones tienen estos datos?
Conclusiones: (escribe aquí)