def cup_saucer(test_image, show=False):
    test_img = copy.copy(test_image)

    CAL_PARAM = {'thresh': [25, 60], 'radius': [30, 85]}
    circles, cimg = ivt.find_circles(copy.copy(test_img),
                                     6,
                                     param=CAL_PARAM,
                                     blur=1,
                                     show=False)

    CAL_PARAM = {'thresh': [105, 140], 'radius': [30, 85]}
    circles2, cimg = ivt.find_circles2(copy.copy(test_img),
                                       2,
                                       param=CAL_PARAM,
                                       blur=1,
                                       overlap=True,
                                       separation=180,
                                       show=False)

    print len(circles[0])
    print len(circles2[0])

    table_circles = {}
    store = []
    for j, i in enumerate(circles2[0]):
        circle_info = {}
        circle_info["id"] = j
        coords = np.array([i[:-1]])
        radius = i[-1]
        circle_info["circle"] = i
        num = 0
        for k in (circles[0]):
            #print np.array([k[:-1]])
            if cdist(np.array([k[:-1]]), coords) < radius:
                num = num + 1
        circle_info["num_circles"] = num
        store.append(circle_info)

    for member in store:
        if member["num_circles"] > 3:
            color = (0, 255, 0)
            table_circles["saucer"] = member
        else:
            color = (0, 0, 255)
            table_circles["mug"] = member
        print member['circle']

        cv2.circle(cimg, (int(member["circle"][0]), int(member["circle"][1])),
                   int(member["circle"][2]), color, 1)
        # draw the center of the ci~rcle
        cv2.circle(cimg, (int(member["circle"][0]), int(member["circle"][1])),
                   2, color, 1)
    if show == True:
        plt.imshow(cimg)
        plt.show()

    return table_circles
def cup_saucer2(test_image, show=False):
    test_img = copy.copy(test_image)

    CAL_PARAM = {'thresh': [105, 140], 'radius': [25, 50]}

    circles2, cimg = ivt.find_circles2(copy.copy(test_img),
                                       2,
                                       param=CAL_PARAM,
                                       blur=1,
                                       overlap=False,
                                       separation=80,
                                       show=False)

    print len(circles2[0])

    table_circles = {}
    store = []
    for j, i in enumerate(circles2[0]):
        circle_info = {}
        circle_info["id"] = j
        coords = np.array([i[:-1]])

        radius = i[-1]
        circle_info["radius"] = radius
        circle_info["circle"] = i
        num = 0
        store.append(circle_info)

    if store[0]["radius"] > store[0]["radius"]:
        table_circles["saucer"] = store[0]
        table_circles["mug"] = store[1]
    else:
        table_circles["mug"] = store[0]
        table_circles["saucer"] = store[1]

    cv2.circle(cimg, (int(table_circles["saucer"]["circle"][0]),
                      int(table_circles["saucer"]["circle"][1])),
               int(table_circles["saucer"]["circle"][2]), (0, 255, 0), 1)
    # draw the center of the ci~rcle
    cv2.circle(cimg, (int(table_circles["mug"]["circle"][0]),
                      int(table_circles["mug"]["circle"][1])),
               int(table_circles["mug"]["circle"][2]), (0, 0, 255), 1)
    if show == True:
        plt.imshow(cimg)
        plt.show()

    return table_circles
def find_spoon2(image, show=True):
    img = copy.copy(image)

    CAL_PARAM = {'thresh': [75, 100], 'radius': [25, 35]}

    CROP_RADIUS = 90
    PADDING = 30

    circles, cimg = ivt.find_circles2(copy.copy(img),
                                      2,
                                      param=CAL_PARAM,
                                      blur=1,
                                      show=False)
    print "CIRCLES: ", circles
    empty_cup_centre, empty_cup_id = ivt.farthest_node(
        np.array([180, 185]),
        np.array([[circles[0][0][0], circles[0][0][1]],
                  [circles[0][1][0], circles[0][1][1]]]))
    print "EMPTY_MUG_DISTANCE: ", np.array(empty_cup_centre)

    empty_circles = np.array([[circles[0][empty_cup_id]]])
    spoon_circles = np.array([[circles[0][1 - empty_cup_id]]])

    sx, sy = int(spoon_circles[0][0][0]), int(spoon_circles[0][0][1])
    print "SPOON_MUG_WORLD_CENTRE: ", sx, sy

    #img_3b = ivt.black_out(copy.copy(crop_task_img_3), [180,-1,0,-1])
    img_3b = copy.copy(img)

    img_3b[sy - CROP_RADIUS + PADDING:sy + CROP_RADIUS - PADDING,
           sx - CROP_RADIUS + PADDING:sx + CROP_RADIUS - PADDING] = [0, 0, 0]

    print "EMPTY_CUP_WORLD: ", empty_circles
    ex, ey, er = int(empty_circles[0][0][0]), int(
        empty_circles[0][0][1]), int(empty_circles[0][0][-1] + 1)

    r, g, b = cv2.split(img)

    img_3a = copy.copy(img)
    img_3a[ey - er:ey + er, ex - er:ex + er] = [r.mean(), g.mean(), b.mean()]
    img_3a = img_3a[sy - CROP_RADIUS:sy + CROP_RADIUS,
                    sx - CROP_RADIUS:sx + CROP_RADIUS]

    mug_centre = np.array([[sy, sx]])
    cropped_mug_centre = np.array([[CROP_RADIUS, CROP_RADIUS]])

    print mug_centre
    print cropped_mug_centre

    edged, edg_img, cnts, hierarchy = ivt.extract_contours(
        copy.copy(img_3a),
        min_thresh=65,
        max_thresh=240,
        blur=5,
        dilate=3,
        erode=2,
        cnt_mode=cv2.RETR_TREE)

    minsize = 0
    mindistance = 190
    box_minsize = 0
    minperi = 40

    show_img = copy.copy(img)
    show_img = cv2.cvtColor(show_img, cv2.COLOR_RGB2GRAY)
    show_img = cv2.cvtColor(show_img, cv2.COLOR_GRAY2RGB)
    fnode = np.array([CROP_RADIUS, CROP_RADIUS])

    for cnt in cnts:
        peri = cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, 0.03 * peri, True)
        current_outer_contour = []
        for points in approx:
            current_outer_contour.append(points[0])

        distance = cdist(np.array(cropped_mug_centre), current_outer_contour)
        print "CURRENT", np.shape(current_outer_contour)

        if cv2.contourArea(cnt) < minsize:
            print(
                "Object at #{} REJECTED because CONTOUR not big enough: ".
                format(cnt[0]), cv2.contourArea(cnt))
            continue

        if peri < minperi:
            print(
                "Object at #{} REJECTED because PERIMETER not long enough: ".
                format(cnt[0]), peri)
            continue

        if distance[0][0] > mindistance:
            print(
                "Object at #{} REJECTED because not CLOSE ENOUGH: ".format(
                    cnt[0]), distance[0][0])
            continue
        #mindistance = distance[0][0]

        box = ivt.extract_minBox(cnt)
        box_area = cv2.contourArea(np.array([box]))
        #box_area = abs((box[0][0]-box[2][0])*(box[1][1]-box[0][1]))

        if box_area < box_minsize:
            print(
                "Object at #{} REJECTED because BOX not big enough: ".format(
                    cnt[0]), box_area)
            continue

        print("Object at #{} ACCEPTED: ".format(cnt[0]))
        print "    Contour Area: ", cv2.contourArea(cnt)
        print "    Perimeter:    ", peri
        print "    Distance:     ", distance[0][0]
        print "    Box Area:     ", box_area

        fnode_test, fnode_test_id = ivt.farthest_node(cropped_mug_centre[0],
                                                      current_outer_contour)
        # Make edge more accurate
        fnode_testa = current_outer_contour[fnode_test_id + 1]
        fnode_testb = current_outer_contour[fnode_test_id - 1]

        fnode_test_dist = cdist(np.array(cropped_mug_centre),
                                np.array([fnode_test]))

        fnode_add = fnode_test
        fnode_num = 1
        if fnode_test_dist - cdist(np.array(cropped_mug_centre),
                                   np.array([fnode_testa])) < 2:
            print "HELLO"
            print fnode_test_dist - cdist(np.array(cropped_mug_centre),
                                          np.array([fnode_testa]))
            fnode_add = fnode_add + fnode_testa
            fnode_num = fnode_num + 1

        if fnode_test_dist - cdist(np.array(cropped_mug_centre),
                                   np.array([fnode_testb])) < 2:
            print "HELLO2"
            print fnode_test_dist - cdist(np.array(cropped_mug_centre),
                                          np.array([fnode_testb]))
            fnode_add = fnode_add + fnode_testb
            fnode_num = fnode_num + 1

        fnode_test_mean = fnode_add / fnode_num
        print "FNODE MEAN: ", fnode_test_mean,
        print "FNODE ORIG: ", fnode_test
        fnode_dist = cdist(np.array(cropped_mug_centre),
                           np.array([fnode_test_mean]))
        fnode_dist2 = cdist(np.array(cropped_mug_centre), np.array([fnode]))
        print "FNODE_DISTANCES: ", fnode_dist, fnode_dist2,
        if fnode_dist > fnode_dist2:
            fnode = fnode_test_mean
        print "FNODE: ", fnode

    print "CIRCLE:", spoon_circles
    spoon_mug = np.array([sx, sy])
    #spoon_edge = fnode - (fnode-spoon_mug)*
    spoon_edge = fnode
    if cdist(np.array(cropped_mug_centre), np.array([spoon_edge])) < 60:
        print cropped_mug_centre
        print spoon_edge
        print "VECTOR!!!!", cdist(np.array(cropped_mug_centre),
                                  np.array([spoon_edge]))
        fvect = spoon_edge - CROP_RADIUS
        unit_fvect = fvect / scipy.linalg.norm(fvect)
        spoon_edge = unit_fvect * 70 + 80

    print "SPOON_EDGE: ", spoon_edge

    spoon_mug = np.array([sx, sy])
    fnode_world = np.array(
        [sx - CROP_RADIUS + fnode[0], sy - CROP_RADIUS + fnode[1]])
    spoon_edge_world = [
        sx - CROP_RADIUS + int(spoon_edge[0]),
        sy - CROP_RADIUS + int(spoon_edge[1])
    ]

    cv2.circle(show_img, (int(spoon_mug[0]), int(spoon_mug[1])), 3,
               (0, 255, 0), 5)
    cv2.circle(show_img, (int(fnode_world[0]), int(fnode_world[1])), 3,
               (0, 255, 255), 5)
    cv2.circle(show_img, (int(spoon_edge_world[0]), int(spoon_edge_world[1])),
               3, (255, 0, 255), 5)
    if show:
        plt.figure("Spoon and Cup", figsize=[9, 9])
        plt.subplot(2, 2, 1)
        plt.imshow(show_img)
        cv2.imwrite("show_img.jpg", show_img)
        plt.subplot(2, 2, 2)
        plt.imshow(cimg)
        plt.subplot(2, 2, 3)
        plt.imshow(edged)
        plt.subplot(2, 2, 4)
        plt.imshow(img_3a)
        plt.show()
    #print "FNODE: ", fnode

    return spoon_mug, spoon_edge_world, empty_cup_centre
def find_spoon(image, show=True):
    img = copy.copy(image)
    edged, edg_img, cnts, hierarchy = ivt.extract_contours(
        copy.copy(img),
        min_thresh=25,
        max_thresh=200,
        blur=3,
        dilate=4,
        erode=1,
        cnt_mode=cv2.RETR_TREE)
    CAL_PARAM = {'thresh': [75, 100], 'radius': [25, 35]}

    minsize = 1
    mindistance = 1000
    box_minsize = 1

    circles, cimg = ivt.find_circles2(copy.copy(img),
                                      1,
                                      param=CAL_PARAM,
                                      blur=1,
                                      show=False)

    show_img = copy.copy(img)
    show_img = cv2.cvtColor(show_img, cv2.COLOR_RGB2GRAY)
    show_img = cv2.cvtColor(show_img, cv2.COLOR_GRAY2RGB)

    for cnt in cnts:
        current_outer_contour = []
        for points in cnt:
            current_outer_contour.append(points[0])

        distance = cdist(np.array([[circles[0][0][0], circles[0][0][1]]]),
                         current_outer_contour)

        if cv2.contourArea(cnt) < minsize:
            print(
                "Object at #{} REJECTED because CONTOUR not big enough: ".
                format(cnt[0]), cv2.contourArea(cnt))
            continue

        if distance[0][0] > mindistance:
            print(
                "Object at #{} REJECTED because not CLOSE ENOUGH: ".format(
                    cnt[0]), distance[0][0])
            continue
        mindistance = distance[0][0]

        box = ivt.extract_minBox(cnt)
        box_area = abs((box[0][0] - box[2][0]) * (box[1][1] - box[0][1]))

        if box_area < box_minsize:
            print(
                "Object at #{} REJECTED because BOX not big enough: ".format(
                    cnt[0]), box_area)
            continue
        fnode = ivt.farthest_node([circles[0][0][0], circles[0][0][1]],
                                  current_outer_contour)

    print "CIRCLE:", circles
    cv2.circle(show_img, (int(circles[0][0][0]), int(circles[0][0][1])), 3,
               (0, 255, 0), 5)
    cv2.circle(show_img, (fnode[0][0], fnode[0][1]), 3, (0, 255, 255), 5)
    if show:
        plt.figure("Spoon and Cup")
        plt.subplot(2, 2, 1)
        plt.imshow(show_img)
        cv2.imwrite("show_img.jpg", show_img)
        plt.subplot(2, 2, 2)
        plt.imshow(cimg)
        plt.subplot(2, 2, 3)
        plt.imshow(edged)
        plt.show()
    #print "FNODE: ", fnode

    return circles[0], fnode