def filterMouse(cnts, last_center): """ Receives a set of countours and the last known position of the mouse and use a set of heuristics to choose the rat """ rx,ry,mouse = -1,-1,[] try: if len(cnts) == 0: raise MouseNotFound('Detection sees nothing!') #-------------------------------- #find the center that is the closest to the previous detection #-------------------------------- px,py = last_center centers = [jasf_cv.getCenterOfContour(c) for c in cnts] distances = [pointDistance(np.array(c) , np.array((px,py))) for c in centers] i = np.argmin(distances) rx,ry = centers[i] mouse = cnts[i] if pointDistance((rx,ry), (px,py)) > 80: print 'new center', rx,ry print 'previous center', px,py raise MouseNotFound('Closest center not close enough to previous position! Is this rat a ninja or what??') except MouseNotFound as E: print 'rat not found!' print E.reason return last_center[0], last_center[1], False return rx,ry,mouse
def pickCorrectContour(self, cnts, paramsDict): """ Receives a set of countours and the last known position of the mouse and use a set of heuristics to choose the rat """ rx, ry, mouse = -1, -1, [] last_center = paramsDict['last_center'] distanceRejectTh = paramsDict['distanceRejectTh'] try: if len(cnts) == 0: raise MouseNotFound('Detection sees nothing!') #-------------------------------- #find the center that is the closest to the previous detection #-------------------------------- px, py = last_center centers = [jasf_cv.getCenterOfContour(c) for c in cnts] distances = [ jasf.math.pointDistance(np.array(c), np.array((px, py))) for c in centers ] i = np.argmin(distances) rx, ry = centers[i] mouse = cnts[i] if jasf.math.pointDistance((rx, ry), (px, py)) > distanceRejectTh: print 'new center', rx, ry print 'previous center', px, py raise MouseNotFound( 'Closest center not close enough to previous position! Is this rat a ninja or what??' ) except MouseNotFound as E: print 'rat not found!\n', E.reason return last_center[0], last_center[1], False return rx, ry, mouse
def filterMouse(cnts, last_center): """ Receives a set of countours and the last known position of the mouse and use a set of heuristics to choose the rat """ rx,ry,mouse = -1,-1,[] try: if len(cnts) == 0: raise MouseNotFound('Detection sees nothing!') px,py = last_center centers = [jasf_cv.getCenterOfContour(c) for c in cnts] distances = [pointDistance(np.array(c) , np.array((px,py))) for c in centers] i = np.argmin(distances) rx,ry = centers[i] mouse = cnts[i] if pointDistance((rx,ry), (px,py)) > 80: print 'new center', rx,ry print 'previous center', px,py raise MouseNotFound('Closest center not close enough to previous position! Is this rat a ninja or what??') except MouseNotFound as E: print 'rat not found!' print E.reason return last_center[0], last_center[1], False return rx,ry,mouse
def analyseUserInput(x,y): """This function will be called in two cases: *by the next functoin *when there is some userInput stored from previous run This piece of code was refactored in order to be used in these two cases """ global control_mouse #compute center of current contours and their distances to the user click #'cnts' here will be set on the loop that is written after this function definition centers = [jasf_cv.getCenterOfContour(c) for c in cnts] distances = [np.linalg.norm(np.array(c) - np.array((x,y))) for c in centers] #the mouse is the one closest to the user click i = np.argmin(distances) rx,ry = centers[i] mouse = cnts[i] #the user cannot miss badly if jasf.math.pointDistance((rx,ry), (x,y)) > 20: print 'not close enough!' pass else: print 'position set!' control_mouse.setPosition(rx, ry, mouse) control_mouse.initialized = True #add user input to dictionary of user inputs userInputData[control_settings['currentVideoFileName']].append({'frame': readControlSetting('framesSinceStart'), 'input':(rx,ry), 'settings_state':readSettingsState()})
def initialize(img, th, th_max, otsu_th): """Find the countours on the first frame. If there are more than one, then we need help from the user to select which contour to track""" cnts = jasf_ratFinder.detectInterestingContours(img, th, th_max, otsu_th) cnts = cnts[0]#we don't need the other results for this if len(cnts) == 1: #if there is only one initial center, return it as the rat rx,ry =jasf_cv.getCenterOfContour(cnts[0]) return rx,ry, cnts[0] else: #if there are more, then we ask the user to help us global ratInitialized, mouse, rx, ry ratInitialized = False rx,ry = -1,-1 tkMessageBox.showinfo("Alert!", "We need you to inform the initial position of the rat! Please click on the rat on window 'initial position'") def getMousePosition(event, x, y, flags, param): """ mouse callback to set the rat position. This function gets the user press position and compare it with the known centers, picking the closest match""" global rx, ry, ratInitialized,mouse if event == cv2.EVENT_LBUTTONUP: print 'clicked on', x, y #compute center of current contours and their distances to the user click centers = [jasf_cv.getCenterOfContour(c) for c in cnts] distances = [np.linalg.norm(np.array(c) - np.array((x,y))) for c in centers] #the mouse is the one closest to the user click i = np.argmin(distances) rx,ry = centers[i] mouse = cnts[i] #the user cannot miss badly if pointDistance((rx,ry), (x,y)) > 20: print 'didnt work!' tkMessageBox.showinfo("Alert!", "The position clicked is not close enough to one of my centers!") else: print 'mouse set' ratInitialized = True #create window to display the current detection and assign the previous function #the deal with the user input cv2.namedWindow('initial position', cv2.WINDOW_KEEPRATIO) cv2.setMouseCallback('initial position', getMousePosition) while ratInitialized == False: #read thresholds th = cv2.getTrackbarPos('th', window_settings) th_max = cv2.getTrackbarPos('max', window_settings) #find contours cnts = jasf_ratFinder.detectInterestingContours(img, th, th_max, otsu_th) cnts = cnts[0]#we don't need the other outputs #draw img2show = myDrawContours(img, cnts) #show cv2.imshow('initial position', img2show) cv2.waitKey(5) cv2.destroyWindow('initial position') return rx, ry, mouse
def initialize(img, th, th_max): cnts = findRat(img, th, th_max) cnts = cnts[0] if len(cnts) == 1: #if there is only one initial center, return it as the rat rx,ry =jasf_cv.getCenterOfContour(cnts[0]) return rx,ry, cnts[0] else: #if there are more, then we ask the user to help us global ratInitialized, mouse, rx, ry ratInitialized = False rx,ry = -1,-1 tkMessageBox.showinfo("Alert!", "We need you to inform the initial position of the\ rat! Please click on the rat on window 'initial position'") def getMousePosition(event, x, y, flags, param): """ mouse callback to set the rat position. This function gets the user press position and compare it with the known centers, picking the closest match""" global rx, ry, ratInitialized,mouse if event == cv2.EVENT_LBUTTONUP: print 'clicked on', x, y centers = [jasf_cv.getCenterOfContour(c) for c in cnts] print len(centers) distances = [np.linalg.norm(np.array(c) - np.array((x,y))) for c in centers] i = np.argmin(distances) rx,ry = centers[i] mouse = cnts[i] if pointDistance((rx,ry), (x,y)) > 20: print 'didnt work!' tkMessageBox.showinfo("Alert!", "The position clicked is not close\ enough to one of my centers!") else: print 'mouse set' ratInitialized = True cv2.namedWindow('initial position', cv2.WINDOW_KEEPRATIO) cv2.setMouseCallback('initial position', getMousePosition) while ratInitialized == False: #read thresholds th = cv2.getTrackbarPos('th', window_settings) th_max = cv2.getTrackbarPos('max', window_settings) #find contours cnts = findRat(img, th, th_max) cnts = cnts[0] #draw img2show = myDrawContours(img, cnts) #show cv2.imshow('initial position', img2show) cv2.waitKey(5) cv2.destroyWindow('initial position') return rx, ry, mouse
def myDrawContours(output, cnts): output = cv2.cvtColor(output, cv2.COLOR_GRAY2BGR) cv2.drawContours(output, cnts, -1, (255,0,0), 2) for c in cnts: x,y,w,h = cv2.boundingRect(c) cv2.rectangle(output, (x,y), (x+w, y+h), (0,255,0), 2) rect = cv2.minAreaRect(c) box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(output, [box], 0, (0,0,255), 2) center = jasf_cv.getCenterOfContour(c) cv2.circle(output, center, 2, (0,0,255), 2) return output
def getMousePosition(event, x, y, flags, param): """ mouse callback to set the rat position. This function gets the user press position and compare it with the known centers, picking the closest match""" global rx, ry, ratInitialized,mouse if event == cv2.EVENT_LBUTTONUP: print 'clicked on', x, y centers = [jasf_cv.getCenterOfContour(c) for c in cnts] print len(centers) distances = [np.linalg.norm(np.array(c) - np.array((x,y))) for c in centers] i = np.argmin(distances) rx,ry = centers[i] mouse = cnts[i] if pointDistance((rx,ry), (x,y)) > 20: print 'didnt work!' tkMessageBox.showinfo("Alert!", "The position clicked is not close\ enough to one of my centers!") else: print 'mouse set' ratInitialized = True
def readParametersAndExecute(event): #read parameters from settings window settings = self.readSettingsParameters() th, th_max, area_delta, dilateSize, erodeSize = settings['th'], settings['max'], settings['delta'],\ settings['dilateSize'], settings['erodeSize'] #find contours self.contourFinder.setParams(dilateSize, erodeSize, th, th_max) cnts, otsu_threshold, filterSmall = self.contourFinder.detectInterestingContours(img) #draw all contours img2show = jasf_cv.drawContours(img, cnts) #show image with contours produced with the new parameters to the user self.GUI.setUserClickWindowImg(img2show) #ret val will be true if the user clicked on the screen pointRead, retVal = self.GUI.readUserInputClick() if retVal == False: return x,y = pointRead[0], pointRead[1] self.GUI.setClickWasRead() if len(cnts) == 0: self.GUI.log("the current parameters produce no contour! you need to tune it!") return #compute center of current contours centers = [jasf_cv.getCenterOfContour(c) for c in cnts] #compute distances from centers to user click distances = [jasf.math.pointDistance(np.array(c), np.array((x,y))) for c in centers] #find closes center i = np.argmin(distances) rx,ry = centers[i] mouse_cnt = cnts[i] #reject distant points if jasf.math.pointDistance((rx,ry), (x,y)) > 20: self.GUI.log('didnt work!') tkMessageBox.showinfo("Alert!", "The position clicked is not close enough to one of my centers!") else: #this is the case of sucessfull detection self.setMousePosition(rx, ry, mouse_cnt) self.GUI.log('mouse set') #by closing the window we proceed with the code self.GUI.setUserClick_Done()