def onSave(self, event): nfHPM = 0 # number of frames in which head position is missing nfHDM = 0 # number of frames in which head direction is missing fp_ = self.fPath + '.csv' fh = open(fp_, 'w') fh.write('frame-index, hPosX, hPosY, mHPos, bPosX, bPosY, hDir, mHD\n') for fi in range(1, self.frame_cnt + 1): d_ = self.oData[fi] if d_['hPos'] == ('None', 'None') or d_['hPos'] == ('D', 'D'): nfHPM += 1 # head position is missing if type(d_['hD']) != int: nfHDM += 1 # head direction is missing line = '%i, %s, %s, %s, %s, %s, %s, %s\n' % (fi, str( d_['hPos'][0]), str(d_['hPos'][1]), str( d_['mHPos']), str(d_['bPos'][0]), str( d_['bPos'][1]), str(d_['hD']), str(d_['mHD'])) fh.write(line) fh.write( '------------------------------------------------------------------\n' ) fh.write('Number of frames in which head position is missing, %i\n' % nfHPM) fh.write('Number of frames in which head direction is missing, %i\n' % nfHDM) fh.close() msg = 'Saved.\n' chr_num = 50 # characters in one line if len(fp_) > chr_num: for i in range(len(fp_) / chr_num): msg += '%s\n' % (fp_[chr_num * i:chr_num * (i + 1)]) msg += '%s\n' % (fp_[chr_num * (i + 1):]) show_msg(msg, size=(400, 200))
def onSave(self, event): WD = 0 # walking distance HM = 0 # head movements without walking (~ looking around) nfH = 0 # number of frames when only head tag is detected nfT = 0 # number of frames when only tail tag is detected nfB = 0 # number of frames when only both tags are detected nfN = 0 # number of frames when only no tags were detected fp_ = self.fPath + '.csv' fh = open(fp_, 'w') fh.write('frame-index, hPosX, hPosY, tbPosX, tbPosY, WD, HM, h2ac_dist\n') hsf = self.vFPS/2 # half second frames for fi in range(1, self.frame_cnt+1): h_ = self.oData[fi]['hPos'] t_ = self.oData[fi]['tbPos'] if type(h_[0]) == int and type(t_[0]) == int: nfB += 1 elif type(h_[0]) == int and type(t_[0]) != int: nfH += 1 elif type(h_[0]) != int and type(t_[0]) == int: nfT += 1 elif type(h_[0]) != int and type(t_[0]) != int: nfN += 1 wd_ = 0; hm_ = 0 if fi > (hsf) and fi % hsf == 0: ### every half second, calculate walking-distance and head-movement ph_ = self.oData[fi-hsf]['hPos'] pt_ = self.oData[fi-hsf]['tbPos'] if type(h_[0])==int and type(h_[1])==int and type(ph_[0])==int and type(ph_[1])==int: # all the head position info available hl = np.sqrt( (h_[0]-ph_[0])**2 + (h_[1]-ph_[1])**2 ) # line connecting two head tag positions if hl > (self.tagSz/2): # if movement distance is too small, discard if type(t_[0])==int and type(t_[1])==int and type(pt_[0])==int and type(pt_[1])==int: # all the tail position info available hla = np.degrees(np.arctan2( (h_[1]-ph_[1]), (h_[0]-ph_[0]) )) # degree of line connecting two head tag positions tla = np.degrees(np.arctan2( (t_[1]-pt_[1]), (t_[0]-pt_[0]) )) # degree of line connecting two tail tag positions angle_diff = calc_angle_diff(hla, tla) if angle_diff < 45: # 45 degrees difference is considered as more or less similar direction to account it as 'walking' wd_ = hl # walking distance for one frame WD += hl # total walking distance if wd_ == 0: # if walking didn't happen, hl is recorded as head movement hm_ = hl HM += hl line = '%i, %s, %s, %s, %s, %i, %i, %s\n'%(fi, str(h_[0]), str(h_[1]), str(t_[0]), str(t_[1]), wd_, hm_, str(self.oData[fi]['h2ac_dist'])) fh.write(line) fh.write('------------------------------------------------------------------\n') fh.write('Total walking distance, %i\n'%WD) fh.write('Total head movements without walking, %i\n'%HM) fh.write('------------------------------------------------------------------\n') fh.write('Number of frames when both tags are detected, %i\n'%nfB) fh.write('Number of frames when only head tag is detected, %i\n'%nfH) fh.write('Number of frames when only tail tag is detected, %i\n'%nfT) fh.write('Number of frames when no tags are detected, %i\n'%nfN) fh.close() msg = 'Saved.\n' chr_num = 50 # characters in one line if len(fp_) > chr_num: for i in range(len(fp_)/chr_num): msg += '%s\n'%(fp_[chr_num*i:chr_num*(i+1)]) msg += '%s\n'%(fp_[chr_num*(i+1):]) show_msg(msg, size=(400,200))
def start_arduino(self): if DEBUG: print('CATOSFrame.start_arduino()') self.mods["arduino"] = Arduino(self, self.output_folder) if self.mods["arduino"].aConn == None: return # !!! remove for actual setup. This is for testing purpose. msg = "Arduino chip is not found.\nPlease connect it and retry." show_msg(msg, self.panel) self.onClose(None) writeFile(self.log_file_path, "%s, [CATOS], arduino mod init.\n" % (get_time_stamp()))
def onClose(self, event): self.timer.Stop() result = True if self.session_start_time != -1: # session is running result = show_msg(msg='Session is not stopped..\nUnsaved data will be lost. (Stop analysis or Cmd+S to save.)\nOkay to proceed to exit?', cancel_btn = True) if result == True: if self.cv_proc.video_rec != None: self.cv_proc.stop_video_rec() wx.FutureCall(500, self.Destroy)
def start_arduino(self): self.mods["arduino"] = Arduino(self, self.output_folder) if self.mods["arduino"].aConn == None: show_msg('Arduino chip is not found.\nPlease connect it and retry.', self.panel) self.onClose(None) writeFile(self.log_file_path, '%s, [CATOS], arduino mod init.\n'%(get_time_stamp()))
def onStartStopAnalyzeVideo(self, event): '''Choose a video file and starts analysis''' if self.session_start_time == -1: # not in analysis session. start a session dlg = wx.DirDialog(self, "Choose directory for analysis", getcwd(), wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST) if dlg.ShowModal() == wx.ID_CANCEL: return self.fPath = dlg.GetPath() self.frame_cnt = len(glob(path.join(self.fPath, 'f*.jpg'))) if self.frame_cnt == 0: show_msg('No jpg frame images in the chosen directory.') self.fPath = '' return if path.isfile(path.join(self.fPath, 'bg.jpg')) == False: show_msg( msg="'bg.jpg' file is not found in the chosen directory.", cancel_btn=False) return self.cv_proc.bg = load_img(path.join(self.fPath, 'bg.jpg'), flag='cv') # load background image self.cv_proc.bg = self.onLoadImg(self.cv_proc.bg) self.onChangeAnimalSp(None) # set default parameters of cv_proc self.sTxt_fp.SetLabel('%s' % (path.basename(self.fPath))) result_csv_file = self.fPath + '.csv' if path.isfile( result_csv_file) == False: # result CSV file doesn't exist for i in range(1, self.frame_cnt + 1): self.oData[i] = dict( hPos=('None', 'None'), mHPos=False, bPos=('None', 'None'), hD='None', mHD=False ) # head position, head position was manually determined, base of head(around nect), head direction, head direction was manually determined else: # result CSV file exists f = open(result_csv_file, 'r') lines = f.readlines() f.close() for i in range(1, self.frame_cnt + 1): self.oData[i] = dict(hPos=('None', 'None'), mHPos=False, bPos=('None', 'None'), hD='None', mHD=False) if i < len(lines): items = [x.strip() for x in lines[i].split(',')] idx_ = int(items[0]) if items[1] == 'None': hPos_val = ('None', 'None') elif items[1] == 'D': hPos_val = ('D', 'D') else: hPos_val = (int(items[1]), int(items[2])) if items[3] == 'True': mHPos_val = True else: mHPos_val = False if items[4] == 'None': bPos_val = ('None', 'None') elif items[4] == 'D': bPos_val = ('D', 'D') else: bPos_val = (int(items[4]), int(items[5])) if items[6] == 'None': hD_val = 'None' elif items[6] == 'D': hD_val = 'D' else: hD_val = int(items[6]) if items[7] == 'True': mHD_val = True else: mHD_val = False self.oData[idx_]['hPos'] = copy(hPos_val) self.oData[idx_]['mHPos'] = copy(mHPos_val) self.oData[idx_]['bPos'] = copy(bPos_val) self.oData[idx_]['hD'] = copy(hD_val) self.oData[idx_]['mHD'] = copy(mHD_val) self.fi = 1 self.session_start_time = time() self.btn_start.SetLabel('Stop analysis') ### start video recorder self.video_path = self.fPath + '.avi' fp = path.join(self.fPath, self.filenames % self.fi) img = load_img(fp, flag='cv') img = self.onLoadImg(img) self.cv_proc.start_video_rec(self.video_path, img) self.proc_img() # process 1st image else: # in session. stop it. result = show_msg(msg='Save data?', cancel_btn=True) if result == True: self.onSave(None) if self.is_running == True: self.onSpace(None) self.session_start_time = -1 self.sTxt_s_time.SetLabel('0:00:00') self.btn_start.SetLabel('Analyze video (folder)') self.sTxt_fp.SetLabel('') self.loaded_img.SetBitmap(wx.NullBitmap) self.fPath = '' self.frame_cnt = 0 self.fi = 0 self.oData = {} self.cv_proc.stop_video_rec()
def onStartStopAnalyzeVideo(self, event): '''Choose a video file and starts analysis''' if self.session_start_time == -1: # not in analysis session. start a session dlg = wx.DirDialog(self, "Choose directory for analysis", getcwd(), wx.DD_DEFAULT_STYLE|wx.DD_DIR_MUST_EXIST) if dlg.ShowModal() == wx.ID_CANCEL: return self.fPath = dlg.GetPath() self.sString = self.fPath[-8:] self.frame_cnt = len(glob(path.join(self.fPath, '*.jpg'))) if self.frame_cnt == 0: show_msg('No jpg frame images in the chosen directory.') self.fPath = '' return fNames = self.fPath.split('/') self.sTxt_fp.SetLabel( '%s / %s / %s / %s'%(fNames[-4],fNames[-3],fNames[-2],fNames[-1]) ) result_csv_file = self.fPath + '.csv' if path.isfile(result_csv_file) == False: # result CSV file doesn't exist for i in range(1, self.frame_cnt+1): self.oData[i] = dict( hPos = (None,None), tbPos = (None,None), h2ac_dist = None ) # hPos: head tag position, # tbPos: tail-base tag position, # h2ac_dist: distance from the head tag to the arena center else: # result CSV file exists f = open(result_csv_file, 'r') lines = f.readlines() f.close() for i in range(1, self.frame_cnt+1): self.oData[i] = dict( hPos = (None,None), tbPos = (None,None), h2ac_dist = None ) if i < len(lines): items = [ x.strip() for x in lines[i].split(',') ] idx_ = int(items[0]) if items[1] == 'None': hPos_val = (None, None) elif items[1] == 'D': hPos_val = ('D', 'D') else: hPos_val = ( int(items[1]), int(items[2]) ) if items[3] == 'None': tbPos_val = (None, None) elif items[3] == 'D': tbPos_val = ('D', 'D') else: tbPos_val = ( int(items[3]), int(items[4]) ) if items[7] == 'None': h2ac_dist_val = None else: h2ac_dist_val = int(items[7]) self.oData[idx_]['hPos'] = copy(hPos_val) self.oData[idx_]['tbPos'] = copy(tbPos_val) self.oData[idx_]['h2ac_dist'] = copy(h2ac_dist_val) self.fi = 1 self.session_start_time = time() self.btn_start.SetLabel('Stop analysis') ### start video recorder self.video_path = self.fPath + '.avi' fp = path.join(self.fPath, 'f%06i.jpg'%self.fi) img = load_img(fp, flag='cv') self.cv_proc.start_video_rec( self.video_path, img ) self.proc_img() # process 1st image else: # in session. stop it. result = show_msg(msg='Save data?', cancel_btn = True) if result == True: self.onSave(None) if self.is_running == True: self.onSpace(None) self.session_start_time = -1 self.sTxt_s_time.SetLabel('0:00:00') self.btn_start.SetLabel('Analyze video (folder)') self.sTxt_fp.SetLabel('') self.loaded_img.SetBitmap(wx.NullBitmap) self.fPath = '' self.sString = '' self.frame_cnt = 0 self.fi = 0 self.oData = {} self.cv_proc.stop_video_rec()