PDI+VC · Ejercicio de Programación

EP01_10 — 📄 Metadatos: Lectura de Archivo PGM

1.17.10 EP01_10 📄 Metadatos: Lectura de Archivo PGM

En esta actividad, debes leer un archivo de imagen en el formato PGM (Portable Gray Map) y extraer sus dimensiones a partir del encabezado.

  • El formato PGM (P2) es un archivo de texto simple (ASCII) que almacena imágenes en tonos de gris.
  • El archivo posee un encabezado estructurado de la siguiente forma:
  1. Versión: El identificador P2.
  2. Comentarios: Líneas opcionales que comienzan con # (deben ignorarse).
  3. Dimensiones: Dos enteros que representan Ancho y Alto.
  4. Máximo: Un entero que representa la intensidad máxima (generalmente 255).
  • Después del encabezado, siguen los datos de los píxeles.

📌 Importante:

  • Lectura de Archivo: Debes abrir el archivo indicado en el ejemplo utilizando la función open() de Python.
  • Orden de Salida: A diferencia del orden presente en el archivo, la salida esperada debe estar en el formato de tupla: (Altura, Ancho, Canales).
  • Como los archivos PGM son en tonos de gris, el número de Canales es siempre 1.
  • Ver un simulador interactivo para esta cuestión en la Figura 1.20 (ajusta las dimensiones para ver cómo se genera el encabezado ASCII).

1.17.10.1 🧠 Entendiendo el formato PGM

El formato PGM es uno de los más simples para el procesamiento de imágenes. Por ser en texto puro, permite visualizar los metadatos e incluso los valores de los píxeles abriendo el archivo en un bloc de notas:

Componente Ejemplo Significado
Número Mágico P2 Identifica que es un PGM en formato de texto (ASCII).
Comentario # CREATOR... Línea informativa ignorada por el procesador.
Dimensiones 397 343 397 columnas (Ancho) y 343 filas (Altura).
Intensidad 255 Define el valor del blanco puro (escala de 0 a 255).

1.17.10.2 📋 Tarea (especificación para VPL)

Entrada:

Ninguna entrada mediante teclado. El programa debe leer el archivo "aula01fig03b.pgm" presente en el directorio de ejecución.

Salida:

Una tupla que contenga (Altura, Ancho, 1).

1.17.10.3 📌 Ejemplos

Nombre del Archivo Salida Esperada Observación
“aula01fig03b.pgm” (343, 397, 1) Nota la inversión del orden: Altura primero
📄 Simulador EP01_10: Estructura del Archivo PGM ASCII P2 & Formato (H, W, C)

Cambie las dimensiones de ancho (W) y alto (H) para observar el ensamblaje dinámico del encabezado PGM y el formato de la tupla del array resultante en Python (Filas × Columnas × Canales).

DEFINICIONES DE LA IMAGEN
💡 Atención a la convención: El encabezado PGM declara primero W H (Ancho × Alto), mientras que el array en Python/NumPy reporta la tupla como (H, W, C) (Filas × Columnas × Canales).
CONTENIDO DEL ARCHIVO (.PGM)
P2
# CREADOR: UFABC PDI / EP01_10
397 343
255
120 134 210 0 85 255 ...
Salida de la función mm.readImg (Formato del Array):
(343, 397, 1)
Figura 1.20: Simulador EP01_10: Estructura de Archivo PGM (Encabezado ASCII P2 y Mapeo a Tupla Python)
NotaNota

El archivo necesario para este EP se descargará automáticamente del repositorio mediante el siguiente código:

%%writefile tmp/mm_out_2.cpp
#include <iostream>
#include <string>
// No matter how much we try, C++ does not have a direct equivalent for
// downloading files with urllib. We'll simulate the structure.

int main() {
    // Constants
    const std::string BASE_URL = "https://raw.githubusercontent.com/fzampirolli/pdi-vc/master/all/cap01/imagens";
    const std::string file = "aula01fig03b.pgm";

    // Simulating the download process (no actual download in C++ standard library)
    std::cout << "Simulating download of: " << file << "\n";

    // Simulating the loop over files
    std::string url = BASE_URL + "/" + file;
    std::cout << "URL: " << url << "\n";
    std::cout << "✅ Arquivo baixado: " << file << "\n";

    return 0;
}
Overwriting tmp/mm_out_2.cpp
!g++ -I. -std=c++17 tmp/mm_out_2.cpp -o tmp/mm_out_2 \
  && ./tmp/mm_out_2
Simulating download of: aula01fig03b.pgm
URL: https://raw.githubusercontent.com/fzampirolli/pdi-vc/master/all/cap01/imagens/aula01fig03b.pgm
✅ Arquivo baixado: aula01fig03b.pgm
%%writefile EP01_10.cpp
// your solution
Overwriting EP01_10.cpp
TestSuite("EP01_10.cpp").run()
✔️ EP01_10.cases ya existe en casos/
📋 1 caso(s) cargado(s) de casos/EP01_10.cases

🔍 Probando C++: EP01_10.cpp
⚠️ EP01_10.cpp: archivo vacío (menos de 3 líneas). Pruebas omitidas.