From e741278d1a9e8426a84c9bae7f9b0cfbe9444be8 Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Tue, 18 Jan 2022 03:46:21 +0900 Subject: [PATCH] simultaneous tracking (player and pokemon) support added --- src/rngtool.py | 136 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 117 insertions(+), 19 deletions(-) diff --git a/src/rngtool.py b/src/rngtool.py index 4cfffa0..0d95155 100644 --- a/src/rngtool.py +++ b/src/rngtool.py @@ -7,6 +7,7 @@ import time import cv2 from xorshift import Xorshift import calc +from collections import Counter IDLE = 0xFF SINGLE = 0xF0 @@ -20,7 +21,7 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40)->Tuple[ """measuring the type and interval of player's blinks Returns: - blinks:List[int],intervals:list[int],offset_time:float: [description] + blinks:List[int], intervals:list[int], offset_time:float """ eye = img @@ -40,7 +41,7 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40)->Tuple[ offset_time = 0 - # 瞬きの観測 + # observe blinks while len(blinks)Tuple[ if 0.01Tuple[ cv2.destroyAllWindows() return (blinks, intervals, offset_time) -def tracking_poke_blink(img, roi_x, roi_y, roi_w, roi_h, size = 60)->Tuple[List[int],List[int],float]: - """measuring the type and interval of pokemon's blinks +def tracking_poke_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.85, size = 60)->Tuple[List[int],List[int],float]: + """measuring the interval of pokemon's blinks Returns: intervals:list[int],offset_time:float: [description] @@ -106,7 +107,7 @@ def tracking_poke_blink(img, roi_x, roi_y, roi_w, roi_h, size = 60)->Tuple[List[ prev_time = time.perf_counter() - # 瞬きの観測 + # observe blinks while len(intervals)Tuple[List[ if (roi==prev_roi).all(): continue prev_roi = roi - cv2.imshow("",roi) + cv2.imshow("",cv2.resize(roi, (roi_w*2, roi_h*2))) cv2.waitKey(1) res = cv2.matchTemplate(roi,eye,cv2.TM_CCOEFF_NORMED) _, match, _, _ = cv2.minMaxLoc(res) - if 0.4Tuple[List[ video.release() return intervals +def simultaneous_tracking(plimg, plroi:Tuple[int,int,int,int], pkimg, pkroi:Tuple[int,int,int,int], plth=0.88, pkth=0.999185, size=8)->Tuple[List[int],List[int],float]: + """measuring type/intervals of player's blinks and the interval of pokemon's blinks + note: this methods is very unstable. it not recommended to use. + Returns: + intervals:list[int],offset_time:float: [description] + """ + video = cv2.VideoCapture(0,cv2.CAP_DSHOW) + video.set(cv2.CAP_PROP_FRAME_WIDTH,1920) + video.set(cv2.CAP_PROP_FRAME_HEIGHT,1080) + video.set(cv2.CAP_PROP_BUFFERSIZE,1) + + pl_state = IDLE + pk_state = IDLE + blinks = [] + intervals = [] + pl_prev = time.perf_counter() + pk_prev = time.perf_counter() + + prev_roi = None + debug_txt = "" + + offset_time = 0 + + blinkcounter = 0 + + # observe blinks + while len(blinks)0.3: + blinks[-1] = 1 + debug_txt = debug_txt+"d" + pl_state = DOUBLE + elif pl_state==DOUBLE: + pass + + if pl_state!=IDLE and time_counter - pl_prev>0.7: + pl_state = IDLE + print(debug_txt, len(blinks)) + + if pk_state==IDLE: + #poke eye + roi_x,roi_y,roi_w,roi_h = pkroi + roi = cv2.cvtColor(frame[roi_y:roi_y+roi_h,roi_x:roi_x+roi_w],cv2.COLOR_RGB2GRAY) + + res = cv2.matchTemplate(roi,pkimg,cv2.TM_CCORR_NORMED)#CCORR might be better? + _, match, _, _ = cv2.minMaxLoc(res) + cv2.imshow("pk",roi) + cv2.waitKey(1) + if 0.40.7: + pk_state = IDLE + + cv2.destroyAllWindows() + print(intervals) + return (blinks, intervals, offset_time) + def recov(blinks:List[int],rawintervals:List[int])->Xorshift: """ Recover the xorshift from the type and interval of blinks. @@ -165,7 +260,7 @@ def recov(blinks:List[int],rawintervals:List[int])->Xorshift: return result def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_max=10**6, search_min=0)->Xorshift: - """reidentify Xorshift state by type of observed blinks. + """reidentify Xorshift state by the type of observed blinks. Args: rng (Xorshift): identified rng @@ -223,13 +318,13 @@ def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_ return None -def reidentifyByIntervals(rng:Xorshift, rawintervals:List[int], npc = 0, search_max=10**6, search_min=0)->Xorshift: +def reidentifyByIntervals(rng:Xorshift, rawintervals:List[int], npc = 0, th = 0, search_max=10**6, search_min=0)->Xorshift: """reidentify Xorshift state by intervals of observed blinks. This method is faster than "reidentifyByBlinks" in most cases since it can be reidentified by less blinking. Args: rng (Xorshift): [description] - rawintervals (List[int]): list of intervals of blinks. 6 or more is recommended. + rawintervals (List[int]): list of intervals of blinks. 7 or more are recommended. npc (int, optional): [description]. Defaults to 0. search_max ([type], optional): [description]. Defaults to 10**6. search_min (int, optional): [description]. Defaults to 0. @@ -248,9 +343,6 @@ def reidentifyByIntervals(rng:Xorshift, rawintervals:List[int], npc = 0, search_ blinkrands = [(i, int((r&0b1110)==0)) for i,r in list(enumerate(identify_rng.getNextRandSequence(search_max)))[d::1+npc]] #prepare - - - expected_blinks_lst = [] expected_blinks = 0 lastblink_idx = -1 @@ -280,15 +372,21 @@ def reidentifyByIntervals(rng:Xorshift, rawintervals:List[int], npc = 0, search_ #search result = Xorshift(*rng.getState()) + distlst = [] for idx, blinks in expected_blinks_lst: - if search_blinks==blinks and search_min <= idx: - print(f"found at advances:{idx}, d={d}") + #check by hamming distance + distance = bin(search_blinks^blinks).count("1") + distlst.append(distance) + isSame = distance<=th + if isSame and search_min <= idx: + print(f"found at advances:{idx}, d={d}, hamming={distance}") result.getNextRandSequence(idx) return result + c = Counter(distlst) + print(sorted(c.items())) return None - def recovByMunchlax(rawintervals:List[float])->Xorshift: """Recover the xorshift from the interval of Munchlax blinks. @@ -299,8 +397,8 @@ def recovByMunchlax(rawintervals:List[float])->Xorshift: Xorshift: [description] """ advances = len(rawintervals) - intervals = [interval+0.048 for interval in rawintervals]#観測結果のずれを補正 - intervals = intervals[1:]#最初の観測結果はノイズなのでそれ以降を使う + intervals = [interval+0.048 for interval in rawintervals]#Corrects for delays in observation results + intervals = intervals[1:]#The first observation is noise, so we use the one after that. states = calc.reverseStatesByMunchlax(intervals) prng = Xorshift(*states)