import cv2

import numpy as np
from matplotlib import pyplot as plt

import cv2.cv as cv
import glob
from PIL import Image

import kmean 
import skinDetect as skinner
import math


# Obtencio del vector de Roba de la imatge
def getClothes(imgPath, coords, por = 0.10, skin = True, invert = True, aviso = False):
    img, mask = skinner.skinImgClothesTors(imgPath, coords, por = por, zone = 'nas-galtes', skinner = skin, invert = invert, aviso = aviso)
    
    return getDescriptRoba(img, None, skin = skin, aviso = aviso)


def comprareClustersClothes(images,cascade,por = 0.10, skin=True, aviso=False):
    for i in range(1, len(images)):
        for j in range(0, i):
            img1, mask1 = skinner.skinImgDectTors(images[i], cascade, skinner=skin)
            img2, mask2 = skinner.skinImgDectTors(images[j], cascade, skinner=skin)
                
            if img1 is not None and img2 is not None:
                
                print 'Comparant Imatge ' + images[i] + ' amb ' + images[j]
                
                k_img1 = kmean.elbow(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY),aviso=False)
                kmean_img1 = kmean.Kmeans(k = k_img1)
                kmean_img1.run(image = img1)
                centrosImg1 = kmean_img1.valuesClustersCentroid()
                valoresImg1 = sorted([pixelBGR2GRAY(pixel) for pixel in centrosImg1])


                k_img2 = kmean.elbow(cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY),aviso=False)
                kmean_img2 = kmean.Kmeans(k = k_img2)
                kmean_img2.run(image = img2)
                centrosImg2 = kmean_img2.valuesClustersCentroid()
                valoresImg2 = sorted([pixelBGR2GRAY(pixel) for pixel in centrosImg2])
                
                
                print 'Es la misma Ropa: '+ str(isEqualClothes(valoresImg1,valoresImg2))
                
                if aviso:
                    #Mostrar el resultat
                    cv2.namedWindow("Image 1")
                    cv2.imshow("Image 1", img1)

                    cv2.namedWindow("Image 2")
                    cv2.imshow("Image 2", img2)

                    cv2.waitKey()
                    cv2.destroyAllWindows()


def compareDescriptorClothes(images,cascade,limite=0.20,skin=False, aviso=False):
    for i in range(1, len(images)):
        for j in range(0, i):
            img1,mask1 = skinner.skinImgDectTors(images[i], cascade, skinner=skin, aviso=False)
            img2,mask2 = skinner.skinImgDectTors(images[j], cascade, skinner=skin, aviso=False)
            
            if img1 is not None and img2 is not None:
                
                print 'Comparant Imatge ' + images[i] + ' amb ' + images[j]
                
                print 'Es la misma Ropa: '+ str(isRobaIgual(img1,img2,mask1,mask2,skin=skin,aviso=aviso))
                
                if aviso:
                    #Mostrar el resultat
                    cv2.namedWindow("Image 1")
                    cv2.imshow("Image 1", img1)

                    cv2.namedWindow("Image 2")
                    cv2.imshow("Image 2", img2)

                    cv2.waitKey()
                    cv2.destroyAllWindows()


def getDescriptRoba(image, mask, skin = False, aviso = False):
    img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    h,s,v = cv2.split(img)
    
    vecH = extractDescriptorChannel(h, mask = mask)
    vecS = extractDescriptorChannel(s, mask = mask)
    vecV = extractDescriptorChannel(v, mask = mask)
    
    #return np.concatenate((vecH,vecS, vecV), axis=1)
    return [vecH, vecS, vecV]
    

# Comparativa utilitzan distancia Bhattacharyya
def isRobaIgual(image1,image2,mask1,mask2, limit = 0.20, skin=False, aviso=False):
    img1 = cv2.cvtColor(image1, cv2.COLOR_BGR2HSV)
    img2 = cv2.cvtColor(image2, cv2.COLOR_BGR2HSV)
    h1,s1,v1 = cv2.split(img1)
    h2,s2,v2 = cv2.split(img2)
    
    vecH1 = extractDescriptorChannel(h1, mask=mask1)
    vecS1 = extractDescriptorChannel(s1, mask=mask1)
    vecV1 = extractDescriptorChannel(v1, mask=mask1)
    vecH2 = extractDescriptorChannel(h2, mask=mask2)
    vecS2 = extractDescriptorChannel(s2, mask=mask2)
    vecV2 = extractDescriptorChannel(v2, mask=mask2)
    
    hista = np.concatenate((vecH1,vecV1), axis=1)
    histb = np.concatenate((vecH2,vecV2), axis=1)
    
    if bhattacharyya(hista,histb) < limit:
        return True
    else:
        return False


# Comprova si les robes son iguals
def isEqualClothes(img1,img2, diff = 10):
    values = [img1,img2]
    ns = [len(img1),len(img2)]
    m, n, cont = min(ns), max(ns), 0
    print str(img1)
    print str(img2)
    for v1 in values[0]:
        i=0
        while i < len(values[1]):
            #print 'Compara ' +str(v1) +' i '+str(values[1][i]) + ' dif ' +str(abs(v1-values[1][i])) 
            if abs(v1-values[1][i]) < diff:
                #print 'suma cont ' +str(cont)
                cont += 1
                break
            i +=1
            
    if cont >= m:
        return True
        
    return False

def pixelBGR2GRAY(pixel):
    if len(pixel) > 0:
        
        return sum(pixel)/len(pixel)
    
    return 0

def diffImage(img1,img2):
    new_img1, new_img2 = equalImgs(img1,img2)
    
    return cv2.absdiff(new_img1,new_img2)

def averageColor(img):
    image = Image.fromarray(img)
    color = [None,None,None]
    for canal in range(3):
        pixels = image.getdata(band=canal)
        
        valors = [pixel for pixel in pixels]
        color[canal] = sum(valors)/float(len(valors))
    
    return color

def mostColor(image):
    image = Image.fromarray(image)
    w,h = image.size
    pixels = image.getcolors(w*h)
    
    freqColor = pixels[0]
    for count , color in pixels:
        if count > freqColor[0]:
            freqColor = (count,color)
            
    return freqColor

def getPaleta(image):
    image = Image.fromarray(image)
    
    return image.getcolors()
    
# compara la distancia entre dos vectors  [Ja ficat en un altre modul] <<<<<<<<--------------OJO
def compareVectors(vec1,vec2):
    d = vec1 - vec2
    return np.dot(d,d)

# Ja esta en uyn altre modul <<<<<<<----------------- OJO
def pearson(x, y):
    assert len(x) == len(y)
    n = len(x)
    assert n > 0
    avg_x = float(sum(x))/len(x)
    avg_y = float(sum(y))/len(y)
    diffprod = 0
    xdiff2 = 0
    ydiff2 = 0
    for idx in range(n):
        xdiff = x[idx] - avg_x
        ydiff = y[idx] - avg_y
        diffprod += xdiff * ydiff
        xdiff2 += xdiff * xdiff
        ydiff2 += ydiff * ydiff

    return diffprod / float(math.sqrt(xdiff2 * ydiff2))


def chiDis(x,y):
    out = None
    nx = len(x) 
    ny = len(y)
    
    if (nx > 0) and (ny > 0) and (nx == ny):
        out = (sum([((x[i]-y[i])**2)/float(x[i]+y[i]) for i in range(0,nx) if x[i]!= 0 and y[i]!= 0]))/2
        
    return out

#Distancia de Bhattacharyya
def bhattacharyya(h1, h2):
    '''Calculates the Byattacharyya distance of two histograms.'''
    return 1 - np.sum(np.sqrt(np.multiply(normalize(h1), normalize(h2))))

def normalize(h):
    return h / np.sum(h)


def extractDescriptorChannel(image, channel = 0, mask = None, size = 256):
    #img = cv2.imread('lena.jpg')
    #cv2.imshow('Face', image)
    
    out = []
    if len(image.shape) > 2:
        if channel < image.shape[2]:
            out.extend(cv2.calcHist(images = [image], channels = [channel], mask = mask, histSize = [size], ranges = [0, size]))
    else:
        if channel == 0:
            out.extend(cv2.calcHist(images = [image], channels = [0], mask = mask, histSize = [size], ranges = [0, size]))

    return out
    
def histogramaGray(image, title='', aviso=True, wait=False, mask=None):
    cv2.imshow('Captura', image)
    hist = cv2.calcHist([image], [0], mask, [256], [0, 256])
    plt.plot(hist, color='gray' )

    plt.xlabel('intensidad de iluminacion')
    plt.ylabel('cantidad de pixeles')
    
    if aviso:
        plt.title(title)
        plt.show()
    if wait:
        cv2.waitKey()
        cv2.destroyAllWindows()
    
def histogramaColor(image, aviso=True, wait=False,title='',mask=None):
    #img = cv2.imread('lena.jpg')
    cv2.imshow('Face', image)

    color = ('b','g','r')

    for i, c in enumerate(color):
        hist = cv2.calcHist([image], [i], mask, [256], [0, 256])
        plt.plot(hist, color = c)
        plt.xlim([0,256])
    
    if aviso:
        plt.title(title)
        plt.show()
    if wait:
        cv2.waitKey()
        cv2.destroyAllWindows()
        


def grafica(x,Y, etiquetes = None, title='', color = ('r','g','b','c','m','y','k'),tipo = ('-','--','-.',':')):
    i,c,t = 0,0,0
    etiqueta = ''
    plt.figure()
    
    for y in Y:
        if etiquetes is not None:
            etiqueta = etiquetes[i]
        plt.plot(x,y,color[c]+tipo[t],label=etiqueta)
        i +=1
        c += 1
        if c > len(color):
            i = 0
            t +=1
            if t > len(tipo):
                t = 0
                
    if etiquetes is not None:
        plt.legend(loc=1)
    
    plt.title(title)
    plt.show()
    

def mainImagesKmean(inputDir):  
    # if a video path was not supplied, grab the reference
    #camera = cv2.VideoCapture(0)
    exts=['*.jpg','*.jpeg','*.png']
    images = []
    
    # read list of images
    for ext in exts:    
        images.extend(glob.glob(inputDir+'/'+ext))
        
    cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_frontalface_alt2.xml")
        
    comprareClustersClothes(images,cascade, aviso = True)
    
    
def mainImages(inputDir):  
    # if a video path was not supplied, grab the reference
    #camera = cv2.VideoCapture(0)
    exts=['*.jpg','*.jpeg','*.png']
    images = []
    
    # read list of images
    for ext in exts:    
        images.extend(glob.glob(inputDir+'/'+ext))
        
    cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_frontalface_alt2.xml")
        
    compareDescriptorClothes(images,cascade, aviso = True)
    
#mainImages('./fotos/ret')
