class YoutubeTagger(Operator): def __init__(self, video_url, labelsPath): #super(YoutubeTagger, self).__init__() self.video_url = video_url #I guess I have to manually generate a video stream here... self.video_stream = VideoStream(self.video_url) self.video_stream = iter(self.video_stream) self.width = self.video_stream.width self.height = self.video_stream.height self.labelsPath = labelsPath self.csvDict = self.getAllYTTags() # subscripting binds a transformation to the current stream def apply(self, vstream): self.video_stream = vstream return self def __getitem__(self, xform): """Applies a transformation to the video stream """ return xform.apply(self) def getAllYTTags(self): fd = open(self.labelsPath, 'r') labelReader = csv.reader(fd) outputDict = dict() for i, row in enumerate(labelReader): if (i == 0): #skip the header--we'll assume we know what it is continue else: frInfo = self.toFrameInfo(row) youtubeID = frInfo.youtubeID if youtubeID in outputDict: lstOfFrameInfos = outputDict[youtubeID] lstOfFrameInfos.append(frInfo) outputDict[youtubeID] = lstOfFrameInfos else: nlst = [frInfo] outputDict[youtubeID] = nlst fd.close() #sort by frame_no for key in outputDict: lstOfFrameInfos = outputDict[key] lstOfFrameInfos = sorted(lstOfFrameInfos, key=lambda x: x.frame_no) outputDict[key] = lstOfFrameInfos return outputDict def toFrameInfo(self, row): # on my laptop, the to_csv function in pandas generates columns in alphabetical order youtubeID = row[0] sec_no = float(row[1]) fps = int(row[2]) frame_no = int(row[3]) obj_type = row[4] xmin = float(row[5]) xmin = xmin * self.width xmax = float(row[6]) xmax = xmax * self.width ymin = float(row[7]) ymin = ymin * self.height ymax = float(row[8]) ymax = ymax * self.height return FrameInfo(youtubeID, sec_no, fps, frame_no, obj_type, xmin, xmax, ymin, ymax) # youtubeID = row[8] # sec_no = float(row[3]) # fps = int(row[1]) # frame_no = int(row[2]) # obj_type = row[0] # xmin = float(row[5]) # xmin = xmin * self.width # xmax = float(row[4]) # xmax = xmax * self.width # ymin = float(row[7]) # ymin = ymin * self.height # ymax = float(row[6]) # ymax = ymax * self.height # return FrameInfo(youtubeID, sec_no, fps, frame_no, obj_type, xmin, xmax, ymin, ymax) def __iter__(self): self.input_iter = iter(self.video_stream) #self.super_iter() return self def parseID(self): head_tail = os.path.split(self.video_url) fname = head_tail[1] if len(fname) < 5: raise Exception( "Format error: expecting a file name with an extension") return fname[:-4] def _get_tag(self, frame_count): res_tag = {'objects': []} videoID = self.parseID() labelLst = self.csvDict[videoID] #we can switch to binary search later... for l in labelLst: if frame_count <= l.frame_no: res_tag = { 'objects': [{ 'label': l.getLabel(), 'bb': l.getBox() }] } return res_tag return res_tag def __next__(self): frame_count = self.video_stream.__next__()['frame'] return self._get_tag(frame_count)
class YoutubeTagger(Operator): def __init__(self, video_url, labelsPath): #super(YoutubeTagger, self).__init__() self.video_url = video_url #I guess I have to manually generate a video stream here... self.video_stream = VideoStream(self.video_url) self.video_stream = iter(self.video_stream) self.width = self.video_stream.width self.height = self.video_stream.height self.labelsPath = labelsPath self.csvDict = self.getAllYTTags() # subscripting binds a transformation to the current stream def apply(self, vstream): self.video_stream = vstream return self def __getitem__(self, xform): """Applies a transformation to the video stream """ return xform.apply(self) def getAllYTTags(self): label_local = True try: fd = open(self.labelsPath, 'r') except FileNotFoundError: label_local = False url = self.labelsPath response = urllib.request.urlopen(url) fd = [l.decode('utf-8') for l in response.readlines()] labelReader = csv.reader(fd) outputDict = dict() for i,row in enumerate(labelReader): if (i== 0): #skip the header--we'll assume we know what it is continue else: frInfo = self.toFrameInfo(row) youtubeID = frInfo.youtubeID if youtubeID in outputDict: lstOfFrameInfos = outputDict[youtubeID] lstOfFrameInfos.append(frInfo) outputDict[youtubeID] = lstOfFrameInfos else: nlst = [frInfo] outputDict[youtubeID] = nlst if label_local: fd.close() #sort by frame_no for key in outputDict: lstOfFrameInfos = outputDict[key] lstOfFrameInfos = sorted(lstOfFrameInfos, key=lambda x: x.frame_no) outputDict[key] = lstOfFrameInfos return outputDict def toFrameInfo(self, row): # on my laptop, the to_csv function in pandas generates columns in alphabetical order youtubeID = row[0] sec_no = float(row[1]) fps = int(row[2]) frame_no = int(row[3]) obj_type = row[4] xmin = float(row[5]) xmin = xmin * self.width xmax = float(row[6]) xmax = xmax * self.width ymin = float(row[7]) ymin = ymin * self.height ymax = float(row[8]) ymax = ymax * self.height return FrameInfo(youtubeID, sec_no, fps, frame_no, obj_type, xmin, xmax, ymin, ymax) # youtubeID = row[8] # sec_no = float(row[3]) # fps = int(row[1]) # frame_no = int(row[2]) # obj_type = row[0] # xmin = float(row[5]) # xmin = xmin * self.width # xmax = float(row[4]) # xmax = xmax * self.width # ymin = float(row[7]) # ymin = ymin * self.height # ymax = float(row[6]) # ymax = ymax * self.height # return FrameInfo(youtubeID, sec_no, fps, frame_no, obj_type, xmin, xmax, ymin, ymax) def __iter__(self): self.input_iter = iter(self.video_stream) self.super_iter() return self def parseID(self): head_tail = os.path.split(self.video_url) fname = head_tail[1] if len(fname) < 5: raise Exception("Format error: expecting a file name with an extension") return fname[:-4] def _get_tag(self, frame_count): res_tag = {'objects': []} videoID = self.parseID() labelLst = self.csvDict[videoID] #we can switch to binary search later... for l in labelLst: if frame_count <= l.frame_no: res_tag = {'objects': [{'label' : l.getLabel(), 'bb' : l.getBox()}]} return res_tag return res_tag def __next__(self): frame_count = self.video_stream.__next__()['frame'] return self._get_tag(frame_count) # class YoutubeTagger(Operator): # def __init__(self, video_url, batch_size, labelsPath): # super(YoutubeTagger, self).__init__() # self.video_url = video_url # self.batch_size = batch_size # self.row_count = 0 # self.next_count = 0 # #get the open file descriptor for reading the label/bb info # self.fd = open(labelsPath, 'r') # self.labelReader = csv.reader(self.fd) # #throw away the header # header = self.labelReader.next() # row1 = self.labelReader.next() # info1 = self.toFrameInfo(row1) # self.cur_frame = 0 #video frame counter # self.cur_info = info1 # self.prev_info = info1 # def __iter__(self): # self.input_iter = iter(self.video_stream) # self.super_iter() # return self # def _get_tags(self): # if self.next_count == 0 or self.next_count >= self.batch_size: # self.next_count = 0 # # we assume it iterates the entire batch size and save the results # self.tags = [] # try: # cur_tags = self.youtubeTag() # except StopIteration: # raise StopIteration("Iterator is closed") # self.tags += cur_tags # self.next_count += 1 # return self.tags # def __next__(self): # return {'objects' : self._get_tags()} # def toFrameInfo(self, row): # youtubeID = row[0] # sec_no = row[1] # fps = row[2] # frame_no = row[3] # obj_type = row[4] # xmin = float(row[5]) # xmax = float(row[6]) # ymin = float(row[7]) # ymax = float(row[8]) # return FrameInfo(youtubeID, sec_no, fps, frame_no, obj_type, xmin, xmax, ymax, ymin) # def youtubeTag(self): # res_tags = [] # count = 0 # for frame in self.input_iter: # vid_name = self.cur_info.youtubeID + '.mp4' # if not vid_name in self.video_url: # tmp_info = FrameInfo() # while (not vid_name in self.video_url): # try: # row = self.labelReader.next() # tmp_info = self.toFrameInfo(row) # vid_name = self.tmp_info.youtubeID + '.mp4' # except StopIteration: # #we must have all the tags we need... # return res_tags # self.cur_info = tmp_info # self.prev_info = copy.deepcopy(tmp_info) # if self.cur_frame == self.cur_info.frame_no: # new_tag = [{'label' : self.cur_info.getLabel(), 'bb' : self.cur_info.getBox()}] # res_tags.append(new_tag) # self.prev_info = copy.deepcopy(self.cur_info) # self.cur_info = self.toFrameInfo(self.labelReader.next()) # elif self.cur_frame < self.cur_info.frame_no: # new_tag = [{'label' : self.prev_info.getLabel(), 'bb' : self.prev_info.getBox()}] # res_tags.append(new_tag) # elif self.cur_frame > self.cur_info.frame_no: # #catch the frame info up to the right frame number # tmp_info = self.cur_info # p_info = self.cur_info # r_cnt = 0 # for row in self.labelReader: # p_info = copy.deepcopy(tmp_info) # tmp_info = self.toFrameInfo(row) # vid_name = self.tmp_info.youtubeID + '.mp4' # if self.cur_frame <= tmp_info.frame_no and vid_name in self.video_url: # #the iterator over labelReader is now at the right spot, so stop # self.cur_info = tmp_info # self.prev_info = p_info # break # r_cnt += 1 # if r_cnt == 0: # #just copy the latest frame info for the rest of the frames # new_tag = [{'label' : self.cur_info.getLabel(), 'bb' : self.cur_info.getBox()}] # res_tags.append(new_tag) # self.cur_frame += 1 #again, there might be an off-by-one error here # count+= 1 # if count >= self.batch_size: # break # if count == 0: # raise StopIteration("Iterator is closed") # return res_tags # def youtubeTag(path, output): # fullpath = path + output # fh = open(fullpath, 'r') # csvreader = csv.reader(fh) # outputDict = dict() # for i,row in enumerate(csvreader): # if (i== 0): #skip the header--we'll assume we know what it is # continue # else: # youtubeID = row[0] # sec_no = row[1] # fps = row[2] # frame_no = row[3] # obj_type = row[4] # xmin = row[5] # xmax = row[6] # ymin = row[7] # ymax = row[8] # frInfo = FrameInfo(sec_no, fps, frame_no, obj_type, xmin, xmax, ymin, ymax) # if youtubeID in outputDict: # lstOfFrameInfos = outputDict[youtubeID] # lstOfFrameInfos.append(frInfo) # outputDict[youtubeID] = lstOfFrameInfos # else: # nlst = [frInfo] # outputDict[youtubeID] = nlst # fh.close() # for yid in outputDict: # outputDict[yid]