def main(): robot = Robot() eyeball = Posts() DEBUG = True nudge_count = 0 MIN_MATCHES = 13 MAX_ITEMS = 8 MAX_FAILS = 40 RUN_FAN = False GRIP, TRIP = 1, 1 ROBOGO = False BIN_REVERSE = False cardlist = [] smile = orientation.Simile(just_faces=False) pathfront = orientation.peep.__mtgpics__ looker = cv2.AKAZE_create() matcher = cv2.FlannBasedMatcher(orientation.flann_pms, {}) cam = cv2.VideoCapture(0) time.sleep(6) wait = time.time() print(" -- Loading Hopper --") robot.load_hopper() bin_name = robot.bin_lookup(0.0) old_window = "" id_failure_cnt = 0 while True: __, frame = cam.read() showimg = eyeball.draw_guides(frame.copy()) warp = eyeball.get_warp(frame) cv2.imshow("warp", warp) cv2.imshow("cam", showimg) ch = cv2.waitKey(1) & 0xff eyeball.check_key(ch) if ch == 27: robot.dothis("stop") robot.dothis("fan_off") cv2.destroyAllWindows() break if ch == ord('q'): print robot.sensor_stats(min_ret=100) if ch == ord('w'): print robot.xyz_pos() if ch == ord('e'): print("i'm [e] pressed!") ee = smile.updown(warp) print("DIST: vs UP: vs DOWN:") for q in sorted(ee.keys()): print("{:6} - {:6} - {:6}".format(q, ee[q][0], ee[q][1])) if ch == ord('r'): print("[r] cards in matcher: {}".format(len(cardlist))) for n, card in enumerate(cardlist): print("{:3}: {:4} - {} #kp={}".format(n, card.code, card.name, len(card.kp))) if ch == ord('f'): RUN_FAN = not RUN_FAN if RUN_FAN: wait = robot.dothis('fan_on') + time.time() else: wait = robot.dothis('fan_off') + time.time() if ch == ord('g'): ROBOGO = not ROBOGO print("ROBOGO = {}".format(ROBOGO)) if ROBOGO and not robot.ID_DONE: old_cardlist_len = len(cardlist) matcher, cardlist = card_adder(smile.fistfull(warp, trips=TRIP, grip=GRIP), matcher, orientation.orient_db, cardlist, maxitems=MAX_ITEMS) current_kp, matchdict = card_compare(warp, looker, matcher) texture = len(current_kp) if texture < (MIN_MATCHES * 3): print("WARNING, not enough texture in input image (kp={})". format(texture)) bestmatch = sorted([(i, matches) for i, matches in matchdict.viewitems() if len(matches) > (MIN_MATCHES + texture) / 6], key=lambda x: len(x[1]), reverse=True) if not bestmatch: id_failure_cnt += 1 msg = "" if (len(cardlist) == old_cardlist_len): GRIP += 1 TRIP += np.random.randint(-1, 3) if (TRIP > 4) or (TRIP < 0): TRIP = 1 msg = ", and nothing new added to matcher(len={}) GRIP={}, TRIP={}"\ .format(old_cardlist_len, GRIP, TRIP) if DEBUG: print("No luck: {} fails{}".format(id_failure_cnt, msg)) if len(bestmatch) > 1: GRIP = 1 if DEBUG: print("Has {} candidates".format(len(bestmatch))) if (id_failure_cnt > MAX_FAILS) and not bestmatch: # send the card to the unidentified group/bin cardlist, GRIP, TRIP = [], 1, 1 matcher.clear() robot.ID_DONE = True bin_name = robot.bin_lookup(10000.1) print("Couldn't match this in {} tries".format(id_failure_cnt)) id_failure_cnt = 0 for indx, matches in bestmatch: one_card = cardlist[indx] pricestr = 'None' pricetag = 0 priceline = pricer.single_price(one_card.id)[0] if priceline: pricetag = priceline[1] pricestr = "$" + " ,$".join(map(str, priceline)[1:3]) bin_name = robot.bin_lookup(pricetag) new_window = "{} {} | {}".format(one_card.name, one_card.code, pricestr) warp = eyeball.show_card_info(new_window.split(" | "), warp, max_expansion=2.6, topleft=(5, 5)) cv2.imshow( new_window, cv2.drawMatchesKnn( warp, current_kp, cv2.imread(os.path.join(pathfront, one_card.pic_path)), one_card.kp, matches, outImg=np.zeros((eyeball.yc, eyeball.xc * 2, 3), dtype=np.uint8), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)) if old_window: cv2.destroyWindow(old_window) old_window = new_window id_failure_cnt = 0 robot.ID_DONE = True # only do all this for the first card on the 'bestmatch' list! break # with card identified, begin moving the robot current_time = time.time() if robot.ID_DONE and (not robot.PICKING_UP) and ( not robot.NEED_DROP) and (current_time > wait): if DEBUG: print("moving arm over hopper") wait = robot.dothis("pickup_pos") + time.time() wait += (robot.dothis("servo_up") * 0.5) robot.PICKING_UP = True sens = robot.sensor_stats() # if DEBUG: print("{}".format(sens)) if robot.PICKING_UP and (current_time > wait): if DEBUG: print("checking that hopper is high enough") if "op" in sens['y_max']: if DEBUG: print("raising hopper by default amount") wait = robot.hopper_up() + time.time() if "op" in sens['x_max'] and nudge_count < 12: if DEBUG: print("raising hopper by a nudge {}".format(nudge_count)) robot.hopper_up(0.1) if DEBUG: print("sensor indicates card on board") robot.CARD_CARRIED = True robot.PICKING_UP = False if robot.CARD_CARRIED and (current_time > wait): if DEBUG: print("card is moving out for bin drop") wait = robot.go_xz(bin_name) + time.time() robot.CARD_CARRIED = False robot.PICKING_UP = False robot.NEED_DROP = True if robot.NEED_DROP and (current_time > wait): if DEBUG: print("checking that card made it to drop zone") sens = robot.sensor_stats() if "op" in sens['x_max']: if DEBUG: print( "*** arrived at drop zone empty! *** going back to get card" ) wait = robot.hopper_up(0.1) + time.time() + robot.go_xz( bin_name, reverse=True) robot.NEED_DROP = False else: if DEBUG: print("Dropping card into bin") wait = robot.dothis('servo_drop') + time.time() robot.NEED_DROP = False robot.ID_DONE = False
def main(): camx, camy = 640, 480 # typical web-cam dimensions yc, xc = (445, 312) # typical pixels for a card cdx1, cdy1, cdx2, cdy2 = card_corners(camx, camy, yc, xc) MIN_MATCHES = 5 DRAW_MATCHES, RUN_FREE, PRINT_GOOD = True, False, True MAX_ITEMS = 500 cardlist = [] user_given_name = None M2 = cv2.getRotationMatrix2D((xc / 2, xc / 2), -90, 1) smile = orientation.Simile(just_faces=False) pathfront = orientation.peep.__mtgpics__ looker = cv2.AKAZE_create() matcher = cv2.FlannBasedMatcher(orientation.flann_pms, {}) cam = cv2.VideoCapture(0) undertaker(img_code='USER') ui = dict( g="[g]ive the new pics a base-name. Currently: '{}' ", p= "[p]rint verbose news about the matcher: {}{}bonus info! matcher has {} objects.", t="[t]ake a picture: {} with {} errors", k="[k]ompare the area in the green box with database items", r="[r]un comparisons continuously, ie. on every frame: {}", e="[e]rasing {} items from cardlist and matcher", c="[c]lean up the windows", d="[d]rawing Matches set to: {}", esc="[esc]ape (exit) the program loop", h="[h]elp - show these options") for vals in ui.viewvalues(): print(vals) while True: __, frame = cam.read() showimg = frame.copy() cv2.rectangle(showimg, (cdx1, cdy1), (cdx2, cdy2), (0, 255, 0)) cv2.imshow("cam", showimg) ch = cv2.waitKey(1) & 0xff if ch != 255: print ch if ch == ord('r'): RUN_FREE = not RUN_FREE print(ui['r'].format(RUN_FREE)) if ch == ord('g'): print(ui['g'].format(user_given_name)) user_given_name = str( raw_input("type in the new pic base-name >>> ")).strip() if ch == ord('p'): PRINT_GOOD = not PRINT_GOOD print(ui['p'].format(PRINT_GOOD, os.linesep, len(cardlist))) if ch == ord('t'): samp_img = cv2.warpAffine(frame[cdy1:cdy2, cdx1:cdx2], M2, (xc, yc)) quant, errors = seemore.pic_adder(samp_img, img_name=user_given_name) print(ui['t'].format(quant + 1, errors)) if RUN_FREE or (ch == ord('k')): samp_img = cv2.warpAffine(frame[cdy1:cdy2, cdx1:cdx2], M2, (xc, yc)) matcher, cardlist = card_adder(smile.handful(samp_img), matcher, orientation.orient_db, cardlist, maxitems=MAX_ITEMS) cv2.imshow("sample", samp_img) current_kp, matchdict = card_compare(samp_img, looker, matcher) for indx, matches in matchdict.viewitems(): if len(matches) > MIN_MATCHES: one_card = cardlist[indx] pricestr = pricer.single_price(one_card.id)[0] if pricestr: pricestr = ", ".join(map(str, pricestr)[1:3]) if not DRAW_MATCHES: cv2.imshow( "{} {}".format(one_card.name, one_card.code), cv2.imread( os.path.join(pathfront, one_card.pic_path))) if PRINT_GOOD: print("good match: {} {} (pnts:{}) prices: {}". format(cardlist[indx].name, cardlist[indx].code, len(matches), pricestr)) else: cv2.imshow( "{} {}".format(one_card.name, one_card.code), cv2.drawMatchesKnn( samp_img, current_kp, cv2.imread( os.path.join(pathfront, one_card.pic_path)), one_card.kp, matches, outImg=np.zeros((yc, xc * 2, 3), dtype=np.uint8), flags=cv2. DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)) if PRINT_GOOD: print("good match: {} {} (pnts:{}) prices: {}". format(one_card.name, one_card.code, len(matches), pricestr)) if ch == ord('e'): print(ui['e'].format(len(cardlist))) matcher.clear() cardlist = [] ch = ord('c') if ch == ord('c'): print(ui['c']) cv2.destroyAllWindows() if ch == ord('d'): DRAW_MATCHES = not DRAW_MATCHES print(ui['d'].format(DRAW_MATCHES)) if ch == ord('h'): print("") for vals in ui.viewvalues(): print(vals) if ch == 27: print(ui['esc']) cv2.destroyAllWindows() break
def main(): robot = Robot() eyeball = Posts() DEBUG = True nudge_count = 0 MIN_MATCHES = 13 MAX_ITEMS = 8 MAX_FAILS = 40 RUN_FAN = False GRIP, TRIP = 1, 1 ROBOGO = False BIN_REVERSE = False cardlist = [] smile = orientation.Simile(just_faces=False) pathfront = orientation.peep.__mtgpics__ looker = cv2.AKAZE_create() matcher = cv2.FlannBasedMatcher(orientation.flann_pms, {}) cam = cv2.VideoCapture(0) time.sleep(6) wait = time.time() print(" -- Loading Hopper --") robot.load_hopper() bin_name = robot.bin_lookup(0.0) old_window = "" id_failure_cnt = 0 while True: __, frame = cam.read() showimg = eyeball.draw_guides(frame.copy()) warp = eyeball.get_warp(frame) cv2.imshow("warp", warp) cv2.imshow("cam", showimg) ch = cv2.waitKey(1) & 0xff eyeball.check_key(ch) if ch == 27: robot.dothis("stop") robot.dothis("fan_off") cv2.destroyAllWindows() break if ch == ord('q'): print robot.sensor_stats(min_ret=100) if ch == ord('w'): print robot.xyz_pos() if ch == ord('e'): print("i'm [e] pressed!") ee = smile.updown(warp) print("DIST: vs UP: vs DOWN:") for q in sorted(ee.keys()): print("{:6} - {:6} - {:6}".format(q, ee[q][0], ee[q][1])) if ch == ord('r'): print("[r] cards in matcher: {}".format(len(cardlist))) for n, card in enumerate(cardlist): print("{:3}: {:4} - {} #kp={}".format(n, card.code, card.name, len(card.kp))) if ch == ord('f'): RUN_FAN = not RUN_FAN if RUN_FAN: wait = robot.dothis('fan_on') + time.time() else: wait = robot.dothis('fan_off') + time.time() if ch == ord('g'): ROBOGO = not ROBOGO print("ROBOGO = {}".format(ROBOGO)) if ROBOGO and not robot.ID_DONE: old_cardlist_len = len(cardlist) matcher, cardlist = card_adder(smile.fistfull(warp, trips=TRIP, grip=GRIP), matcher, orientation.orient_db, cardlist, maxitems=MAX_ITEMS) current_kp, matchdict = card_compare(warp, looker, matcher) texture = len(current_kp) if texture < (MIN_MATCHES * 3): print("WARNING, not enough texture in input image (kp={})".format(texture)) bestmatch = sorted([(i, matches) for i, matches in matchdict.viewitems() if len(matches) > (MIN_MATCHES + texture) / 6], key=lambda x: len(x[1]), reverse=True) if not bestmatch: id_failure_cnt += 1 msg = "" if (len(cardlist) == old_cardlist_len): GRIP += 1 TRIP += np.random.randint(-1, 3) if (TRIP > 4) or (TRIP < 0): TRIP = 1 msg = ", and nothing new added to matcher(len={}) GRIP={}, TRIP={}"\ .format(old_cardlist_len, GRIP, TRIP) if DEBUG: print("No luck: {} fails{}".format(id_failure_cnt, msg)) if len(bestmatch) > 1: GRIP = 1 if DEBUG: print("Has {} candidates".format(len(bestmatch))) if (id_failure_cnt > MAX_FAILS) and not bestmatch: # send the card to the unidentified group/bin cardlist, GRIP, TRIP = [], 1, 1 matcher.clear() robot.ID_DONE = True bin_name = robot.bin_lookup(10000.1) print("Couldn't match this in {} tries".format(id_failure_cnt)) id_failure_cnt = 0 for indx, matches in bestmatch: one_card = cardlist[indx] pricestr = 'None' pricetag = 0 priceline = pricer.single_price(one_card.id)[0] if priceline: pricetag = priceline[1] pricestr = "$" + " ,$".join(map(str, priceline)[1:3]) bin_name = robot.bin_lookup(pricetag) new_window = "{} {} | {}".format(one_card.name, one_card.code, pricestr) warp = eyeball.show_card_info(new_window.split(" | "), warp, max_expansion=2.6, topleft=(5, 5)) cv2.imshow(new_window, cv2.drawMatchesKnn(warp, current_kp, cv2.imread(os.path.join(pathfront, one_card.pic_path)), one_card.kp, matches, outImg=np.zeros((eyeball.yc, eyeball.xc * 2, 3), dtype=np.uint8), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)) if old_window: cv2.destroyWindow(old_window) old_window = new_window id_failure_cnt = 0 robot.ID_DONE = True # only do all this for the first card on the 'bestmatch' list! break # with card identified, begin moving the robot current_time = time.time() if robot.ID_DONE and (not robot.PICKING_UP) and (not robot.NEED_DROP) and (current_time > wait): if DEBUG: print("moving arm over hopper") wait = robot.dothis("pickup_pos") + time.time() wait += (robot.dothis("servo_up") * 0.5) robot.PICKING_UP = True sens = robot.sensor_stats() # if DEBUG: print("{}".format(sens)) if robot.PICKING_UP and (current_time > wait): if DEBUG: print("checking that hopper is high enough") if "op" in sens['y_max']: if DEBUG: print("raising hopper by default amount") wait = robot.hopper_up() + time.time() if "op" in sens['x_max'] and nudge_count < 12: if DEBUG: print("raising hopper by a nudge {}".format(nudge_count)) robot.hopper_up(0.1) if DEBUG: print("sensor indicates card on board") robot.CARD_CARRIED = True robot.PICKING_UP = False if robot.CARD_CARRIED and (current_time > wait): if DEBUG: print("card is moving out for bin drop") wait = robot.go_xz(bin_name) + time.time() robot.CARD_CARRIED = False robot.PICKING_UP = False robot.NEED_DROP = True if robot.NEED_DROP and (current_time > wait): if DEBUG: print("checking that card made it to drop zone") sens = robot.sensor_stats() if "op" in sens['x_max']: if DEBUG: print("*** arrived at drop zone empty! *** going back to get card") wait = robot.hopper_up(0.1) + time.time() + robot.go_xz(bin_name, reverse=True) robot.NEED_DROP = False else: if DEBUG: print("Dropping card into bin") wait = robot.dothis('servo_drop') + time.time() robot.NEED_DROP = False robot.ID_DONE = False
def main(): camx, camy = 640, 480 # typical web-cam dimensions yc, xc = (445, 312) # typical pixels for a card cdx1, cdy1, cdx2, cdy2 = card_corners(camx, camy, yc, xc) MIN_MATCHES = 5 DRAW_MATCHES, RUN_FREE, PRINT_GOOD = True, False, True MAX_ITEMS = 500 cardlist = [] user_given_name = None M2 = cv2.getRotationMatrix2D((xc/2, xc/2), -90, 1) smile = orientation.Simile(just_faces=False) pathfront = orientation.peep.__mtgpics__ looker = cv2.AKAZE_create() matcher = cv2.FlannBasedMatcher(orientation.flann_pms, {}) cam = cv2.VideoCapture(0) undertaker(img_code='USER') ui = dict(g="[g]ive the new pics a base-name. Currently: '{}' ", p="[p]rint verbose news about the matcher: {}{}bonus info! matcher has {} objects.", t="[t]ake a picture: {} with {} errors", k="[k]ompare the area in the green box with database items", r="[r]un comparisons continuously, ie. on every frame: {}", e="[e]rasing {} items from cardlist and matcher", c="[c]lean up the windows", d="[d]rawing Matches set to: {}", esc="[esc]ape (exit) the program loop", h="[h]elp - show these options") for vals in ui.viewvalues(): print(vals) while True: __, frame = cam.read() showimg = frame.copy() cv2.rectangle(showimg, (cdx1, cdy1), (cdx2, cdy2), (0, 255, 0)) cv2.imshow("cam", showimg) ch = cv2.waitKey(1) & 0xff if ch != 255: print ch if ch == ord('r'): RUN_FREE = not RUN_FREE print(ui['r'].format(RUN_FREE)) if ch == ord('g'): print(ui['g'].format(user_given_name)) user_given_name = str(raw_input("type in the new pic base-name >>> ")).strip() if ch == ord('p'): PRINT_GOOD = not PRINT_GOOD print(ui['p'].format(PRINT_GOOD, os.linesep, len(cardlist))) if ch == ord('t'): samp_img = cv2.warpAffine(frame[cdy1:cdy2, cdx1:cdx2], M2, (xc, yc)) quant, errors = seemore.pic_adder(samp_img, img_name=user_given_name) print(ui['t'].format(quant+1, errors)) if RUN_FREE or (ch == ord('k')): samp_img = cv2.warpAffine(frame[cdy1:cdy2, cdx1:cdx2], M2, (xc, yc)) matcher, cardlist = card_adder(smile.handful(samp_img), matcher, orientation.orient_db, cardlist, maxitems=MAX_ITEMS) cv2.imshow("sample", samp_img) current_kp, matchdict = card_compare(samp_img, looker, matcher) for indx, matches in matchdict.viewitems(): if len(matches) > MIN_MATCHES: one_card = cardlist[indx] pricestr = pricer.single_price(one_card.id)[0] if pricestr: pricestr = ", ".join(map(str, pricestr)[1:3]) if not DRAW_MATCHES: cv2.imshow("{} {}".format(one_card.name, one_card.code), cv2.imread(os.path.join(pathfront, one_card.pic_path))) if PRINT_GOOD: print("good match: {} {} (pnts:{}) prices: {}" .format(cardlist[indx].name, cardlist[indx].code, len(matches), pricestr)) else: cv2.imshow("{} {}".format(one_card.name, one_card.code), cv2.drawMatchesKnn(samp_img, current_kp, cv2.imread(os.path.join(pathfront, one_card.pic_path)), one_card.kp, matches, outImg=np.zeros((yc, xc*2, 3), dtype=np.uint8), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)) if PRINT_GOOD: print("good match: {} {} (pnts:{}) prices: {}" .format(one_card.name, one_card.code, len(matches), pricestr)) if ch == ord('e'): print(ui['e'].format(len(cardlist))) matcher.clear() cardlist = [] ch = ord('c') if ch == ord('c'): print(ui['c']) cv2.destroyAllWindows() if ch == ord('d'): DRAW_MATCHES = not DRAW_MATCHES print(ui['d'].format(DRAW_MATCHES)) if ch == ord('h'): print("") for vals in ui.viewvalues(): print(vals) if ch == 27: print(ui['esc']) cv2.destroyAllWindows() break