def extract_shape_contours(image, threshold=120, show=True): img = copy.copy(image) gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) gray_flat = gray[np.isfinite(gray)] black, white = np.min(gray_flat), np.max(gray_flat) if show: plt.figure('Gray Image and Histogram') plt.subplot(1, 2, 1) plt.imshow(img) plt.title('Gray Image') plt.subplot(1, 2, 2) plt.hist(gray_flat, bins=np.linspace(black, white, 20), histtype='step') plt.xlim(black, white) plt.title('Gray Histogram') plt.xlabel('Value') plt.ylabel('Count') plt.show() gray_mask = np.zeros_like(gray) gray_mask[gray < threshold] = 250 gray_mask[-20:-1, :] = 0 gray_mask[:, 0:30] = 0 gray_mask[:, -20:-1] = 0 edged, edg_img, cnts, hierarchy = ivt.extract_contours( gray_mask, min_thresh=60, max_thresh=250, blur=3, dilate=1, erode=1, cnt_mode=cv2.RETR_EXTERNAL) if show: plt.figure("Extracted Shapes") plt.subplot(1, 2, 1) plt.imshow(gray_mask) plt.subplot(1, 2, 2) plt.imshow(edged) plt.show() cv2.imwrite("edged_img.jpg", edged) cv2.imwrite("gray_mask.jpg", gray_mask) return cnts, hierarchy
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