def cheetah_render(content, params): return CTemplate(content, searchList=[params]).respond()
def _generate_attributes(self, video_file, video_work_dir): """ Run actual sun_attributes code on video, outputting a file that is the concatenation of frame feature products (checkpoint file) and returning the resultant matrix. The output file will be a numpy binary file storing a 2D array object. If the output file already exists, we will assume that the work as already been completed and will load and return that file's matrix. :raises RuntimeError: Couldn't create raw scores due to error in runtime. This can either be due to frame extraction failure or failure at running the SUN attributes executable. :param video_file: Video for processing :type video_file: str :param video_work_dir: Directory to store work in :type video_work_dir: str :return: 2D numpy array object that is the combined frame feature vectors, or attribute scores. If None is returned, that means scores couldn't be produced on this video. :rtype: numpy.ndarray """ # video frame extraction # # extracting jpb because the MATLAB code only works with jpg files # apparently... # # exiting failure if no frames extracted. # frame2img, _ = self.mp4_extract_video_frames(video_file, 'jpg') # run output vars f_result_output_dir = osp.join(video_work_dir, 'frame_results') self.create_dir(f_result_output_dir) output_files = {} tmp_output_files = {} # tmp version of output_files map of_not_present = [] # frames for which no non-temp output present # Predict output files we will need for images specified/produced # If one or more of the predicted output files doesn't exist in # their predicted location, queue it to be processed. for frame, img_file in sorted(frame2img.items()): output_files[frame] = osp.join(f_result_output_dir, 'frm%06d.features' % frame) tmp_output_files[frame] = \ self.tempify_filename(output_files[frame]) if not osp.isfile(output_files[frame]): of_not_present.append(frame) # Only create a work file and process if anything actually needs to # be processed if of_not_present: # remove old temp files if present (i don't know what the MATLAB # code might do with a partially written file, i.e. if it will # append to it or not) self._log.debug("removing pre-existing temp frame work files") for f in tmp_output_files.values(): if osp.isfile(f): os.remove(f) # Create actual work file, overwriting any that might already be # present. work_file = osp.join(video_work_dir, 'sa_work_file.txt') with open(work_file, 'w') as wfile: for frame in of_not_present: wfile.write("%s,%s\n" % (frame2img[frame], tmp_output_files[frame])) # Generating configuration file from template, overwriting an # existing one if present (things may be different). config_file = osp.join(video_work_dir, 'sa_config.xml') sa_tmp_folder = \ self.create_dir(osp.join(video_work_dir, 'sa_tmp')) sl = {'sa_src_dir': self._sa_src_dir, 'working_dir': sa_tmp_folder} with open(config_file, 'w') as cfile: cfile.write(str(CTemplate(file=self._config_tmpl, searchList=sl))) run_args = [self._sa_runner, self._mcr_root, work_file, config_file] self._log.debug("call: %s", ' '.join(run_args)) log_file = osp.join(video_work_dir, 'last_run.log') with open(log_file, 'w') as lf: # MATLAB is known to rarely timeout indefinitely. Using ex start = time.time() p = subprocess.Popen(run_args, stdout=lf, stderr=lf) while p.poll() is None: # check if timeout exceeded, kicking the bucket if so if (time.time() - start) > self._matlab_run_timeout_seconds: p.terminate() raise RuntimeError( "MATLAB processing exceeded configured timeout " "(%.1f minutes). Check run log file for possible " "details as to why: %s", self._matlab_run_timeout_seconds / 60.0, log_file ) time.sleep(self._timeout_poll_interval) if p.returncode != 0: raise RuntimeError("Failed to process sun_attributes " "for video %s with return code %s. " "Check log file: %s" % (video_file, str(p.returncode), log_file)) # Run successful, check that configured tmp files exist and # rename them to the official output names. for frame in of_not_present: if not osp.isfile(tmp_output_files[frame]): raise RuntimeError("sun_attributes failed to produce " "output for requested frame %d. " "Check that it is actually present " "in the generated work file (%s) " "as well as check the log file (%s)." % (frame, work_file, log_file)) os.rename(tmp_output_files[frame], output_files[frame]) # Remove temp work files generated by sun_attributes self._log.debug("removing sa temp working directory") shutil.rmtree(sa_tmp_folder) ### # Combination # # First, need to construct the combined matrix, which is just each # frame's results stacked from top to bottom in frame order. # self._log.debug("creating raw combined features matrix") combined_matrix = [] for frm, features_file in sorted(output_files.items()): self._log.debug("-> adding frame %d : %s", frm, features_file) combined_matrix.append(np.loadtxt(features_file)) combined_matrix = np.array(combined_matrix) # make 2D array of list return combined_matrix