Extracción y análisis de pinturas del museo de Louvre.

Descripción

Crear un programa capaz de extraer imágenes de la página del museo de Louvre, Francia. Luego con un software de análisis de imágen se identificar las personas que había en cada cuadro y finalmente analizar cómo cambia el número de personas promedio por cuadro según la época en la que se realizó la pintura.

1. Programa de extracción de imágenes de una URL dada

Librerías necesarias para ejecutar el programa

Antes de ejecutar el notebook es necesario instalar las siguientes librerías y ejecutando los siguientes comandos

In [ ]:
!pip install --user bs4
In [ ]:
!pip install --user urlib.request
In [ ]:
!pip install --user PIL
In [ ]:
!pip install --user io
In [1]:
from bs4 import BeautifulSoup
from urllib.request import urlopen
from PIL import Image
import requests
import pandas as pd
from io import BytesIO

Para este código vamos a utilizar la librería BeautifulSoup, la cual identifica los diferentes elementos de una URL dada. Luego creamos una función (get_images), que crea una lista con todos los objetos tipo imagen que detectó la librería BeautifulSoup.

Acá se encuentra el código original escrito para python2 y que utiliza la librería urllib2, la cual no es compatible con python3 (a diferencia de urllib.request que fue la utilicé en este código). El código corresponde a la tercera respuesta del foro.

Para extraer imágenes se crea dos funciones utilizando la librería BeautifulSoup, de la siguiente forma. La cual recibe como variable una URL.

In [3]:
def make_soup(url):
    html = urlopen(url).read()
    return BeautifulSoup(html)

def get_images(url):
    soup = make_soup(url)
    images = [img for img in soup.findAll('img')]
    image_links = [each.get('src') for each in images]
    return image_links

Finalmente, con la librería PIL, usando el comando Image.open, extraemos la imágen de la URL dada.

In [4]:
im1 = Image.open(requests.get(get_images('https://collections.louvre.fr/en/ark:/53355/cl010208581')[2], stream=True).raw)
im1
Out[4]:

2. Identificar las personas que se encuentran en cada imágen

La identificacion de objetos se realiza a traves del modulo imageai el cual tiene la capacidad de comparar elementos dentro de una imagen con un modelo para indicar que clase de objeto es, en este caso son personas.

El identificador fue implementado con base al codigo indicado aqui y modificado para que realizara la deteccion automaticamente.

Para realizar la identificacion de personas se instalan las siguientes librerias

In [ ]:
!pip install --user tensorflow==2.4.0
In [ ]:
!pip install --user imageai --upgrade

Se actualizan las siguiente

In [ ]:
!pip install --user keras==2.4.3 numpy==1.19.3 pillow==7.0.0 scipy==1.4.1 h5py==2.10.0 matplotlib==3.3.2 opencv-python keras-resnet==0.2.0

Ahora se importa el modulo imageai y OS. Tambien se ejecuta una linea que va a indicar donde esta el path del directorio donde estan los modelos y las pinturas.

In [4]:
from imageai.Detection import ObjectDetection
import os

Los modelos se pueden descargar directamente del repositorio indicado en la parte superior donde se encuentra el codigo original.

Ahora con las lineas siguientes se llama al modelo, en este caso es resnet50 y en la cuarta linea se carga el modelo. Finalmente en la linea 5 se indica el camino donde esta guardada la imagen(en caso de que este guardado en un lugar diferente al lugar donde esta el archivo de python se le indica el path) y en la segunda parte del codigo se le indica donde guardar una copia de la imagen analizada donde se muestra en un recuadro la persona que identifico y el porcentaje de coincidencia con el modelo.

In [7]:
execution_path = os.getcwd()

detector = ObjectDetection()
detector.setModelTypeAsYOLOv3()
detector.setModelPath( os.path.join(execution_path , "yolo.h5"))
detector.loadModel()
detections = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "image.jpg"), output_image_path=os.path.join(execution_path , "imagenew.jpg"), minimum_percentage_probability=30)
In [12]:
import matplotlib.pyplot as plt
import matplotlib.image as img
image = img.imread('image.jpg')
plt.imshow(image)
plt.show()

El codigo anterior identifica 80 objetos en cada imagen.

Luego de recorrer la imagen se obtendra lo siguiente

In [14]:
image = img.imread('imagenew.jpg')
plt.imshow(image)
plt.show()

3. Análisis de resultados

Para realizar las gráficas, se utiliza la librería seaborn que se instala mediante el siguiente comando

In [ ]:
!pip install --user seaborn
In [5]:
import seaborn as sns

Usando los resultados encontrados por el programa de identificación de personas en imágenes, el número promedio de personas por año que se encontró fue el siguiente

In [19]:
sns.scatterplot(data=datos_fecha_1250,x='fecha',y='personas')
plt.ylabel("N° de personas promedio por cuadro")
plt.xlabel("Año")
Out[19]:
Text(0.5, 0, 'Año')

Y por siglo

In [22]:
sns.scatterplot(x=siglo,y=personas_siglo)
plt.ylabel("N° de personas promedio por cuadro por siglo")
plt.xlabel("Siglo")
plt.title("Número promedio de personas por cuadro del siglo XIII al XIX de la muestra del museo de Louvre")
Out[22]:
Text(0.5, 1.0, 'Número promedio de personas por cuadro del siglo XIII al XIX de la muestra del museo de Louvre')