Esempio n. 1
0
def watch_for_card(camera):
    has_moved = False
    been_to_base = False

    global captures
    global font
    captures = []

    font = cv.InitFont(cv.CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0)
    img = cv.QueryFrame(camera)
    size = cv.GetSize(img)
    n_pixels = size[0] * size[1]

    grey = cv.CreateImage(size, 8, 1)
    recent_frames = [cv.CloneImage(grey)]
    base = cv.CloneImage(grey)
    cv.CvtColor(img, base, cv.CV_RGB2GRAY)
    # cv.ShowImage('card', base)
    tmp = cv.CloneImage(grey)

    while True:
        img = cv.QueryFrame(camera)
        cv.CvtColor(img, grey, cv.CV_RGB2GRAY)

        biggest_diff = max(sum_squared(grey, frame) / n_pixels for frame in recent_frames)

        # display the cam view
        cv.PutText(img, "%s" % biggest_diff, (1, 24), font, (255, 255, 255))
        cv.ShowImage('win', img)
        recent_frames.append(cv.CloneImage(grey))
        if len(recent_frames) > 3:
            del recent_frames[0]

        # check for keystroke
        c = cv.WaitKey(10)
        # if there was a keystroke, reset the last capture
        if c == 27:
            return captures
        elif c == 32:
            has_moved = True
            been_to_base = True
        elif c == 114:
            base = cv.CloneImage(grey)


        # if we're stable-ish
        if biggest_diff < 10:
            # if we're similar to base, update base
            # else, check for card
            # base_diff = max(sum_squared(base, frame) / n_pixels for frame in recent_frames)
            base_corr = 0
            try:
                base_corr = min(ccoeff_normed(base, frame) for frame in recent_frames)
            except:
                print ("Unable to calculate the base_corr")
                pass
            # cv.ShowImage('debug', base)

            """for i, frame in enumerate(recent_frames):
                tmp = cv.CloneImage(base)
                cv.Sub(base, frame, tmp)
                cv.Pow(tmp, tmp, 2.0)
                cv.PutText(tmp, "%s" % (i+1), (1,24), font, (255, 255, 255))
                #my_diff = sum_squared(base, frame) / n_pixels
                my_diff = ccoeff_normed(base, frame) #score(base, frame, cv.CV_TM_CCOEFF_NORMED)
                cv.PutText(tmp, "%s" % my_diff, (40, 24), font, (255, 255, 255))
                cv.ShowImage('dbg%s' % (i+1), tmp)"""
            # print "stable. corr = %s. moved = %s. been_to_base = %s" % (base_corr, has_moved, been_to_base)
            if base_corr > 0.75 and not been_to_base:
                base = cv.CloneImage(grey)
                #	cv.ShowImage('debug', base)
                has_moved = False
                been_to_base = True
                print "STATE: been to base. waiting for move"
            elif has_moved and been_to_base:
                corners = detect_card(grey, base)
                if corners is not None:
                    card = get_card(grey, corners)
                    cv.Flip(card, card, -1)
                    captures.append(card)
                    update_windows()
                    # cv.ShowImage('card', card)
                    has_moved = False
                    been_to_base = False
                    print "STATE: detected. waiting for go to base"
        else:
            if not has_moved:
                print "STATE: has moved. waiting for stable"
            has_moved = True
Esempio n. 2
0
def watch_for_card(camera):
    has_moved = False
    been_to_base = False

    global captures
    global font
    captures = []

    font = cv.InitFont(cv.CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0)
    img = cv.QueryFrame(camera)
    size = cv.GetSize(img)
    n_pixels = size[0] * size[1]

    grey = cv.CreateImage(size, 8, 1)
    recent_frames = [cv.CloneImage(grey)]
    base = cv.CloneImage(grey)
    cv.CvtColor(img, base, cv.CV_RGB2GRAY)
    #cv.ShowImage('card', base)
    tmp = cv.CloneImage(grey)

    while True:
        img = cv.QueryFrame(camera)
        cv.CvtColor(img, grey, cv.CV_RGB2GRAY)

        biggest_diff = max(
            sum_squared(grey, frame) / n_pixels for frame in recent_frames)

        #display the cam view
        cv.PutText(img, "%s" % biggest_diff, (1, 24), font, (255, 255, 255))
        cv.ShowImage('win', img)
        recent_frames.append(cv.CloneImage(grey))
        if len(recent_frames) > 3:
            del recent_frames[0]

        #check for keystroke
        c = cv.WaitKey(10)
        #if there was a keystroke, reset the last capture
        if c == 27:
            return captures
        elif c == 32:
            has_moved = True
            been_to_base = True
        elif c == 114:
            base = cv.CloneImage(grey)

        #if we're stable-ish
        if biggest_diff < 10:
            #if we're similar to base, update base
            #else, check for card
            #base_diff = max(sum_squared(base, frame) / n_pixels for frame in recent_frames)
            base_corr = min(
                ccoeff_normed(base, frame) for frame in recent_frames)
            #cv.ShowImage('debug', base)
            """for i, frame in enumerate(recent_frames):
				tmp = cv.CloneImage(base)
				cv.Sub(base, frame, tmp)
				cv.Pow(tmp, tmp, 2.0)
				cv.PutText(tmp, "%s" % (i+1), (1,24), font, (255, 255, 255))
				#my_diff = sum_squared(base, frame) / n_pixels
				my_diff = ccoeff_normed(base, frame) #score(base, frame, cv.CV_TM_CCOEFF_NORMED)
				cv.PutText(tmp, "%s" % my_diff, (40, 24), font, (255, 255, 255))
				cv.ShowImage('dbg%s' % (i+1), tmp)"""
            #print "stable. corr = %s. moved = %s. been_to_base = %s" % (base_corr, has_moved, been_to_base)
            if base_corr > 0.75 and not been_to_base:
                base = cv.CloneImage(grey)
                #	cv.ShowImage('debug', base)
                has_moved = False
                been_to_base = True
                print "STATE: been to base. waiting for move"
            elif has_moved and been_to_base:
                corners = detect_card(grey, base)
                if corners is not None:
                    card = get_card(grey, corners)
                    cv.Flip(card, card, -1)
                    captures.append(card)
                    update_windows()
                    #cv.ShowImage('card', card)
                    has_moved = False
                    been_to_base = False
                    print "STATE: detected. waiting for go to base"
        else:
            if not has_moved:
                print "STATE: has moved. waiting for stable"
            has_moved = True
Esempio n. 3
0
	def calc_background_similarity(self):
		return min(ccoeff_normed(self.background_gray, frame) for frame in self.recent_frames_gray)
Esempio n. 4
0
def match_card(card, known_set, cache):
	mag, grad = gradient(card)
	phash = dct_hash(card)

	#fetch the twenty candidates with the lowest hamming distance on the phash
	#there's a 99% chance that the matching card is one of the first 20
	candidate_matches = sorted([
		(name, set_name, hamming_dist(h, phash))
		for name, set_name, h in known_set
	], key = lambda (n,s,dist): dist)
	#we want the first 20
	candidate_matches = candidate_matches[:20]

	#calculate the correlation score,
	#and also find the 'place' of each phash score
	#(multiple candidates can tie a phash score, so we rank by count of 
	#distances < our distance)
	candidate_scores= [
		(
			name, set_name,
			dist, len([d for _,_,d in candidate_matches if d < dist]),
			ccoeff_normed(grad, cache.getCard(set_name, name))
		) for name,set_name,dist in candidate_matches
	]

	#sort by score, and add a rank
	candidate_scores = sorted(candidate_scores,
			key = lambda (n,s,d,hr,ccoeff): ccoeff,
			reverse = True)
	norm_factor = 0 - candidate_scores[-1][4]
	total_score = sum([ccoeff + norm_factor for n,s,d,hr,ccoeff in candidate_scores])

	#for each score, compute the normaized features (- mean, / std_median)
	#for correlation, we want the share of normalized score
	features = [
		(
			name, set_name,
			(corr_rank - 9.5) / 5.766,
			(h_rank - 6.759942) / 4.522550,
			(dist - 17.374153) / 3.014411,
			(((corr + norm_factor) / total_score)- 0.050000) / 0.040183,
		) for corr_rank, (name, set_name, dist, h_rank, corr)
		in enumerate(candidate_scores)
	]

	#compute the score (based on fancy machine learning.)
	#todo: make more automatic and configurable
	scores = [
		(
			name, set_name,
			1.0 / (1 + math.e ** -(-6.48728 + 0.53659 * cr + -0.11304 * hr + -3.06121 * d + 2.94122 * corr))
		) for name, set_name, cr, hr, d, corr in features
	]

	#consider the scores in order
	scores = sorted(scores, key=lambda (n,s,score): score, reverse=True)

	#each score is a probability 0.0-1.0 of how likely it is that
	#that name, set_name is the correct card. we'll consider <= 0.50 a no
	# >= 0.60 a yes, and 0.5..0.6 a maybe (todo: adjust?)

	yes_cards = [(n, s) for n, s, score in scores if score >= 0.6]
	maybe_cards = [(n, s) for n, s, score in scores if 0.6 > score > 0.5]

	#if we have one or more 'yes' cards
	if len(yes_cards) > 0:
		#if they're all the same card...
		if len(set([n for n,s in yes_cards])) == 1:
			#then we're sure it's that card (unsure on set, but it's the same art, so hard to tell
			return (yes_cards[0], True)
	elif len(maybe_cards) > 0:
		#we have no 'yes' cards at all. if we have any maybe cards...
		#if they're all the same card
		if len(set([n for n,s in maybe_cards])) == 1:
			#it *could* be this card, but we're not confidant
			return (maybe_cards[0], False)

	#we can't really say what it is with any sort of confidence
	return (('',''),False)
Esempio n. 5
0
def match_card(card, known_set, cache):
	mag, grad = gradient(card)
	phash = dct_hash(card)

	#fetch the twenty candidates with the lowest hamming distance on the phash
	#there's a 99% chance that the matching card is one of the first 20
	candidate_matches = sorted([
		(name, set_name, hamming_dist(h, phash))
		for name, set_name, h in known_set
	], key = lambda (n,s,dist): dist)

	# Not even a chance, return
	if len(candidate_matches) is 0:
		return (('',''),False)

	#we want the first 20
	candidate_matches = candidate_matches[:20]

	#calculate the correlation score,
	#and also find the 'place' of each phash score
	#(multiple candidates can tie a phash score, so we rank by count of 
	#distances < our distance)
	candidate_scores= [
		(
			name, set_name,
			dist, len([d for _,_,d in candidate_matches if d < dist]),
			ccoeff_normed(grad, cache.getCard(set_name, name))
		) for name,set_name,dist in candidate_matches
	]
	'''
	print "candidate_scores"
	for name, set_name, dist, length, coef_norm in candidate_scores:
		print "\tname %s set_name %s dist %d length %d coef_nrom %d" % (name, set_name, dist, length, coef_norm)
	'''

	#sort by score, and add a rank
	candidate_scores = sorted(candidate_scores,
			key = lambda (n,s,d,hr,ccoeff): ccoeff,
			reverse = True)
	norm_factor = 0 - candidate_scores[-1][4]
	total_score = sum([ccoeff + norm_factor for n,s,d,hr,ccoeff in candidate_scores])

	#for each score, compute the normaized features (- mean, / std_median)
	#for correlation, we want the share of normalized score
	features = [
		(
			name, set_name,
			(corr_rank - 9.5) / 5.766,
			(h_rank - 6.759942) / 4.522550,
			(dist - 17.374153) / 3.014411,
			(((corr + norm_factor) / total_score)- 0.050000) / 0.040183,
		) for corr_rank, (name, set_name, dist, h_rank, corr)
		in enumerate(candidate_scores)
	]

	#compute the score (based on fancy machine learning.)
	#todo: make more automatic and configurable
	scores = [
		(
			name, set_name,
			1.0 / (1 + math.e ** -(-6.48728 + 0.53659 * cr + -0.11304 * hr + -3.06121 * d + 2.94122 * corr))
		) for name, set_name, cr, hr, d, corr in features
	]

	#consider the scores in order
	scores = sorted(scores, key=lambda (n,s,score): score, reverse=True)

	'''
	print "score"
	for name, set_name, score in scores:
		print "\tname %s set_name %s score %d" % (name, set_name, score)
	'''

	#each score is a probability 0.0-1.0 of how likely it is that
	#that name, set_name is the correct card. we'll consider <= 0.50 a no
	# >= 0.60 a yes, and 0.5..0.6 a maybe (todo: adjust?)

	yes_cards = [(n, s) for n, s, score in scores if score >= 0.6]
	maybe_cards = [(n, s) for n, s, score in scores if 0.6 > score > 0.5]

	'''
	print "maybe cards"
	for name, set_name in maybe_cards:
		print "\tname %s set_name %s" % (name, set_name)
	print "Done maybe"

	print "yes cards"
	for name, set_name in yes_cards:
		print "\tname %s set_name %s" % (name, set_name)
	print "Done maybe"
	'''

	#if we have one or more 'yes' cards
	if len(yes_cards) > 0:
		#if they're all the same card...
		if len(set([n for n,s in yes_cards])) == 1:
			#then we're sure it's that card (unsure on set, but it's the same art, so hard to tell
			return (yes_cards[0], True)
	elif len(maybe_cards) > 0:
		#we have no 'yes' cards at all. if we have any maybe cards...
		#if they're all the same card
		if len(set([n for n,s in maybe_cards])) == 1:
			#it *could* be this card, but we're not confidant
			return (maybe_cards[0], False)

	#we can't really say what it is with any sort of confidence
	return (('',''),False)