import cv2
#from pyimagesearch import imutils
import numpy as np
from matplotlib import pyplot as plt

import cv2.cv as cv
import glob
from PIL import Image
#from video import create_capture
#from common import clock, draw_str

import kmean

def resize(img,w,h,size=96):
    rows,cols = img.shape[:2]
    
    pts1 = np.float32([[0,0],[w,0],[0,h],[w,h]])
    pts2 = np.float32([[0,0],[size,0],[0,size],[size,size]])
     
    M = cv2.getPerspectiveTransform(pts1,pts2)
     
    return cv2.warpPerspective(img,M,(size,size)) #devuelve la imagen con la dimension deseada

def skinDetect(image,lower,upper):
    frame = cv2.imread(image,0)
    
    # Para redimensionar
    r = 400.0 / frame.shape[1]
    dim = (400, int(frame.shape[0] * r))
    
    # perform the actual resizing of the image and show it
    #frame = cv2.resize(frame, dim, interpolation = cv2.INTER_AREA)

    # resize the frame, convert it to the HSV color space,
    # and determine the HSV pixel intensities that fall into
    # the speicifed upper and lower boundaries
    #frame = imutils.resize(frame, width = 400)
    converted = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    skinMask = cv2.inRange(converted, lower, upper)
    
    # apply a series of erosions and dilations to the mask
    # using an elliptical kernel
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11))
    skinMask = cv2.erode(skinMask, kernel, iterations = 2)
    skinMask = cv2.dilate(skinMask, kernel, iterations = 2)
    
    # blur the mask to help remove noise, then apply the
    # mask to the frame
    skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0)
    skin = cv2.bitwise_and(frame, frame, mask = skinMask)
    
    # show the skin in the image along with the mask
    cv2.imshow("images", np.hstack([frame, skin])) 
    
    cv2.waitKey()
    cv2.destroyAllWindows()

def skinImagesDect(images,cascade,ref,por = 0.10):
    #Imatge de referencia
    frame = cv2.imread(ref)
    mostra = frame
    
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.equalizeHist(gray)
    
    lower = np.array([0], dtype = "uint8")
    upper = np.array([0], dtype = "uint8")
    
    #Para detectar la cara
    rects = detect(gray, cascade)
    vis = frame.copy()
    draw_rects(vis, rects, (0, 255, 0))       
    for x1, y1, x2, y2 in rects:
        dx = int((x2-x1)*por)
        dy = int((y2-y1)*por)
        px = int((x2-x1)/2)
        py = int((y2-y1)/2)
        
        #Torso
        yi2 = int(y2+((y2-y1)*1.6))
        yi1 = y2 + (dy*3)
        
        xi1 = x1 - int((x2-x1)/2)
        xi2 = x2 + int((x2-x1)/2)
        
        if yi1 > vis.shape[0]:
            yi1 = vis.shape[0]
        if yi2 > vis.shape[0]:
            yi2 = vis.shape[0]
            
        if xi1 < 0:
            xi1 = 0
        if xi2 > vis.shape[1]:
            xi2 = vis.shape[1]

        roi = frame[y1+py-int(dy):y1+py+int(dy), x1+px-dx:x1+px+int(dx)]
        
        minimos, maximos, medios = valueSkins(roi)
        #lower = np.array([x for x in minimos], dtype = "uint8")
        #upper = np.array([x for x in maximos], dtype = "uint8")
        
    converted = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    skinMask = cv2.inRange(converted, lower, upper)
    
    inverSkinMask = np.copy(skinMask)
    
    inverSkinMask[inverSkinMask == 0] += 1
    inverSkinMask[inverSkinMask == 255] = 0
    inverSkinMask[inverSkinMask == 1] = 255

    # apply a series of erosions and dilations to the mask
    # using an elliptical kernel
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 1))
    skinMask = cv2.erode(skinMask, kernel, iterations = 2)
    skinMask = cv2.dilate(skinMask, kernel, iterations = 2)

    # blur the mask to help remove noise, then apply the
    # mask to the frame
    skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0)
    skin = cv2.bitwise_and(frame, frame, mask = inverSkinMask)
    #skin = cv2.bitwise_and(frame, frame, mask = skinMask)
    
    #retall del torso
    torsoRef = skin[yi1:yi2,xi1:xi2]
          
    for image in images:
        
        frame = cv2.imread(image)
        
        # define the upper and lower boundaries of the HSV pixel
        # intensities to be considered 'skin'
        #lower = np.array([0, 48, 80], dtype = "uint8")
        #upper = np.array([20, 255, 255], dtype = "uint8")
        lower = np.array([0], dtype = "uint8")
        upper = np.array([0], dtype = "uint8")
        
        # grab the current frame
        #(grabbed, frame) = camera.read()
        
        #gray = frame
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        gray = cv2.equalizeHist(gray)
        
        #Para detectar la cara
        rects = detect(gray, cascade)
        vis = frame.copy()
        draw_rects(vis, rects, (0, 255, 0))       
        for x1, y1, x2, y2 in rects:
            dx = int((x2-x1)*por)
            dy = int((y2-y1)*por)
            px = int((x2-x1)/2)
            py = int((y2-y1)/2)
            
            #Torso
            yi2 = int(y2+((y2-y1)*1.6))
            yi1 = y2 + (dy*3)
            
            xi1 = x1 - int((x2-x1)/2)
            xi2 = x2 + int((x2-x1)/2)
            
            if yi1 > vis.shape[0]:
                yi1 = vis.shape[0]
            if yi2 > vis.shape[0]:
                yi2 = vis.shape[0]
                
            if xi1 < 0:
                xi1 = 0
            if xi2 > vis.shape[1]:
                xi2 = vis.shape[1]
            
            draw_rect(vis, xi1 , xi2, yi1, yi2 ,(255,0,0))            
            
            # requadre de la frent amb un por = 0.30
            #draw_rect(vis, x1+int(dx), x2-int(dx), y1+int(dy/8), y1+int(dy*0.65) ,(0,0,255))
            #roi = frame[y1+int(dy/8):y1+int(dy*0.65), x1+int(dx):x2-int(dx)]            
            
            #requadre del nas -> bon resultat amb por = 0.10
            draw_rect(vis, x1+px-dx, x1+px+int(dx), y1+py-int(dy), y1+py+int(dy) ,(0,0,255))
            roi = frame[y1+py-int(dy):y1+py+int(dy), x1+px-dx:x1+px+int(dx)]
            
            minimos, maximos, medios = valueSkins(roi)
            #lower = np.array([x for x in minimos], dtype = "uint8")
            #upper = np.array([x for x in maximos], dtype = "uint8")
        
        
        # Para redimensionar
        r = 400.0 / frame.shape[1]
        dim = (400, int(frame.shape[0] * r))
        
        # perform the actual resizing of the image and show it
        #frame = cv2.resize(frame, dim, interpolation = cv2.INTER_AREA)
    
        # resize the frame, convert it to the HSV color space,
        # and determine the HSV pixel intensities that fall into
        # the speicifed upper and lower boundaries
        #frame = imutils.resize(frame, width = 400)
        converted = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        skinMask = cv2.inRange(converted, lower, upper)
        
        inverSkinMask = np.copy(skinMask)
        
        inverSkinMask[inverSkinMask == 0] += 1
        inverSkinMask[inverSkinMask == 255] = 0
        inverSkinMask[inverSkinMask == 1] = 255
    
        # apply a series of erosions and dilations to the mask
        # using an elliptical kernel
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 1))
        skinMask = cv2.erode(skinMask, kernel, iterations = 2)
        skinMask = cv2.dilate(skinMask, kernel, iterations = 2)
    
        # blur the mask to help remove noise, then apply the
        # mask to the frame
        skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0)
        skin = cv2.bitwise_and(frame, frame, mask = inverSkinMask)
        #skin = cv2.bitwise_and(frame, frame, mask = skinMask)
        
        #retall del torso
        torso = skin[yi1:yi2,xi1:xi2]
        
        cv2.imshow('Torso', torso)
        cv2.imshow('TorsoRef', torsoRef)
        
        imageRef,imageAct = equalImgs(torsoRef,torso)
        
        print 'Referencia '
        k_ref = kmean.elbow(cv2.cvtColor(torsoRef, cv2.COLOR_BGR2GRAY))
        
        ref = kmean.Kmeans(k = k_ref)
        ref.run(image = torsoRef)
        
        centrosRef = ref.valuesClustersCentroid()
        valoresRef = sorted([pixelBGR2GRAY(pixel) for pixel in centrosRef])
        
        print 'Mostrar Grises'
        print str(valoresRef) 
        
        #ref.showImage()
        #ref.showClustering()
        
        print 'Actual '
        k_act = kmean.elbow(cv2.cvtColor(torso, cv2.COLOR_BGR2GRAY))
        
        act = kmean.Kmeans(k = k_act)
        act.run(image = torso)
        
        centrosAct = act.valuesClustersCentroid()
        valoresAct = sorted([pixelBGR2GRAY(pixel) for pixel in centrosAct])
        
        print 'Mostrar Grises'
        print str(valoresAct)
        
        print 'Misma Ropa: '+ str(isEqualClothes(valoresAct,valoresRef))
        
        #act.showImage()
        #act.showClustering()
        
        #col = mostColor(imageAct)
        #col_ref = mostColor(imageRef)
        #print 'Referencia sobre los colores'
        #print 'Referencia ' + str(col_ref)
        #print 'Valor actual ' + str(col)

        # show the skin in the image along with the mask
        #cv2.imshow("images", np.hstack([frame, skin]))
        
        #Per mostrear tret per probar kmean
        cv2.imshow("images", np.hstack([vis, skin]))
        
        #cv2.imshow('Mostra', mostra)
    
        # if the 'q' key is pressed, stop the loop
        cv2.waitKey()
        cv2.destroyAllWindows()
    # cleanup the camera and close any open windows

    cv2.destroyAllWindows()

def skinImgClothesTors(img, coords, por = 0.10, zone='nas', skinner=True, invert=True, aviso=False):
    if not zone in ('nas','front','nas-galtes'):
        return None, None
    
    frame = cv2.imread(img)
    tors = False
    
    #Valors per defecte al no tenir pell reconeguda
    lower = np.array([0], dtype = "uint8")
    upper = np.array([0], dtype = "uint8")
    
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.equalizeHist(gray)
    
    vis = frame.copy()    
    x1, y1, x2, y2 = coords
    
    dx = int((x2-x1)*por)
    dy = int((y2-y1)*por)
    px = int((x2-x1)/2)
    py = int((y2-y1)/2)
    
    #Obtenir valors del Torso
    tors = True
    yi2 = int(y2+((y2-y1)*1.6))
    yi1 = y2 + (dy*3)
    
    xi1 = x1 - int((x2-x1)/2)
    xi2 = x2 + int((x2-x1)/2)
    
    #Regular valors segons la grandaria de la imatge
    if yi1 > vis.shape[0]:
        yi1 = vis.shape[0]
    if yi2 > vis.shape[0]:
        yi2 = vis.shape[0]
        
    if xi1 < 0:
        xi1 = 0
    if xi2 > vis.shape[1]:
        xi2 = vis.shape[1]
        
    #Mostrar Requadre del Torso
    draw_rect(vis, xi1 , xi2, yi1, yi2 ,(255,0,0)) 
    
    # requadre de la frent amb un por = 0.30
    if zone == 'front':
        draw_rect(vis, x1+px-int(dx), x1+px+int(dx), y1+int(dy), y1+int(dy*2) ,(0,0,255))
        roi = frame[y1+int(dy):y1+int(dy*2), x1+px-int(dx):x1+px+int(dx)]            
    
    
    #requadre del nas -> bon resultat amb por = 0.10
    if zone == 'nas':
        draw_rect(vis, x1+px-int(dx*0.80), x1+px+int(dx*0.80), y1+py-int(dy), y1+py+int(dy*0.60) ,(0,0,255))
        roi = frame[y1+py-int(dy):y1+py+int(dy*0.60), x1+px-int(dx*0.80):x1+px+int(dx*0.80)]
        
    if zone == 'nas-galtes':
        #Nas
        draw_rect(vis, x1+px-int(dx*0.80), x1+px+int(dx*0.80), y1+py-int(dy), y1+py+int(dy*0.60) ,(0,0,255))
        roi1 = frame[y1+py-int(dy):y1+py+int(dy*0.60), x1+px-int(dx*0.80):x1+px+int(dx*0.80)]
        #Galta dreta
        draw_rect(vis, x1+px+int(dx*1.5), x1+px+int(dx*2.5), y1+py+int(dy*0.20), y1+py+int(dy*1.5) ,(0,0,255))
        roi2 = frame[y1+py+int(dy*0.20):y1+py+int(dy*1.5), x1+px+int(dx*1.5):x1+px+int(dx*2.5)]
        #Galta esquerra
        draw_rect(vis, x1+px-int(dx*2.5), x1+px-int(dx*1.5), y1+py+int(dy*0.20), y1+py+int(dy*1.5) ,(0,0,255))
        roi3 = frame[y1+py+int(dy*0.20):y1+py+int(dy*1.5), x1+px-int(dx*2.5):x1+px-int(dx*1.5)]
    
        roi = np.concatenate((roi1.reshape(1,roi1.shape[1]*roi1.shape[0],roi1.shape[2]),roi2.reshape(1,roi2.shape[1]*roi2.shape[0],roi2.shape[2]),roi3.reshape(1,roi3.shape[1]*roi3.shape[0],roi3.shape[2])), axis=1)
        
    minimos, maximos, medios = valueSkins(roi)
    lower = np.array([0, minimos[1], minimos[2]], dtype = "uint8")
    upper = np.array([255,maximos[1],maximos[2]], dtype = "uint8")
        
    
    converted = cv2.cvtColor(frame, cv2.COLOR_BGR2YCR_CB)
    skinMask = cv2.inRange(converted, lower, upper)
    
    #Invertir la mascara
    inverSkinMask = np.copy(skinMask)
    if invert:
        inverSkinMask[inverSkinMask == 0] += 1
        inverSkinMask[inverSkinMask == 255] = 0
        inverSkinMask[inverSkinMask == 1] = 255

    # apply a series of erosions and dilations to the mask
    # using an elliptical kernel
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 1))
    skinMask = cv2.erode(skinMask, kernel, iterations = 2)
    skinMask = cv2.dilate(skinMask, kernel, iterations = 2)

    # blur the mask to help remove noise, then apply the
    # mask to the frame
    skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0)
    skin = cv2.bitwise_and(frame, frame, mask = inverSkinMask)
    
    if aviso:
        #Mostrar el resultat
        cv2.imshow("images", np.hstack([vis, skin]))
        cv2.waitKey()
        cv2.destroyAllWindows()
    
    if skinner:
        result = skin
        maskara = inverSkinMask[yi1:yi2,xi1:xi2]
    else:
        result = vis
        maskara = None
    
    if tors:
        return result[yi1:yi2,xi1:xi2], maskara
    else:
        return None, None


    
def skinImgDectTors(img, cascade, por=0.10, zone='nas', skinner=True, invert=True, aviso=False):
    if not zone in ('nas','front','nas-galtes'):
        return None
    
    frame = cv2.imread(img)
    tors = False
    
    #Valors per defecte al no tenir pell reconeguda
    lower = np.array([0], dtype = "uint8")
    upper = np.array([0], dtype = "uint8")
    
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.equalizeHist(gray)
    
    #Para detectar la cara
    rects = detect(gray, cascade)
    vis = frame.copy()
    draw_rects(vis, rects, (0, 255, 0))       
    for x1, y1, x2, y2 in rects:
        dx = int((x2-x1)*por)
        dy = int((y2-y1)*por)
        px = int((x2-x1)/2)
        py = int((y2-y1)/2)
        
        #Obtenir valors del Torso
        tors = True
        yi2 = int(y2+((y2-y1)*1.6))
        yi1 = y2 + (dy*3)
        
        xi1 = x1 - int((x2-x1)/2)
        xi2 = x2 + int((x2-x1)/2)
        
        #Regular valors segons la grandaria de la imatge
        if yi1 > vis.shape[0]:
            yi1 = vis.shape[0]
        if yi2 > vis.shape[0]:
            yi2 = vis.shape[0]
            
        if xi1 < 0:
            xi1 = 0
        if xi2 > vis.shape[1]:
            xi2 = vis.shape[1]
            
        #Mostrar Requadre del Torso
        draw_rect(vis, xi1 , xi2, yi1, yi2 ,(255,0,0)) 
        
        # requadre de la frent amb un por = 0.30
        if zone == 'front':
            draw_rect(vis, x1+px-int(dx), x1+px+int(dx), y1+int(dy), y1+int(dy*2) ,(0,0,255))
            roi = frame[y1+int(dy):y1+int(dy*2), x1+px-int(dx):x1+px+int(dx)]            
        
        
        #requadre del nas -> bon resultat amb por = 0.10
        if zone == 'nas':
            draw_rect(vis, x1+px-int(dx*0.80), x1+px+int(dx*0.80), y1+py-int(dy), y1+py+int(dy*0.60) ,(0,0,255))
            roi = frame[y1+py-int(dy):y1+py+int(dy*0.60), x1+px-int(dx*0.80):x1+px+int(dx*0.80)]
            
        if zone == 'nas-galtes':
            #Nas
            draw_rect(vis, x1+px-int(dx*0.80), x1+px+int(dx*0.80), y1+py-int(dy), y1+py+int(dy*0.60) ,(0,0,255))
            roi1 = frame[y1+py-int(dy):y1+py+int(dy*0.60), x1+px-int(dx*0.80):x1+px+int(dx*0.80)]
            #Galta dreta
            draw_rect(vis, x1+px+int(dx*1.5), x1+px+int(dx*2.5), y1+py+int(dy*0.20), y1+py+int(dy*1.5) ,(0,0,255))
            roi2 = frame[y1+py+int(dy*0.20):y1+py+int(dy*1.5), x1+px+int(dx*1.5):x1+px+int(dx*2.5)]
            #Galta esquerra
            draw_rect(vis, x1+px-int(dx*2.5), x1+px-int(dx*1.5), y1+py+int(dy*0.20), y1+py+int(dy*1.5) ,(0,0,255))
            roi3 = frame[y1+py+int(dy*0.20):y1+py+int(dy*1.5), x1+px-int(dx*2.5):x1+px-int(dx*1.5)]
        
            roi = np.concatenate((roi1.reshape(1,roi1.shape[1]*roi1.shape[0],roi1.shape[2]),roi2.reshape(1,roi2.shape[1]*roi2.shape[0],roi2.shape[2]),roi3.reshape(1,roi3.shape[1]*roi3.shape[0],roi3.shape[2])), axis=1)
        
        minimos, maximos, medios = valueSkins(roi)
        lower = np.array([0, minimos[1], minimos[2]], dtype = "uint8")
        upper = np.array([255,maximos[1],maximos[2]], dtype = "uint8")
        
    
    converted = cv2.cvtColor(frame, cv2.COLOR_BGR2YCR_CB)
    skinMask = cv2.inRange(converted, lower, upper)
    
    #Invertir la mascara
    inverSkinMask = np.copy(skinMask)
    if invert:
        inverSkinMask[inverSkinMask == 0] += 1
        inverSkinMask[inverSkinMask == 255] = 0
        inverSkinMask[inverSkinMask == 1] = 255

    # apply a series of erosions and dilations to the mask
    # using an elliptical kernel
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 1))
    skinMask = cv2.erode(skinMask, kernel, iterations = 2)
    skinMask = cv2.dilate(skinMask, kernel, iterations = 2)

    # blur the mask to help remove noise, then apply the
    # mask to the frame
    skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0)
    skin = cv2.bitwise_and(frame, frame, mask = inverSkinMask)
    
    if aviso:
        #Mostrar el resultat
        cv2.imshow("images", np.hstack([vis, skin]))
        cv2.waitKey()
        cv2.destroyAllWindows()
    
    if skinner:
        result = skin
        maskara = inverSkinMask[yi1:yi2,xi1:xi2]
    else:
        result = vis
        maskara = None
    
    if tors:
        return result[yi1:yi2,xi1:xi2], maskara
    else:
        return None, None
    
    
def skinVideoDect(camera,cascade,por = 0.10, zone = 'nas' ,invert = False):
    if not zone in ('nas','front','nas-galtes'):
        return None
    
    while True:
        #Valors per defecte al no tenir pell reconeguda
        lower = np.array([0], dtype = "uint8")
        upper = np.array([0], dtype = "uint8")
        
        # grab the current frame
        (grabbed, frame) = camera.read()
        
        #gray = frame
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        gray = cv2.equalizeHist(gray)
        
        #Para detectar la cara
        rects = detect(gray, cascade)
        vis = frame.copy()
        draw_rects(vis, rects, (0, 255, 0))
        roi = None
        for x1, y1, x2, y2 in rects:
            dx = int((x2-x1)*por)
            dy = int((y2-y1)*por)
            px = int((x2-x1)/2)
            py = int((y2-y1)/2)
            
            #Obtenir valors del Torso
            yi2 = int(y2+((y2-y1)*1.6))
            yi1 = y2 + (dy*3)
            
            xi1 = x1 - int((x2-x1)/2)
            xi2 = x2 + int((x2-x1)/2)
            
            #Regular valors segons la grandaria de la imatge
            if yi1 > vis.shape[0]:
                yi1 = vis.shape[0]
            if yi2 > vis.shape[0]:
                yi2 = vis.shape[0]
                
            if xi1 < 0:
                xi1 = 0
            if xi2 > vis.shape[1]:
                xi2 = vis.shape[1]
                
            #Mostrar Requadre del Torso
            draw_rect(vis, xi1 , xi2, yi1, yi2 ,(255,0,0)) 
            
            # requadre de la frent amb un por = 0.30
            if zone == 'front':
                draw_rect(vis, x1+px-int(dx), x1+px+int(dx), y1+int(dy), y1+int(dy*2) ,(0,0,255))
                roi = frame[y1+int(dy):y1+int(dy*2), x1+px-int(dx):x1+px+int(dx)]            
            
            
            #requadre del nas -> bon resultat amb por = 0.10
            if zone == 'nas':
                draw_rect(vis, x1+px-int(dx*0.80), x1+px+int(dx*0.80), y1+py-int(dy), y1+py+int(dy*0.60) ,(0,0,255))
                roi = frame[y1+py-int(dy):y1+py+int(dy*0.60), x1+px-int(dx*0.80):x1+px+int(dx*0.80)]
            
            if zone == 'nas-galtes':
                #Nas
                draw_rect(vis, x1+px-int(dx*0.80), x1+px+int(dx*0.80), y1+py-int(dy), y1+py+int(dy*0.60) ,(0,0,255))
                roi1 = frame[y1+py-int(dy):y1+py+int(dy*0.60), x1+px-int(dx*0.80):x1+px+int(dx*0.80)]
                #Galta dreta
                draw_rect(vis, x1+px+int(dx*1.5), x1+px+int(dx*2.5), y1+py+int(dy*0.20), y1+py+int(dy*1.5) ,(0,255,0))
                roi2 = frame[y1+py+int(dy*0.20):y1+py+int(dy*1.5), x1+px+int(dx*1.5):x1+px+int(dx*2.5)]
                #Galta esquerra
                draw_rect(vis, x1+px-int(dx*2.5), x1+px-int(dx*1.5), y1+py+int(dy*0.20), y1+py+int(dy*1.5) ,(0,255,0))
                roi3 = frame[y1+py+int(dy*0.20):y1+py+int(dy*1.5), x1+px-int(dx*2.5):x1+px-int(dx*1.5)]
            
                roi = np.concatenate((roi1.reshape(1,roi1.shape[1]*roi1.shape[0],roi1.shape[2]),roi2.reshape(1,roi2.shape[1]*roi2.shape[0],roi2.shape[2]),roi3.reshape(1,roi3.shape[1]*roi3.shape[0],roi3.shape[2])), axis=1)
            
            minimos, maximos, medios = valueSkins(roi)
            lower = np.array([0,minimos[1],minimos[2]], dtype = "uint8")
            upper = np.array([255,maximos[1],maximos[2]], dtype = "uint8")
        
    
        # if we are viewing a video and we did not grab a
        # frame, then we have reached the end of the video
        if not grabbed:
            break
        
        #COLOR_RGB2YCR_CB
        converted = cv2.cvtColor(frame, cv2.COLOR_RGB2YCR_CB)
        #COLOR_BGR2HSV
        #converted = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        skinMask = cv2.inRange(converted, lower, upper)
        
        #Invertir la mascara
        inverSkinMask = np.copy(skinMask)
        if invert:
            inverSkinMask[inverSkinMask == 0] += 1
            inverSkinMask[inverSkinMask == 255] = 0
            inverSkinMask[inverSkinMask == 1] = 255
    
        # apply a series of erosions and dilations to the mask
        # using an elliptical kernel
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 1))
        skinMask = cv2.erode(skinMask, kernel, iterations = 2)
        skinMask = cv2.dilate(skinMask, kernel, iterations = 2)
    
        # blur the mask to help remove noise, then apply the
        # mask to the frame
        skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0)
        skin = cv2.bitwise_and(frame, frame, mask = inverSkinMask)
        #skin = cv2.bitwise_and(frame, frame, mask = skinMask)
        
        #Mostrar el resultat
        cv2.imshow("images", np.hstack([vis, skin]))
    
        #Espera un milisegon a espera que es presioni 'q'
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
        
    # cleanup the camera and close any open windows
    camera.release()
    cv2.destroyAllWindows()

      
def detect(img, cascade):
    rects = cascade.detectMultiScale(img, scaleFactor=1.2, minNeighbors=4, minSize=(10, 10), flags = cv.CV_HAAR_SCALE_IMAGE)
    if len(rects) == 0:
        return []
    rects[:,2:] += rects[:,:2]
    return rects

def draw_rects(img, rects, color):
    for x1, y1, x2, y2 in rects:
        cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
        
def draw_rect(img, x1, x2, y1, y2 ,color):
    cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
        
def valueSkins(img, por = 0.10):    
    x,y = img.shape[0], img.shape[1]
    
    dx= int(x*por)
    dy= int(y*por) 

    h,s,v = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB))
    
    #h,s,v = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))
    
    vech = sorted(np.reshape(h, h.size))
    vecs = sorted(np.reshape(s, s.size))
    vecv = sorted(np.reshape(v, v.size))
    n = len(vech)
    
    minh, maxh = min(vech), max(vech)
    medioh = [vech[(n+1)/2] if n%2 != 0 else vech[(n)/2] for x in range(0,1)][0]
    
    mins, maxs = min(vecs), max(vecs) 
    medios = [vecs[(n+1)/2] if n%2 != 0 else vecs[(n)/2] for x in range(0,1)][0]
    
    minv, maxv = min(vecv), max(vecv)
    mediov = [vecv[(n+1)/2] if n%2 != 0 else vecv[(n)/2]  for x in range(0,1)][0]

    return (minh,mins,minv), (maxh,maxs,maxv), (medioh,medios,mediov)

def equalImgs(img1,img2):
    y1,x1 = img1.shape[:2]
    y2,x2 = img2.shape[:2]
    
    if (x1+y1) > (x2+y2):
        new_img1 = resize(img1,x2,y2)
        new_img2 = img2
    else:
        new_img2 = resize(img2,x1,y1)
        new_img1 = img1
    
    return new_img1, new_img2


def main():    
    # if a video path was not supplied, grab the reference
    camera = cv2.VideoCapture(0)
    
    cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_frontalface_alt2.xml")
    
    skinVideoDect(camera,cascade,zone='nas-galtes',invert=False)
    
    #skinDetect('./fotos/retalls/145602_141--0.png',lower,upper)
    
    
def mainImgDect():    
    # if a video path was not supplied, grab the reference
    camera = cv2.VideoCapture(0)
    
    cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_frontalface_alt2.xml")
    
    img, mask = skinImgDectTors('./fotos/ret/164300_141--0.png',cascade,skinner=True, zone='nas-galtes',invert=True, aviso=True)
    
    cv2.imshow('images', img)
    
    cv2.waitKey()
    cv2.destroyAllWindows()

def mainImages(inputDir,ref):  
    # 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")
    
    skinImagesDect(images,cascade,ref)

#main()
#mainImgDect()
#mainImages('./fotos/ret','./fotos/ret/164228_141--0.png')
