diff --git a/PRACTICAS/Practica 1/Ruiz-P1.pdf b/PRACTICAS/Practica 1/Ruiz-P1.pdf new file mode 100644 index 0000000..0723faf Binary files /dev/null and b/PRACTICAS/Practica 1/Ruiz-P1.pdf differ diff --git a/PRACTICAS/Practica 1/Ruiz-P1.py b/PRACTICAS/Practica 1/Ruiz-P1.py new file mode 100644 index 0000000..b3fc13e --- /dev/null +++ b/PRACTICAS/Practica 1/Ruiz-P1.py @@ -0,0 +1,384 @@ +import cv2 +import os +import numpy as np +import matplotlib.pyplot as plt + +#Cambiamos el directorio de trabajo +os.chdir('/home/jose/Escritorio/VCP1/') + +#Funcion para leer una imagen +#flagColor: 0 Grises, 1 Color +def leeimagen(filename,flagColor): + #Cargamos la imagen + img = cv2.imread(filename,flagColor)/255 + + return img + +# Funcion para mostrar una imagen. +def pintaI(im): + #Mostramos la imagen + cv2.namedWindow('image', cv2.WINDOW_NORMAL) + img = (np.clip(im,0,1)*255.).astype(np.uint8) + cv2.imshow('image',img) + cv2.waitKey(0) + cv2.destroyAllWindows() + +#Concatena varias imagenes +def multIM(img,nfil,ncol,tamx,tamy,color=True): + fig=plt.figure(figsize=(tamx, tamy)) + for i,im in enumerate(img): + fig.add_subplot(nfil, ncol, i+1) + imgt = (np.clip(im,0,1)*255.).astype(np.uint8) + if color: + nimg = cv2.cvtColor(imgt, cv2.COLOR_BGR2RGB) + else: + nimg = cv2.cvtColor(imgt,cv2.COLOR_GRAY2RGB) + plt.imshow(nimg) + plt.show() + +#Funcion que normaliza los valores de una imagen a valores positivos +def transformar(img): + minimo = np.min(img) + maximo = np.max(img) + + if minimo < 0 or maximo > 1: + img = (img-minimo)/(maximo-minimo) + + return img + +#Funcion para el ejercicio 2.A que nos devuelve una imagen con una convolucion +# separable aplicada indicando el tamaño del kernel +# ============================================================================= +# tam debe ser impar +# ============================================================================= +def convolucion_gauss(img,tam): + val = cv2.getGaussianKernel(ksize=tam,sigma=-1) + + res = cv2.sepFilter2D(src=img,ddepth=-1,kernelX=val,kernelY=val,borderType=cv2.BORDER_REFLECT_101) + + return res + +#Funcion para el ejercicio 2.B que nos devuelve una imagen con una convolucion +# 2D de primera derivada aplicada indicando el tamaño del kernel +# ============================================================================= +# tam debe ser impar +# ============================================================================= +def convolucion_1deriv(img,tam): + kx,ky = cv2.getDerivKernels(1,1,tam) + + res = cv2.sepFilter2D(src=img,ddepth=-1,kernelX=kx,kernelY=ky,borderType=cv2.BORDER_CONSTANT) + + return res + +#Funcion para el ejercicio 2.C que nos devuelve una imagen con una convolucion +# 2D de segunda derivada aplicada indicando el tamaño del kernel +# ============================================================================= +# tam debe ser impar +# ============================================================================= +def convolucion_2deriv(img,tam): + kx,ky = cv2.getDerivKernels(2,2,tam) + + res = cv2.sepFilter2D(src=img,ddepth=-1,kernelX=kx,kernelY=ky) + + return res + +# Funcion para el ejercicio 2.D que nos devuelve una imagen compuesta por +# 4 niveles de la piramide Gaussiana +def piramide_gauss(img): + res = [img] + + aux = cv2.pyrDown(img,borderType=cv2.BORDER_REFLECT_101) + res.append(aux) + aux = cv2.pyrDown(aux,borderType=cv2.BORDER_REFLECT_101) + res.append(aux) + aux = cv2.pyrDown(aux,borderType=cv2.BORDER_REFLECT_101) + res.append(aux) + + return res + + +#Funcion que muestra los elementos de una piramide +def display_piramide(img,color=True): + + for im in img: + imgt = (np.clip(im,0,1)*255.).astype(np.uint8) + if color: + nimg = cv2.cvtColor(imgt, cv2.COLOR_BGR2RGB) + else: + nimg = cv2.cvtColor(imgt,cv2.COLOR_GRAY2RGB) + dpi = 50 + height, width, depth = nimg.shape + + # What size does the figure need to be in inches to fit the image? + figsize = width / float(dpi), height / float(dpi) + + # Create a figure of the right size with one axes that takes up the full figure + plt.figure(figsize=figsize) + #ax = fig.add_axes([0, 0, 1, 1]) + + # Hide spines, ticks, etc. + #ax.axis('off') + + # Display the image. + plt.imshow(nimg) + plt.show() + +#Funcion del ejercicico 2.D que devuelve tanto las imagenes que se almacenan +# para la piramide gaussiana como las imagenes en sí +def piramide_laplaciana_down(img): + res = [img] + dif = [] + aux = img + + for i in range(3): + mini = cv2.pyrDown(aux,borderType=cv2.BORDER_REFLECT_101) + col,fil = aux.shape + maxi = cv2.pyrUp(mini,None,(fil,col),borderType=cv2.BORDER_REFLECT_101) + dif.append(aux-maxi) + res.append(mini) + aux = mini + + return res,dif + +def piramide_laplaciana_up(img,dif): + res = [img] + aux = img + + for im in reversed(dif): + col,fil = im.shape + maxi = cv2.pyrUp(aux,None,(fil,col),borderType=cv2.BORDER_REFLECT_101) + real = maxi+im + res.append(real) + aux = real + + return res + + +#Funcion que crea una imagen hibrida +def crear_hibrida(img1,img2,ksize1,ksize2): + gauss = cv2.getGaussianKernel(ksize1,-1) + gauss = cv2.sepFilter2D(img1,-1,gauss,gauss) + + g2 = cv2.getGaussianKernel(ksize2,-1) + g2 = cv2.sepFilter2D(img2,-1,g2,g2) + laplacian = img2-g2 + + res = gauss+laplacian + + return res + +############################################################################### +############################################################################### +############################################################################### +############################################################################### + + +# ============================================================================= +# Ejercicio 1: A) +# El cálculo de la convolución de una imagen con una máscara +# Gaussiana 2D (Usar GaussianBlur). Mostrar ejemplos con distintos +# tamaños de máscara y valores de sigma. Valorar los resultados. +# ============================================================================= + +img = leeimagen('imagenes/bicycle.bmp',1) + +concat = [img] + +for i in range(3,12,2): + concat.append(cv2.GaussianBlur(img,(i,i),0,0)) + +multIM(concat,2,3,28,13) + +input() + +# ============================================================================= +# Ejercicio 1: B) +# Usar getDerivKernels para obtener las máscaras 1D que permiten +# calcular al convolución 2D con máscaras de derivadas. Representar +# e interpretar dichas máscaras 1D para distintos valores de sigma. +# ============================================================================= + +for i in range(3,8,2): + kx, ky = cv2.getDerivKernels(1,0,i) + + print("Kernel de tamaño "+str(i)+ " con dx=1 y dy=0") + print(np.dot(kx,np.transpose(ky))) + +for i in range(3,8,2): + kx, ky = cv2.getDerivKernels(1,1,i) + + print("Kernel de tamaño "+str(i)+ " con dx=1 y dy=1") + print(np.dot(kx,np.transpose(ky))) + +for i in range(3,8,2): + kx, ky = cv2.getDerivKernels(0,1,i) + + print("Kernel de tamaño "+str(i)+ " con dx=0 y dy=1") + print(np.dot(kx,np.transpose(ky))) + +input() + + +# ============================================================================= +# Ejercicio 1: C) +# Usar la función Laplacian para el cálculo de la convolución 2D con +# una máscara de Laplaciana-de-Gaussiana de tamaño variable. +# Mostrar ejemplos de funcionamiento usando dos tipos de bordes y +# dos valores de sigma: 1 y 3. +# ============================================================================= + +dst = [] + +aux = cv2.Laplacian(src=img,ddepth=-1,ksize=3,borderType=cv2.BORDER_REFLECT_101) +dst.append(aux) +aux = cv2.Laplacian(src=img,ddepth=-1,ksize=3,borderType=cv2.BORDER_CONSTANT) +dst.append(aux) + +aux = cv2.Laplacian(src=img,ddepth=-1,ksize=17,borderType=cv2.BORDER_REFLECT_101) +dst.append(aux) +aux = cv2.Laplacian(src=img,ddepth=-1,ksize=17,borderType=cv2.BORDER_CONSTANT) +dst.append(aux) + +dst = map(transformar,dst) + +multIM(dst,2,2,15,10) + +input() + +# ============================================================================= +# Ejercicio 2: A) +# El cálculo de la convolución 2D con una máscara separable de +# tamaño variable. Usar bordes reflejados. Mostrar resultados +# ============================================================================= + +img = leeimagen('imagenes/motorcycle.bmp',0) + +conv_gauss1 = convolucion_gauss(img,7) +conv_gauss2 = convolucion_gauss(img,15) +conv_gauss3 = convolucion_gauss(img,21) + +multIM([conv_gauss1,conv_gauss2,conv_gauss3],1,3,20,10,False) + +input() + +# ============================================================================= +# Ejercicio 2: B) +# El cálculo de la convolución 2D con una máscara 2D de 1a 1a +# derivada de tamaño variable. Mostrar ejemplos de +# funcionamiento usando bordes a cero. +# ============================================================================= + +conv_1deriv1 = transformar(convolucion_1deriv(img,7)) +conv_1deriv2 = transformar(convolucion_1deriv(img,15)) +conv_1deriv3 = transformar(convolucion_1deriv(img,21)) + +multIM([conv_1deriv1,conv_1deriv2,conv_1deriv3],1,3,20,10,False) + +input() + +# ============================================================================= +# Ejercicio 2: C) +# El cálculo de la convolución 2D con una máscara 2D de 2a +# derivada de tamaño variable. +# ============================================================================= + +conv_2deriv1 = transformar(convolucion_2deriv(img,7)) +conv_2deriv2 = transformar(convolucion_2deriv(img,15)) +conv_2deriv3 = transformar(convolucion_2deriv(img,21)) + +multIM([conv_2deriv1,conv_2deriv2,conv_2deriv3],1,3,20,10,False) + +input() + +# ============================================================================= +# Ejercicio 2: D) +# Una función que genere una representación en pirámide +# Gaussiana de 4 niveles de una imagen. Mostrar ejemplos de +# funcionamiento usando bordes +# ============================================================================= + +dst = piramide_gauss(img) + +display_piramide(dst,False) + +input() + +# ============================================================================= +# Ejercicio 2: E) +# Una función que genere una representación en pirámide +# Laplaciana de 4 niveles de una imagen. Mostrar ejemplos de +# funcionamiento usando bordes. +# ============================================================================= + +dest = [] +dif = [] + +dst,dif = piramide_laplaciana_down(img) + +display_piramide(dst,False) + +trans = map(transformar,dif) + +display_piramide(trans,False) + +up = piramide_laplaciana_up(dst[len(dst)-1],dif) + +display_piramide(up,False) + +input() + +# ============================================================================= +# Ejercicio 3 +# Mezclando adecuadamente una parte de las frecuencias altas de una +# imagen con una parte de las frecuencias bajas de otra imagen, obtenemos +# una imagen híbrida que admite distintas interpretaciones a distintas +# distancias ( ver hybrid images project page). +# Para seleccionar la parte de frecuencias altas y bajas que nos quedamos +# de cada una de las imágenes usaremos el parámetro sigma del +# núcleo/máscara de alisamiento gaussiano que usaremos. A mayor valor +# de sigma mayor eliminación de altas frecuencias en la imagen +# convolucionada. Para una buena implementación elegir dicho valor de +# forma separada para cada una de las dos imágenes ( ver lase comendaciones +# dadas en el paper de Oliva et al.). Recordar que las máscaras 1D siempre deben +# tener de longitud un número impar. +# +# Implementar una función que genere las imágenes de baja y alta +# frecuencia a partir de las parejas de imágenes ( solo en la versión de +# imágenes de gris) . El valor de sigma más adecuado para cada pareja +# habrá que encontrarlo por experimentación +# +# Escribir una función que muestre las tres imágenes ( alta, +# baja e híbrida) en una misma ventana. (Recordar que las +# imágenes después de una convolución contienen número +# flotantes que pueden ser positivos y negativos) +# +# Realizar la composición con al menos 3 de las parejas de +# imágenes +# ============================================================================= + +img1 = leeimagen('imagenes/cat.bmp',0) +img2 = leeimagen('imagenes/dog.bmp',0) + +animales = crear_hibrida(img1,img2,41,31) + +multIM([img1,img2,animales],1,3,15,10,False) + +img1 = leeimagen('imagenes/einstein.bmp',0) +img2 = leeimagen('imagenes/marilyn.bmp',0) + +personas = crear_hibrida(img1,img2,21,17) + +multIM([img1,img2,personas],1,3,15,10,False) + +img1 = leeimagen('imagenes/bird.bmp',0) +img2 = leeimagen('imagenes/plane.bmp',0) + +aire = crear_hibrida(img1,img2,24,17) + +multIM([img1,img2,aire],1,3,15,10,False) + +pir = piramide_gauss(personas) + +display_piramide(pir,False) + +input() diff --git a/PRACTICAS/Practica 2/Ruiz-P2.pdf b/PRACTICAS/Practica 2/Ruiz-P2.pdf new file mode 100644 index 0000000..d8c471d Binary files /dev/null and b/PRACTICAS/Practica 2/Ruiz-P2.pdf differ diff --git a/PRACTICAS/Practica 2/Ruiz-P2.py b/PRACTICAS/Practica 2/Ruiz-P2.py new file mode 100644 index 0000000..a1c6e2e --- /dev/null +++ b/PRACTICAS/Practica 2/Ruiz-P2.py @@ -0,0 +1,590 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +@author: jose +""" + +import cv2 +import os +import numpy as np +import matplotlib.pyplot as plt +import random + +#Cambiamos el directorio de trabajo +os.chdir('./imagenes/') + +# ============================================================================= +# Funcion para leer una imagen +# flagColor: 0 Grises, 1 Color +# ============================================================================= +def leeimagen(filename,flagColor): + #Cargamos la imagen + img = cv2.imread(filename,flagColor) + + return img + +# ============================================================================= +# Funcion para mostrar una imagen. +# ============================================================================= +def pintaI(im): + #Mostramos la imagen + cv2.namedWindow('image', cv2.WINDOW_NORMAL) +# img = (np.clip(im,0,1)*255.).astype(np.uint8) + cv2.imshow('image',im) + cv2.waitKey(0) + cv2.destroyAllWindows() + +# ============================================================================= +# Concatena varias imagenes +# ============================================================================= +def multIM(img,nfil,ncol,tamx,tamy,color=True): + fig=plt.figure(figsize=(tamx, tamy)) + for i,im in enumerate(img): + fig.add_subplot(nfil, ncol, i+1) +# imgt = (np.clip(im,0,1)*255.).astype(np.uint8) + if color: + nimg = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) + else: + nimg = cv2.cvtColor(im,cv2.COLOR_GRAY2RGB) + plt.imshow(nimg) + plt.show() + +# ============================================================================= +# Funcion para mostrar los puntos por octavas +# Funcion del ejercicio 1.b +# ============================================================================= +def pintaPuntos(img,kp,colores,surf=True): + #Hago una copia para no modificar la imagen que se nos pasa + img2 = img.copy() + + #Para cada keyPoint + for p in kp: + #Obtenemos su octava + if(surf): + oc = p.octave + else: + oc,l,s = unpackSIFTOctave(p) + oc += 1 + #Dibujamos la circunferencia en la imagen + cv2.circle(img2,(int(p.pt[0]),int(p.pt[1])),int(p.size/2),list(map(int,colores[oc])),1,cv2.LINE_AA ) + + return img2 + +# ============================================================================= +# Nos devuelve un vector indicadno el numero de puntos que hay por octava +# Funcion del ejercicio 1.b +# ============================================================================= +def puntosPorOctava(kp,surf=True): + #Inicializamos un vector con todo ceros + puntos = np.zeros(20) + + #Por cada keyPoint + for p in kp: + #Obtenemos su octava + if surf: + oc = p.octave + else: + oc,l,s = unpackSIFTOctave(p) + oc+=1 + + #Sumamos uno a la posicion correspondiente a la octava + puntos[oc] += 1 + + return puntos[puntos>0] + +# ============================================================================= +# Nos devuelve un vector indicadno el numero de puntos que hay por capa +# Funcion del ejercicio 1.b +# ============================================================================= +def puntosPorCapa(kp,octava): + #Inicializamos un vector a 0 + puntos = np.zeros(20) + + #Por cada keyPoint + for p in kp: + #Obtenemos su octava + oc,l,s = unpackSIFTOctave(p) + oc+=1 + #Si la octava coincide con la que queremos calcular sumamos uno a la + # posicion correspondiente en el vector + if oc == octava: + puntos[l-1] += 1 + + return puntos[puntos>0] + +# ============================================================================= +# Funcion para desempaquetar los keypoints del método SIFT +# ============================================================================= +def unpackSIFTOctave(kpt): + """unpackSIFTOctave(kpt)->(octave,layer,scale) + @created by Silencer at 2018.01.23 11:12:30 CST + @brief Unpack Sift Keypoint by Silencer + @param kpt: cv2.KeyPoint (of SIFT) + """ + _octave = kpt.octave + octave = _octave&0xFF + layer = (_octave>>8)&0xFF + if octave>=128: + octave |= -128 + if octave>=0: + scale = float(1/(1< maxy else maxy + maxx = im.shape[1] if im.shape[1] > maxx else maxx + + #Calculamos el tamaño del lienzo final + mosaico_size = [maxx*3,maxy*3] + + #Creo la matriz de traslacion + H = np.eye(3) + H[1][2] = (mosaico_size[1]/2-(maxy/2)) + + #Posicionamos la primera imagen en el lienzo + result = cv2.warpPerspective(imgs[0],H,(mosaico_size[0],mosaico_size[1])) + + #Calculamos los puntos necesarios para crear la homografia entre la primera + #imagen y la siguiente + p1 = np.array([kps[0][m.queryIdx].pt for m in matches[0]]) + p2 = np.array([kps[1][m.trainIdx].pt for m in matches[0]]) + #Calculamos la homografia entre estas dos imagenes + homography,masc = cv2.findHomography(p2,p1, cv2.RANSAC,1) + #Colocamos la imagen en el lienzo junto a al primera + cv2.warpPerspective(imgs[1],H.dot(homography),(mosaico_size[0],mosaico_size[1]),dst=result,borderMode=cv2.BORDER_TRANSPARENT) + + #Calculamos los puntos correspondientes entre la segunda imagen y + # la tercera + p1 = np.array([kps[1][m.queryIdx].pt for m in matches[1]]) + p2 = np.array([kps[2][m.trainIdx].pt for m in matches[1]]) + #Calculamos la homografía acumulada + H = H.dot(homography) + #Calculamos la homografia entre estas dos imagenes + homography,masc = cv2.findHomography(p2,p1, cv2.RANSAC,1) + #Añadimos esta tercera imagen al lienzo final + cv2.warpPerspective(imgs[2],H.dot(homography),(mosaico_size[0],mosaico_size[1]),dst=result,borderMode=cv2.BORDER_TRANSPARENT) + + if(r): + result = recortar(result) + + return result + +# ============================================================================= +# Funcion que crea un panorama dadas N imagenes y sus respectivos +# KeyPoints con sus matches. +# Funcion ejercicio 3 +# ============================================================================= +def mosaicoN(imgs,kps,matches,r=True): + maxx = 0 + maxy = 0 + #Obtenemos el tamaño de la imagen mas grande + for im in imgs: + maxy = im.shape[0] if im.shape[0] > maxy else maxy + maxx = im.shape[1] if im.shape[1] > maxx else maxx + + #Calculamos el tamaño del lienzo final + mosaico_size = [maxx*len(imgs),maxy*len(imgs)] + + #Creo la matriz de traslacion + H = np.eye(3) + H[1][2] = (mosaico_size[1]/2-(maxy/2)) + + #Posicionamos la primera imagen en el lienzo + result = cv2.warpPerspective(imgs[0],H,(mosaico_size[0],mosaico_size[1])) + + #Para cada una de las siguientes imágenes, se obtienen los puntos y junto + # con la de la anterior, se crean las homografías que van acumulandose + # con las anteriores y voy colocando cada una de las imagenes en el lienzo + # final + for i in range(len(imgs)-1): + p1 = np.array([kps[i][m.queryIdx].pt for m in matches[i]]) + p2 = np.array([kps[i+1][m.trainIdx].pt for m in matches[i]]) + homography,masc = cv2.findHomography(p2,p1, cv2.RANSAC,1) + cv2.warpPerspective(imgs[i+1],H.dot(homography),(mosaico_size[0],mosaico_size[1]),dst=result,borderMode=cv2.BORDER_TRANSPARENT) + H = H.dot(homography) + + if(r): + result = recortar(result) + + return result + +# ============================================================================= +# BFMatcher con knn2 y utilizando Lowe-Average +# Funcion para el ejercicio 3 y 4 +# ============================================================================= +def BFL2NN(des1,des2): + bf = cv2.BFMatcher(crossCheck=False) + + matches = bf.knnMatch(des1,des2,k=2) + + good = [] + for m,n in matches: + if m.distance < 0.7*n.distance: + good.append([m]) + + return list(map(lambda x:x[0],good)) + +############################################################################### +############################################################################### +############################################################################### +############################################################################### + + +# ============================================================================= +# Ejercicio 1 +# (3 puntos) Detección de puntos SIFT y SURF. Aplicar la detección de +# puntos SIFT y SURF sobre las imágenes, representar dichos puntos sobre +# las imágenes haciendo uso de la función drawKeyPoints. Presentar los +# resultados con las imágenes Yosemite.rar. +# ============================================================================= + +img1 = leeimagen("Yosemite1.jpg",1) +gray1 = leeimagen("Yosemite1.jpg",0) + +img2 = leeimagen("Yosemite2.jpg",1) +gray2 = leeimagen("Yosemite2.jpg",0) + +# SIFT + +sift = cv2.xfeatures2d.SIFT_create() +kpsi1 = sift.detect(gray1,None) +kpsi2 = sift.detect(gray2,None) + +imgsi1 = cv2.drawKeypoints(gray1,kpsi1,None) +imgsi2 = cv2.drawKeypoints(gray2,kpsi2,None) + +# SURF + +surf = cv2.xfeatures2d.SURF_create() +kpsf1 = surf.detect(gray1,None) +kpsf2 = surf.detect(gray2,None) + +imgsf1 = cv2.drawKeypoints(gray1,kpsf1,None) +imgsf2 = cv2.drawKeypoints(gray2,kpsf2,None) + +multIM([imgsi1,imgsi2,imgsf1,imgsf2],2,2,15,10) + +input() + +# ============================================================================= +# Ejercicio 1 - Apartado (a) +# (a) Variar los valores de umbral de la función de detección de puntos +# hasta obtener un conjunto numeroso (≥ 1000) de puntos SIFT y +# SURF que sea representativo de la imagen. Justificar la elección +# de los parámetros en relación a la representatividad de los puntos +# obtenidos. +# ============================================================================= + + +# SIFT + +sift = cv2.xfeatures2d.SIFT_create(contrastThreshold=0.06,edgeThreshold=6) +kpsi1 = sift.detect(gray1,None) +kpsi2 = sift.detect(gray2,None) + +imgsi1 = cv2.drawKeypoints(gray1,kpsi1,None) +imgsi2 = cv2.drawKeypoints(gray2,kpsi2,None) + +# SURF + +surf = cv2.xfeatures2d.SURF_create(hessianThreshold=400) +kpsf1 = surf.detect(gray1,None) +kpsf2 = surf.detect(gray2,None) + +imgsf1 = cv2.drawKeypoints(gray1,kpsf1,None) +imgsf2 = cv2.drawKeypoints(gray2,kpsf2,None) + +multIM([imgsi1,imgsi2,imgsf1,imgsf2],2,2,15,10) + +input() + +# ============================================================================= +# Ejercicio 1 - Apartado (b) +# (b) Identificar cuántos puntos se han detectado dentro de cada octava. +# En el caso de SIFT, identificar también los puntos detectados en +# cada capa. Mostrar el resultado dibujando sobre la imagen original +# un cı́rculo centrado en cada punto y de radio proporcional al valor de +# sigma usado para su detección (ver circle()) y pintar cada octava +# en un color. +# ============================================================================= + +# SIFT + +siftm = cv2.xfeatures2d.SIFT_create(1000) +kpsi1m = siftm.detect(gray1,None) +kpsi2m = siftm.detect(gray2,None) + +print("La imagen 1 con SIFT tiene "+str(len(kpsi1m))+" KeyPoints.") +pp = puntosPorOctava(kpsi1m,False) +for i,p in enumerate(pp): + print("La octava "+str(i)+" tiene "+str(int(pp[i]))+" KeyPoints.") + cp = puntosPorCapa(kpsi1m,i) + for j in range(cp.size): + print("La capa "+str(j)+" de la octava "+str(i)+" tiene "+str(int(cp[j]))+" KeyPoints.") + +print("\nLa imagen 2 con SIFT tiene "+str(len(kpsi2m))) +pp = puntosPorOctava(kpsi2m,False) +for i,p in enumerate(pp): + print("La octava "+str(i)+" tiene "+str(int(pp[i]))+" KeyPoints.") + cp = puntosPorCapa(kpsi2m,i) + for j in range(cp.size): + print("La capa "+str(j)+" de la octava "+str(i)+" tiene "+str(int(cp[j]))+" KeyPoints.") + +nimg1 = cv2.cvtColor(gray1,cv2.COLOR_GRAY2BGR) +nimg2 = cv2.cvtColor(gray2,cv2.COLOR_GRAY2BGR) + +colores = np.array([[0, 0, 255], + [ 0, 255, 0], + [ 255, 0, 0], + [ 255, 0, 255], + [255, 255, 0], + [0, 255, 255], + [255, 0, 125], + [125, 0, 255], + [0,0,0], + [0, 150, 255]], dtype=np.uint8) + +imgsi1 = pintaPuntos(nimg1,kpsi1m,colores,False) +imgsi2 = pintaPuntos(nimg2,kpsi2m,colores,False) + +# SURF + +surfm = cv2.xfeatures2d.SURF_create(2000) +kpsf1m = surfm.detect(gray1,None) +kpsf2m = surfm.detect(gray2,None) + +print("\nLa imagen 1 con SURF tiene "+str(len(kpsf1m))) +pp = puntosPorOctava(kpsf1m) +for i,p in enumerate(pp): + print("La octava "+str(i)+" tiene "+str(int(pp[i]))+" KeyPoints.") + +print("\nLa imagen 2 con SURF tiene "+str(len(kpsf2m))) +pp = puntosPorOctava(kpsf2m) +for i,p in enumerate(pp): + print("La octava "+str(i)+" tiene "+str(int(pp[i]))+" KeyPoints.") + +imgsf1 = pintaPuntos(nimg1,kpsf1m,colores) +imgsf2 = pintaPuntos(nimg2,kpsf2m,colores) + +multIM([imgsi1,imgsi2,imgsf1,imgsf2],2,2,15,10) + +input() + +# ============================================================================= +# Ejercicio 1 - Apartado (c) +# (c) Mostrar cómo con el vector de keyPoint extraıdos se pueden calcu- +# lar los descriptores SIFT y SURF asociados a cada punto usando +# OpenCV. +# ============================================================================= + +#SIFT + +kpsi1,desi1 = sift.compute(gray1,kpsi1) +kpsi2,desi2 = sift.compute(gray2,kpsi2) + +print("img1 SIFT") +print("kp = "+str(len(kpsi1))) +print("des = "+str(desi1.shape)) +print("img2 SIFT") +print("kp = "+str(len(kpsi2))) +print("des = "+str(desi2.shape)) + +#SURF + +kpsf1,desf1 = sift.compute(gray1,kpsf1) +kpsf2,desf2 = sift.compute(gray2,kpsf2) + +print("img1 SURF") +print("kp = "+str(len(kpsf1))) +print("des = "+str(desf1.shape)) +print("img2 SURF") +print("kp = "+str(len(kpsf2))) +print("des = "+str(desf2.shape)) + +input() + +# ============================================================================= +# Ejercicio 2 +# 2. (2.5 puntos) Usar el detector-descriptor SIFT de OpenCV sobre las imágenes +# de Yosemite.rar (cv2.xfeatures2d.SIFT create()). Extraer sus lis- +# tas de keyPoints y descriptores asociados. Establecer las corresponden- +# cias existentes entre ellos usando el objeto BFMatcher de OpenCV y los +# criterios de correspondencias “BruteForce+crossCheck y “Lowe-Average- +# 2NN”. (NOTA: Si se usan los resultados propios del puntos anterior en +# lugar del cálculo de SIFT de OpenCV se añaden 0.5 puntos) +# ============================================================================= + +# ============================================================================= +# Ejercicico 2 - Apartado (a) +# (a) Mostrar ambas imágenes en un mismo canvas y pintar lıneas de difer- +# entes colores entre las coordenadas de los puntos en correspondencias. +# Mostrar en cada caso 100 elegidas aleatoriamente. +# ============================================================================= + +# ============================================================================= +# BruteForce+crossCheck +# ============================================================================= + +bf = cv2.BFMatcher(crossCheck=True) + +matches = bf.match(desi1,desi2) + +matches = sorted(matches, key = lambda x:x.distance) +sample = random.sample(matches,100) + +bfc = cv2.drawMatches(gray1,kpsi1,gray2,kpsi2,sample,None,flags=2) + +# ============================================================================= +# Lowe-Average-2NN +# ============================================================================= + +bf = cv2.BFMatcher(crossCheck=False) + +matches = bf.knnMatch(desi1,desi2,k=2) + +good = [] +for m,n in matches: + if m.distance < 0.7*n.distance: + good.append([m]) + +sample = random.sample(good,100) + +bfnn = cv2.drawMatchesKnn(gray1,kpsi1,gray2,kpsi2,sample,None,flags=2) + +multIM([bfc,bfnn],2,1,15,10) + +input() + +# ============================================================================= +# Ejercicio 3 +# 3. (2.5 puntos) Escribir una función que genere un mosaico de calidad a +# partir de N = 3 imágenes relacionadas por homografıas, sus listas de +# keyPoints calculados de acuerdo al punto anterior y las correspondencias +# encontradas entre dichas listas. Estimar las homografıas entre ellas usando +# la función cv2.findHomography(p1,p2, CV RANSAC,1). Para el mosaico +# será necesario. +# ============================================================================= + +img1 = leeimagen("yosemite1.jpg",1) +img2 = leeimagen("yosemite2.jpg",1) +img3 = leeimagen("yosemite3.jpg",1) +gray1 = leeimagen("yosemite1.jpg",0) +gray2 = leeimagen("yosemite2.jpg",0) +gray3 = leeimagen("yosemite3.jpg",0) + +imgs = [img1,img2,img3] + +sift = cv2.xfeatures2d.SIFT_create() +kp1 = sift.detect(gray1,None) +kp2 = sift.detect(gray2,None) +kp3 = sift.detect(gray3,None) + +kp1,des1 = sift.compute(gray1,kp1) +kp2,des2 = sift.compute(gray2,kp2) +kp3,des3 = sift.compute(gray3,kp3) + +kps = [kp1,kp2,kp3] + +matches12 = BFL2NN(des1,des2) +matches23 = BFL2NN(des2,des3) + +matches = [matches12,matches23] + +mosaico = mosaico3(imgs,kps,matches) + +multIM([mosaico],1,1,10,10) + +input() + +# ============================================================================= +# Ejercicio 4 +# 4. (2.5 puntos) Lo mismo que en el punto anterior pero para N > 5 (usar las +# imágenes para mosaico). +# ============================================================================= + +img1 = leeimagen("mosaico002.jpg",1) +img2 = leeimagen("mosaico003.jpg",1) +img3 = leeimagen("mosaico004.jpg",1) +img4 = leeimagen("mosaico005.jpg",1) +img5 = leeimagen("mosaico006.jpg",1) +img6 = leeimagen("mosaico007.jpg",1) +img7 = leeimagen("mosaico008.jpg",1) +img8 = leeimagen("mosaico009.jpg",1) +img9 = leeimagen("mosaico010.jpg",1) +img10 = leeimagen("mosaico011.jpg",1) +gray1 = leeimagen("mosaico002.jpg",0) +gray2 = leeimagen("mosaico003.jpg",0) +gray3 = leeimagen("mosaico004.jpg",0) +gray4 = leeimagen("mosaico005.jpg",0) +gray5 = leeimagen("mosaico006.jpg",0) +gray6 = leeimagen("mosaico007.jpg",0) +gray7 = leeimagen("mosaico008.jpg",0) +gray8 = leeimagen("mosaico009.jpg",0) +gray9 = leeimagen("mosaico010.jpg",0) +gray10 = leeimagen("mosaico011.jpg",0) + +imgs = [img1,img2,img3,img4,img5,img6,img7,img8,img9,img10] + +sift = cv2.xfeatures2d.SIFT_create() +kp1 = sift.detect(gray1,None) +kp2 = sift.detect(gray2,None) +kp3 = sift.detect(gray3,None) +kp4 = sift.detect(gray4,None) +kp5 = sift.detect(gray5,None) +kp6 = sift.detect(gray6,None) +kp7 = sift.detect(gray7,None) +kp8 = sift.detect(gray8,None) +kp9 = sift.detect(gray9,None) +kp10 = sift.detect(gray10,None) + +kp1,des1 = sift.compute(gray1,kp1) +kp2,des2 = sift.compute(gray2,kp2) +kp3,des3 = sift.compute(gray3,kp3) +kp4,des4 = sift.compute(gray4,kp4) +kp5,des5 = sift.compute(gray5,kp5) +kp6,des6 = sift.compute(gray6,kp6) +kp7,des7 = sift.compute(gray7,kp7) +kp8,des8 = sift.compute(gray8,kp8) +kp9,des9 = sift.compute(gray9,kp9) +kp10,des10 = sift.compute(gray10,kp10) + +kps = [kp1,kp2,kp3,kp4,kp5,kp6,kp7,kp8,kp9,kp10] + +matches12 = BFL2NN(des1,des2) +matches23 = BFL2NN(des2,des3) +matches34 = BFL2NN(des3,des4) +matches45 = BFL2NN(des4,des5) +matches56 = BFL2NN(des5,des6) +matches67 = BFL2NN(des6,des7) +matches78 = BFL2NN(des7,des8) +matches89 = BFL2NN(des8,des9) +matches910 = BFL2NN(des9,des10) + +matches = [matches12,matches23,matches34,matches45,matches56,matches67,matches78] +matches.extend([matches89,matches910]) + +mosaico = mosaicoN(imgs,kps,matches) + +multIM([mosaico],1,1,10,10) \ No newline at end of file diff --git a/PRACTICAS/Practica 3/Ruiz_P3.pdf b/PRACTICAS/Practica 3/Ruiz_P3.pdf new file mode 100644 index 0000000..f60c304 Binary files /dev/null and b/PRACTICAS/Practica 3/Ruiz_P3.pdf differ diff --git a/PRACTICAS/Practica 3/Ruiz_P3.py b/PRACTICAS/Practica 3/Ruiz_P3.py new file mode 100644 index 0000000..0c7cd3a --- /dev/null +++ b/PRACTICAS/Practica 3/Ruiz_P3.py @@ -0,0 +1,608 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Wed Dec 19 16:57:26 2018 + +@author: jose +""" + +import os +import cv2 +import matplotlib.pyplot as plt +import numpy as np +import pickle +from os import listdir +from os.path import join,isfile +from numpy.linalg import norm + +#Cambiamos el directorio de trabajo +os.chdir('./imagenes/') + +def loadDictionary(filename): + with open(filename,"rb") as fd: + feat=pickle.load(fd) + return feat["accuracy"],feat["labels"], feat["dictionary"] + +def loadAux(filename, flagPatches): + if flagPatches: + with open(filename,"rb") as fd: + feat=pickle.load(fd) + return feat["descriptors"],feat["patches"] + else: + with open(filename,"rb") as fd: + feat=pickle.load(fd) + return feat["descriptors"] + +def extractRegion(image): + global refPt, imagen,FlagEND + imagen=image.copy() + # load the image and setup the mouse callback function + refPt=[] + FlagEND=True + #image = cv2.imread(filename) + cv2.namedWindow("image") + # keep looping until the 'q' key is pressed + cv2.setMouseCallback("image", click_and_draw) + # + while FlagEND: + # display the image and wait for a keypress + cv2.imshow("image", image) + cv2.waitKey(0) + # + print('FlagEND', FlagEND) + refPt.pop() + refPt.append(refPt[0]) + cv2.destroyWindow("image") + return refPt + +def click_and_draw(event,x,y,flags,param): + global refPt, imagen,FlagEND + + + # if the left mouse button was clicked, record the starting + # (x, y) coordinates and indicate that cropping is being + # performed + if event == cv2.EVENT_LBUTTONDBLCLK: + FlagEND= False + cv2.destroyWindow("image") + + elif event == cv2.EVENT_LBUTTONDOWN: + refPt.append((x, y)) + #cropping = True + print("rfePt[0]",refPt[0]) + + + elif (event == cv2.EVENT_MOUSEMOVE) & (len(refPt) > 0) & FlagEND: + # check to see if the mouse move + clone=imagen.copy() + nPt=(x,y) + print("npt",nPt) + sz=len(refPt) + cv2.line(clone,refPt[sz-1],nPt,(0, 255, 0), 2) + cv2.imshow("image", clone) + cv2.waitKey(0) + + elif event == cv2.EVENT_RBUTTONDOWN: + # record the ending (x, y) coordinates and indicate that + # the cropping operation is finished + refPt.append((x, y)) + #cropping = False + sz=len(refPt) + print("refPt[sz]",sz,refPt[sz-1]) + cv2.line(imagen,refPt[sz-2],refPt[sz-1],(0, 255, 0), 2) + cv2.imshow("image", imagen) + cv2.waitKey(0) + +# ============================================================================= +# Funcion para leer una imagen +# flagColor: 0 Grises, 1 Color +# ============================================================================= +def leeimagen(filename,flagColor): + #Cargamos la imagen + img = cv2.imread(filename,flagColor) + + return img + +# ============================================================================= +# Concatena varias imagenes +# ============================================================================= +def multIM(img,nfil,ncol,tamx,tamy,color=True): + fig=plt.figure(figsize=(tamx, tamy)) + for i,im in enumerate(img): + fig.add_subplot(nfil, ncol, i+1) +# imgt = (np.clip(im,0,1)*255.).astype(np.uint8) + if color: + nimg = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) + else: + nimg = cv2.cvtColor(im,cv2.COLOR_GRAY2RGB) + plt.imshow(nimg) + plt.show() + +# ============================================================================= +# Funcion que crea una mascara dada una imagen y los vertices de la zona +# donde queremos crea la mascara +# ============================================================================= +def crearMascara(img,vertices): + #Creamos una matriz vacia + m = np.zeros(img.shape,dtype=np.uint8) + + #Creamos un array con los puntos seleccionados de la imagen + approCurve = cv2.approxPolyDP(np.array(vertices,dtype=np.int64),1.0,True) + + #Ahora pasamos estos puntos dentro de la matriz creada al inicio. + cv2.fillConvexPoly(m, approCurve,color=(255,255,255)) + + #Pasamos el color de la mascara a grises + m = cv2.cvtColor(m,cv2.COLOR_BGR2GRAY) + + #Devolvemos la mascara + return m + +# ============================================================================= +# Calcula los descriptores de una imagen +# ============================================================================= +def calcularDescriptores(img,masc=None): + #Pasamos la imagen a gris + gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) + + #Calculamos los descriptores usando SIFT + sift = cv2.xfeatures2d.SIFT_create() + kp,desc = sift.detectAndCompute(gray,masc) + + #Devolvemos tanto los keypoints como los descriptores + return [kp,desc] + +# ============================================================================= +# Calcula las correspondencias entre dos descriptores usando el algoritmo 2NN-Low +# ============================================================================= +def BFL2NN(des1,des2): + bf = cv2.BFMatcher(normType=cv2.NORM_L2,crossCheck=False) + + matches = bf.knnMatch(des1,des2,k=2) + + good = [] + for m,n in matches: + if m.distance < 0.7*n.distance: + good.append([m]) + + good = sorted(good,key=lambda dist:dist[0].distance, reverse=False) + + return good + +# ============================================================================= +# Calcula las correspondencias entre dos imagenes usando una mascara +# ============================================================================= +def calcularCorrespondencias(img1,img2,masc): + # Calculamos los descriptores. + kp1, desc1 = calcularDescriptores(img1, masc) + kp2,desc2 = calcularDescriptores(img2) + + # Calculamos las correpondencias. + corr = BFL2NN(desc1,desc2) + + # Dibujamos las correspondencias. + matches = cv2.drawMatchesKnn(img1=img1,keypoints1=kp1,img2=img2,keypoints2=kp2,matches1to2=corr,outImg=None,flags=2) + + return matches + +# ============================================================================= +# Funcion que calcula los votos para todas las palabras de un diccionario dada +# una imagen +# ============================================================================= +def calcularVotos(img,diccionario): + #Calculamos os decriptores de la imagen. + kp, desc = calcularDescriptores(img) + + # Normalizamos los descriptores de la imagen. + desc = cv2.normalize(src=desc,dst=None,norm_type=cv2.NORM_L2) + dicc = cv2.normalize(src=diccionario,dst=None,norm_type=cv2.NORM_L2) + + # calculamos de semejanza entre las palabras y los descriptores. + votos = np.dot(dicc,desc.T) + + + # Calculamos las palabras que han sido más votadas para la imagen. + palabrasImg = np.zeros(shape=votos.shape[0], dtype=np.int) + for col in range(votos.shape[1]): + # Obtenemos la matriz. + desc_column = votos[:, col] + # Obtenemos el indice del mejor valor de semejanza + min_index = np.argmax(desc_column) + # Aumentamos en uno el número de votos. + palabrasImg[min_index] += 1 + + + # Guardamos palabras y número de votos. + palabras = [[index, palabrasImg[index]] for index in range(len(palabrasImg)) if palabrasImg[index] > 0] + palabras = dict(palabras) + + + return [palabras,palabrasImg] + +# ============================================================================= +# Crea el indice invertido + bolsa de palabras dado un diccionario +# ============================================================================= +def crearIndicesInvertidos(diccionario): + #Cargamos los nombre de todas las imagenes + nombres = [img for img in listdir('./') if isfile(img) and '.pkl' not in img ] + #Creamos un diccionario que contendra el modelo indice invertido + indicesInvertidos = dict([index,[]] for index in range(diccionario.shape[0])) + #Creamos la bolsa de palabras conjunta + bolsa = dict() + + #Para cada imagen + for fich in nombres: + print("calculando votos para:", fich) + #Leelemos la imagen + img = leeimagen(fich,1) + #Calculamos los votos de esta imagen con el diccionario de entrada + votos, bolsaImg = calcularVotos(img,diccionario) + + #Alamacenamos en la bolsa de palabras final el resultado obtenido + #para la imagen en la que estamos. + bolsa[fich] = bolsaImg + + #Recorremos los votos y añadimos para cada uno de los indices, + #la propia imagen. + for index,vot in votos.items(): + indicesInvertidos[index].append(fich) + + #Devolvemos el modelo de indice invertido mas la bolsa de palabras + return [indicesInvertidos, bolsa] + +# ============================================================================= +# Funcion para obtener imagenes semejantes mediante las palabras de una imagen +# ============================================================================= +def imagenesMismasPalabras(diccionario,img, indicesInvertidos): + # Calculamos los votos de la imágenes. + votos, bolsaImg = calcularVotos(img,diccionario) + + # Obtenemos las imágenes que también tienen esas palabras. + imagenes = set() + for palabra, vot in votos.items(): + for nombre in indicesInvertidos[palabra]: + imagenes.add(nombre) + + return imagenes + +# ============================================================================= +# Funcion que calcula las imagens similares a una imagen dada utilizando +# un modelo de indice invertido + bolsa de palabras +# ============================================================================= +def calcularImagenesSimilares(img,indicesInvertidos,diccionario, bolsa,nmax=5): + # Calculamos las imágenes que tienen los mismas palabras que la imagen. + imgs = imagenesMismasPalabras(diccionario,img,indicesInvertidos) + + # calculamos la bolsa de palabras de las imagenes que tienen + # palabras parecidas con las palabras de la imagen. + bolsaImgs = dict([fich,bolsa[fich]] for fich in imgs ) + # Calculamos la bolsa de palabras de nuestra imagen. + vot, bolsaImg = calcularVotos(img,diccionario) + + + # Para cada imagen de bolsaImgs calculamos la semejanza con nuestra imagen. + + similar = [ [fich, ( np.dot(bolsaImg,bImg.T) ) / (norm(bolsaImg)*norm(bImg))] + for fich,bImg in bolsaImgs.items()] + + similar = sorted(similar, key=lambda par: par[1], reverse=True)[:nmax+1] + + similar = dict(similar) + + return similar + +# ============================================================================= +# Funcion que calcula los descriptores mas cercanos a la palabra visual dada +# ============================================================================= +def descriptoresCercanos(descriptores,palabra): + + # Calculamos las distancias entre la palabra y el descriptor. + distancias = [[index,cv2.norm(src1=palabra,src2=desc, normType=cv2.NORM_L2)] for index,desc in descriptores.items()] + + # Ordenamos por menor distancia y nos quedamos con los 10 primeros. + distancias = sorted(distancias, key=lambda d: d[1])[:10] + + distancias = dict(distancias) + + # Devolvemos los 10 descriptores más cercanos. + return distancias + +# ============================================================================= +# Funcion que calcula los descriptores dada una palabra +# ============================================================================= +def descriptoresPalabra(i_palabra,descriptores,etiquetas): + # Obtenemos los índices de los descriptores. + i_desc = [index for index in range(len(etiquetas)) if etiquetas[index] == i_palabra] + + # Guardamos el subconjunto en un diccionario. + descriptoresPalabra = dict([index, descriptores[index]] for index in i_desc) + + # Devolvemos el subconjunto. + return descriptoresPalabra + +# ============================================================================= +# Funcion que calcula los parches mas cercanos dada una palabra visual +# ============================================================================= +def calcularMejoresParches(i_palabra,vocabulario,descriptores,etiquetas,parches): + # calculamos los parches de la palabra. + descriptores_sub = descriptoresPalabra(i_palabra, descriptores, etiquetas) + mejores_desc = descriptoresCercanos(descriptores_sub, vocabulario[i_palabra]) + mejores = dict([[ID,parches[ID]] for ID in mejores_desc.keys()]) + + # devolvemos los parches + return mejores + +def mismaEscena(imgs,m_invertido,diccionario,bolsaImagenes): + bolsa = dict([fich,bolsaImagenes[fich]] for fich in imgs ) + + bolsaImg1 = bolsa.get(imgs[0]) + + sim = [ (( np.dot(bolsaImg1,bimg.T) ) / (norm(bolsaImg1)*norm(bimg)))*255 for name,bimg in bolsa.items()] + + sim = np.array(sim,dtype=np.uint8).reshape((1,5)) + + return sim + +############################################################################### +############################################################################### +############################################################################### +############################################################################### + +# ============================================================================= +# 1. Emparejamiento de descriptores [4 puntos] +# - Mirar las imágenes en imagenesIR.rar y elegir parejas de imágenes +# que tengan partes de escena comunes. Haciendo uso de una máscara +# binaria o de las funciones extractRegion() y clickAndDraw(), se- +# leccionar una región en la primera imagen que esté presente en la se- +# gunda imagen. Para ello solo hay que fijar los vértices de un polıgono +# que contenga a la región. +# - Extraiga los puntos SIFT contenidos en la región seleccionada de la +# primera imagen y calcule las correspondencias con todos los puntos +# SIFT de la segunda imagen (ayuda: use el concepto de máscara con +# el parámetro mask). +# - Pinte las correspondencias encontrados sobre las imágenes. +# - Jugar con distintas parejas de imágenes, valorar las correspondencias +# correctas obtenidas y extraer conclusiones respecto a la utilidad de +# esta aproximación de recuperación de regiones/objetos de interés a +# partir de descriptores de una región. +# ============================================================================= + +# ============================================================================= +# EJEMPLO 1 - img95 - img116 +# ============================================================================= + +# Leo las dos imágenes seleccionadas. +img1 = leeimagen('95.png',1); +img2 = leeimagen('116.png',1); + +#Obtenemos los vertices correspondientes a una zona de la imagen1 +#vertices = extractRegion(img1); +vertices = [(335, 53), (414, 52), (412, 154), (326, 144), (335, 53)] + +#Creamos la máscara +mask = crearMascara(img1,vertices) + +#Muestro la máscara +multIM([mask],1,1,10,10,False) +input() + +#Creamos las correspondencias y mostramos el resultado +res = calcularCorrespondencias(img1,img2,mask) + +multIM([res],1,1,15,15) + +input() + +# ============================================================================= +# EJEMPLO 2 - img130 - img128 +# ============================================================================= + +# Leo las dos imágenes seleccionadas. +img1 = leeimagen('130.png',1); +img2 = leeimagen('128.png',1); + +#Obtenemos los vertices correspondientes a una zona de la imagen1 +#vertices = extractRegion(img1); +vertices = [(230, 240), + (234, 413), + (356, 452), + (497, 366), + (489, 220), + (386, 198), + (230, 240)] + +#Creamos la máscara +mask = crearMascara(img1,vertices) + +#Muestro la máscara +multIM([mask],1,1,10,10,False) +input() + +#Creamos las correspondencias y mostramos el resultado +res = calcularCorrespondencias(img1,img2,mask) + +multIM([res],1,1,15,15) + +input() + +# ============================================================================= +# EJEMPLO 3 - img234 - img248 +# ============================================================================= + +# Leo las dos imágenes seleccionadas. +img1 = leeimagen('234.png',1); +img2 = leeimagen('248.png',1); + +#Obtenemos los vertices correspondientes a una zona de la imagen1 +#vertices = extractRegion(img1); +vertices = [(165, 67), (209, 61), (220, 158), (166, 157), (165, 67)] + +#Creamos la máscara +mask = crearMascara(img1,vertices) + +#Muestro la máscara +multIM([mask],1,1,10,10,False) +input() + +#Creamos las correspondencias y mostramos el resultado +res = calcularCorrespondencias(img1,img2,mask) + +multIM([res],1,1,15,15) + +input() + +# ============================================================================= +# 2. Recuperación de imágenes [4 puntos] +# - Implementar un modelo de ındice invertido + bolsa de palabras para +# las imágenes dadas en imagenesIR.rar usando el vocabulario dado +# en kmeanscenters2000.pkl. +# - Verificar que el modelo construido para cada imagen permite recu- +# perar imágenes de la misma escena cuando la comparamos al resto +# de imágenes de la base de datos. +# - Elegir dos imágenes-pregunta en las se ponga de manifiesto que el +# modelo usado es realmente muy efectivo para extraer sus semejantes y +# elegir otra imagen-pregunta en la que se muestre que el modelo puede +# realmente fallar. Para ello muestre las cinco imágenes más semejantes +# de cada una de las imágenes-pregunta seleccionadas usando como +# medida de distancia el producto escalar normalizado de sus vectores +# de bolsa de palabras. +# - Explicar qué conclusiones obtiene de este experimento. +# ============================================================================= + + +#Cargamos el diccionario +accu, etiquetas, vocabulario = loadDictionary("kmeanscenters2000.pkl") + +#Creamos el modelo de indice invertido + bolsa de palabras +modeloInvertido, bolsa = crearIndicesInvertidos(vocabulario) + +# ============================================================================= +# VERIFICAR MISMA ESCENA +# ============================================================================= + +imgs = ['106.png','107.png','108.png','109.png','25.png'] + +escena = mismaEscena(imgs,modeloInvertido,vocabulario,bolsa) + +multIM([escena],1,1,15,15,False) + +input() + +# ============================================================================= +# EJEMPLO 1 - img425 +# ============================================================================= +#Leo la imagen +img1 = leeimagen('425.png',1) + +#Calculamos las imagenes similares a la imagen cargada anteriormente utilizando +#el diccionario anterior. +similar = calcularImagenesSimilares(img1,modeloInvertido,vocabulario,bolsa) + +#Preparo la visualizacion +imgs = [leeimagen(fich,1) for fich,sim in similar.items()] + +#Muestro el resultado +multIM(imgs,3,3,15,15) + +input() + +# ============================================================================= +# EJEMPLO 2 - img104 +# ============================================================================= +#Leo la imagen +img1 = leeimagen('104.png',1) + +#Calculamos las imagenes similares a la imagen cargada anteriormente utilizando +#el diccionario anterior. +similar = calcularImagenesSimilares(img1,modeloInvertido,vocabulario,bolsa) + +#Preparo la visualizacion +imgs = [leeimagen(fich,1) for fich,sim in similar.items()] + +#Muestro el resultado +multIM(imgs,3,3,15,15) + +input() + +# ============================================================================= +# EJEMPLO 3 - img62 +# ============================================================================= +#Leo la imagen +img1 = leeimagen('62.png',1) + +#Calculamos las imagenes similares a la imagen cargada anteriormente utilizando +#el diccionario anterior. +similar = calcularImagenesSimilares(img1,modeloInvertido,vocabulario,bolsa) + +#Preparo la visualizacion +imgs = [leeimagen(fich,1) for fich,sim in similar.items()] + +#Muestro el resultado +multIM(imgs,3,3,15,15) + +input() + + +# ============================================================================= +# 3. Visualización del vocabulario [3 puntos] +# - Usando las imágenes dadas en imagenesIR.rar se han extraido 600 +# regiones de cada imagen de forma directa y se han re-escalado en +# parches de 24x24 pıxeles. A partir de ellas se ha construido un vocab- +# ulario de 2.000 palabras usando k-means. Los ficheros con los datos +# son descriptorsAndpatches2000.pkl (descriptores de las regiones +# y los parches extraıdos) y kmeanscenters2000.pkl (vocabulario ex- +# traıdo). +# - Elegir al menos dos palabras visuales diferentes y visualizar las re- +# giones imagen de los 10 parches más cercanos de cada palabra visual, +# de forma que se muestre el contenido visual que codifican (mejor en +# niveles de gris). +# - Explicar si lo que se ha obtenido es realmente lo esperado en términos +# de cercanı́a visual de los parches. +# ============================================================================= + + +# ============================================================================= +# EJEMPLO 1 - PALABRA 4 +# ============================================================================= +#Cargamos el fichero de parches y descriptores +desc, patch = loadAux('descriptorsAndpatches2000.pkl',flagPatches=True) + +#Calculamos los mejores parches para una imagen visual determinada +mejores_parches = calcularMejoresParches(4,vocabulario,desc,etiquetas,patch) + +#Preparo la visualizacion (en grises porque lo especifica el enunciado) +imgs = [cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) for ID,img in mejores_parches.items()] + +#Muestro el resultado +multIM(imgs,5,5,15,15,False) + +input() + +# ============================================================================= +# EJEMPLO 2 - PALABRA 18 +# ============================================================================= +#Cargamos el fichero de parches y descriptores +mejores_parches = calcularMejoresParches(18,vocabulario,desc,etiquetas,patch) + +#Preparo la visualizacion (en grises porque lo especifica el enunciado) +imgs = [cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) for ID,img in mejores_parches.items()] + +#Muestro el resultado +multIM(imgs,5,5,15,15,False) + +input() + +# ============================================================================= +# EJEMPLO 2 - PALABRA 21 +# ============================================================================= +#Cargamos el fichero de parches y descriptores +mejores_parches = calcularMejoresParches(21,vocabulario,desc,etiquetas,patch) + +#Preparo la visualizacion (en grises porque lo especifica el enunciado) +imgs = [cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) for ID,img in mejores_parches.items()] + +#Muestro el resultado +multIM(imgs,5,5,15,15,False) + +input() + diff --git a/PRACTICAS/Practica 3/auxFunc.py b/PRACTICAS/Practica 3/auxFunc.py new file mode 100644 index 0000000..fbe903a --- /dev/null +++ b/PRACTICAS/Practica 3/auxFunc.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Oct 24 11:27:33 2017 + +@author: Nicolás Pérez de la Blanca + """ +import cv2 +import pickle +import numpy as np +#from matplotlib import pyplot as plt + +def click_and_draw(event,x,y,flags,param): + global refPt, imagen,FlagEND + + + # if the left mouse button was clicked, record the starting + # (x, y) coordinates and indicate that cropping is being + # performed + if event == cv2.EVENT_LBUTTONDBLCLK: + FlagEND= False + cv2.destroyWindow("image") + + elif event == cv2.EVENT_LBUTTONDOWN: + refPt.append((x, y)) + #cropping = True + print("rfePt[0]",refPt[0]) + + + elif (event == cv2.EVENT_MOUSEMOVE) & (len(refPt) > 0) & FlagEND: + # check to see if the mouse move + clone=imagen.copy() + nPt=(x,y) + print("npt",nPt) + sz=len(refPt) + cv2.line(clone,refPt[sz-1],nPt,(0, 255, 0), 2) + cv2.imshow("image", clone) + cv2.waitKey(0) + + elif event == cv2.EVENT_RBUTTONDOWN: + # record the ending (x, y) coordinates and indicate that + # the cropping operation is finished + refPt.append((x, y)) + #cropping = False + sz=len(refPt) + print("refPt[sz]",sz,refPt[sz-1]) + cv2.line(imagen,refPt[sz-2],refPt[sz-1],(0, 255, 0), 2) + cv2.imshow("image", imagen) + cv2.waitKey(0) + + +def extractRegion(image): + global refPt, imagen,FlagEND + imagen=image.copy() + # load the image and setup the mouse callback function + refPt=[] + FlagEND=True + #image = cv2.imread(filename) + cv2.namedWindow("image") + # keep looping until the 'q' key is pressed + cv2.setMouseCallback("image", click_and_draw) + # + while FlagEND: + # display the image and wait for a keypress + cv2.imshow("image", image) + cv2.waitKey(0) + # + print('FlagEND', FlagEND) + refPt.pop() + refPt.append(refPt[0]) + cv2.destroyWindow("image") + return refPt + + +def loadDictionary(filename): + with open(filename,"rb") as fd: + feat=pickle.load(fd) + return feat["accuracy"],feat["labels"], feat["dictionary"] + +def loadAux(filename, flagPatches): + if flagPatches: + with open(filename,"rb") as fd: + feat=pickle.load(fd) + return feat["descriptors"],feat["patches"] + else: + with open(filename,"rb") as fd: + feat=pickle.load(fd) + return feat["descriptors"] + + diff --git a/TEORIA/Cuestionario 1.pdf b/TEORIA/Cuestionario 1.pdf new file mode 100644 index 0000000..1795bb7 Binary files /dev/null and b/TEORIA/Cuestionario 1.pdf differ diff --git a/TEORIA/Cuestionario 2.pdf b/TEORIA/Cuestionario 2.pdf new file mode 100644 index 0000000..85197e3 Binary files /dev/null and b/TEORIA/Cuestionario 2.pdf differ diff --git a/TEORIA/Cuestionario 3.pdf b/TEORIA/Cuestionario 3.pdf new file mode 100644 index 0000000..3bd12e1 Binary files /dev/null and b/TEORIA/Cuestionario 3.pdf differ