def inferHair(vag_list, enable):
    hair_list = []

    #70% of chanche to add hair
    if enable:

        for vag in vag_list:

            #Hair rules:
            hair_w = vag.w * random.uniform(0.4, 1.5)
            hair_h = vag.h * random.uniform(0.4, 1.5)

            #center:
            x = vag.x
            y = vag.y - (hair_h / 2) - (vag.h / 2)

            #Calculate Bounding Box:
            xmin = int(x - (hair_w / 2))
            xmax = int(x + (hair_w / 2))
            ymin = int(y - (hair_h / 2))
            ymax = int(y + (hair_h / 2))

            hair_list.append(
                BodyPart("hair", xmin, ymin, xmax, ymax, x, y, hair_w, hair_h))

    return hair_list
def inferNip(aur_list):
    nip_list = []

    for aur in aur_list:

        #Nip rules:
        # - circle (w == h)
        # - min dim: 5
        # - bigger if aur is bigger
        nip_dim = int(5 + aur.w * random.uniform(0.03, 0.09))

        #center:
        x = aur.x
        y = aur.y

        #Calculate Bounding Box:
        xmin = int(x - (nip_dim / 2))
        xmax = int(x + (nip_dim / 2))
        ymin = int(y - (nip_dim / 2))
        ymax = int(y + (nip_dim / 2))

        nip_list.append(
            BodyPart("nip", xmin, ymin, xmax, ymax, x, y, nip_dim, nip_dim))

    return nip_list
def resolveTitAurMissingProblems(tits_list, aur_list, problem_code):

    if problem_code == 3:

        random_tit_factor = random.randint(2, 5)  #TOTEST

        #Add the first tit:
        new_w = aur_list[0].w * random_tit_factor  #TOTEST
        new_x = aur_list[0].x
        new_y = aur_list[0].y

        xmin = int(new_x - (new_w / 2))
        xmax = int(new_x + (new_w / 2))
        ymin = int(new_y - (new_w / 2))
        ymax = int(new_y + (new_w / 2))

        tits_list.append(
            BodyPart("tit", xmin, ymin, xmax, ymax, new_x, new_y, new_w,
                     new_w))

        #Add the second tit:
        new_w = aur_list[1].w * random_tit_factor  #TOTEST
        new_x = aur_list[1].x
        new_y = aur_list[1].y

        xmin = int(new_x - (new_w / 2))
        xmax = int(new_x + (new_w / 2))
        ymin = int(new_y - (new_w / 2))
        ymax = int(new_y + (new_w / 2))

        tits_list.append(
            BodyPart("tit", xmin, ymin, xmax, ymax, new_x, new_y, new_w,
                     new_w))

    elif problem_code == 6:

        #Find wich aur is full:
        d1 = abs(tits_list[0].x - aur_list[0].x)
        d2 = abs(tits_list[0].x - aur_list[1].x)

        if d1 > d2:
            #aur[0] is empty
            new_x = aur_list[0].x
            new_y = aur_list[0].y
        else:
            #aur[1] is empty
            new_x = aur_list[1].x
            new_y = aur_list[1].y

        #Calculate Bounding Box:
        xmin = int(new_x - (tits_list[0].w / 2))
        xmax = int(new_x + (tits_list[0].w / 2))
        ymin = int(new_y - (tits_list[0].w / 2))
        ymax = int(new_y + (tits_list[0].w / 2))

        tits_list.append(
            BodyPart("tit", xmin, ymin, xmax, ymax, new_x, new_y,
                     tits_list[0].w, tits_list[0].w))

    elif problem_code == 7:

        #Add the first aur:
        new_w = tits_list[0].w * random.uniform(0.03, 0.1)  #TOTEST
        new_x = tits_list[0].x
        new_y = tits_list[0].y

        xmin = int(new_x - (new_w / 2))
        xmax = int(new_x + (new_w / 2))
        ymin = int(new_y - (new_w / 2))
        ymax = int(new_y + (new_w / 2))

        aur_list.append(
            BodyPart("aur", xmin, ymin, xmax, ymax, new_x, new_y, new_w,
                     new_w))

        #Add the second aur:
        new_w = tits_list[1].w * random.uniform(0.03, 0.1)  #TOTEST
        new_x = tits_list[1].x
        new_y = tits_list[1].y

        xmin = int(new_x - (new_w / 2))
        xmax = int(new_x + (new_w / 2))
        ymin = int(new_y - (new_w / 2))
        ymax = int(new_y + (new_w / 2))

        aur_list.append(
            BodyPart("aur", xmin, ymin, xmax, ymax, new_x, new_y, new_w,
                     new_w))

    elif problem_code == 8:

        #Find wich tit is full:
        d1 = abs(aur_list[0].x - tits_list[0].x)
        d2 = abs(aur_list[0].x - tits_list[1].x)

        if d1 > d2:
            #tit[0] is empty
            new_x = tits_list[0].x
            new_y = tits_list[0].y
        else:
            #tit[1] is empty
            new_x = tits_list[1].x
            new_y = tits_list[1].y

        #Calculate Bounding Box:
        xmin = int(new_x - (aur_list[0].w / 2))
        xmax = int(new_x + (aur_list[0].w / 2))
        ymin = int(new_y - (aur_list[0].w / 2))
        ymax = int(new_y + (aur_list[0].w / 2))
        aur_list.append(
            BodyPart("aur", xmin, ymin, xmax, ymax, new_x, new_y,
                     aur_list[0].w, aur_list[0].w))
def findBodyPart(image, part_name):

    bodypart_list = []  #empty BodyPart list

    #Get the correct color filter:
    if part_name == "tit":
        #Use combined color filter
        f1 = np.asarray([0, 0, 0])  # tit color filter
        f2 = np.asarray([10, 10, 10])
        f3 = np.asarray([0, 0, 250])  # aur color filter
        f4 = np.asarray([0, 0, 255])
        color_mask1 = cv2.inRange(image, f1, f2)
        color_mask2 = cv2.inRange(image, f3, f4)
        color_mask = cv2.bitwise_or(color_mask1, color_mask2)  #combine

    elif part_name == "aur":
        f1 = np.asarray([0, 0, 250])  # aur color filter
        f2 = np.asarray([0, 0, 255])
        color_mask = cv2.inRange(image, f1, f2)

    elif part_name == "vag":
        f1 = np.asarray([250, 0, 0])  # vag filter
        f2 = np.asarray([255, 0, 0])
        color_mask = cv2.inRange(image, f1, f2)

    elif part_name == "belly":
        f1 = np.asarray([250, 0, 250])  # belly filter
        f2 = np.asarray([255, 0, 255])
        color_mask = cv2.inRange(image, f1, f2)

    #find contours:
    contours, hierarchy = cv2.findContours(color_mask, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_SIMPLE)

    #for every contour:
    for cnt in contours:

        if len(cnt) > 5:  #at least 5 points to fit ellipse

            #(x, y), (MA, ma), angle = cv2.fitEllipse(cnt)
            ellipse = cv2.fitEllipse(cnt)

            #Fit Result:
            x = ellipse[0][0]  #center x
            y = ellipse[0][1]  #center y
            angle = ellipse[2]  #angle
            aMin = ellipse[1][0]
            #asse minore
            aMax = ellipse[1][1]
            #asse maggiore

            #Detect direction:
            if angle == 0:
                h = aMax
                w = aMin
            else:
                h = aMin
                w = aMax

            #Normalize the belly size:
            if part_name == "belly":
                if w < 15:
                    w *= 2
                if h < 15:
                    h *= 2

            #Normalize the vag size:
            if part_name == "vag":
                if w < 15:
                    w *= 2
                if h < 15:
                    h *= 2

            #Calculate Bounding Box:
            xmin = int(x - (w / 2))
            xmax = int(x + (w / 2))
            ymin = int(y - (h / 2))
            ymax = int(y + (h / 2))

            bodypart_list.append(
                BodyPart(part_name, xmin, ymin, xmax, ymax, x, y, w, h))

    return bodypart_list