def load_serialized(filename_with_path): """ load a serialized model """ if not os.path.isfile(filename_with_path): print( "{} is not a valid file, please check".format(filename_with_path)) return feature_selection_filename = filename_with_path.replace( "_reg.json", "_fs.json") feature_selection = None if os.path.isfile(feature_selection_filename): feature_selection = json_load(feature_selection_filename) regressor = skljson.from_json(filename_with_path) # override n_jobs to prevent warning, model should be fast enough # n_jobs helps during training regressor.n_jobs = 1 class Model: """ wrapper to the serialized scikit learn model, that uses feature selection in the first step """ def __init__(self, regressor, fs=None): self._regressor = regressor self._fs = fs def feature_select(self, X): fs = np.array(self._fs) X = np.array(X) _X = [] # perform selection for each input row for x in X: _X.append(x[fs]) return _X def predict(self, X): if self._fs: X = self.feature_select(X) return self._regressor.predict(X) return Model(regressor, feature_selection)
def predict_quality( self, videofilename, model_config_filename, device_type="pc", device_resolution="3840x2160", viewing_distance="1.5xH", display_size=55, temporary_folder="tmp", ): assert_file(videofilename, f"{videofilename} does not exist, please check") assert_file(model_config_filename, f"{model_config_filename} does not exist, please check") device_type = device_type.lower() assert_msg( device_type in DEVICE_TYPES, f"specified device_type '{device_type}' is not supported, only {DEVICE_TYPES} possible", ) assert_msg( device_resolution in DEVICE_RESOLUTIONS, f"specified device_resolution '{device_resolution}' is not supported, only {DEVICE_RESOLUTIONS} possible", ) assert_msg( viewing_distance in VIEWING_DISTANCES, f"specified viewing_distance '{viewing_distance}' is not supported, only {VIEWING_DISTANCES} possible", ) assert_msg( display_size in DISPLAY_SIZES, f"specified display_size '{display_size}' is not supported, only {DISPLAY_SIZES} possible", ) ffprobe_result = ffprobe(videofilename) assert_msg( ffprobe_result["codec"] in CODECS_SUPPORTED, f"your video codec is not supported by the model: {ffprobe_result['codec']}", ) model_config = json_load(model_config_filename) device_type = "pc" if device_type in ["pc", "tv"] else "mobile" # select only the required config for the device type model_config = model_config[device_type] # assume the RF model part is locally stored in the path of model_config_filename rf_model = os.path.join(os.path.dirname(model_config_filename), model_config["rf"]) # load parametetric model coefficients model_coefficients = model_config["params"] display_res = float(device_resolution.split("x")[0]) * float( device_resolution.split("x")[1]) self.display_res = display_res check_or_install_videoparser() os.makedirs(temporary_folder, exist_ok=True) feature_cache = os.path.join( temporary_folder, os.path.splitext(os.path.basename(videofilename))[0] + "_feat.pkl") logging.info(f"use feature cache file {feature_cache}") if not os.path.isfile(feature_cache): # run bitstream parser bitstream_parser_result_file = run_videoparser( videofilename, temporary_folder) if bitstream_parser_result_file == "": logging.error(f"no bitstream stats file for {videofilename}") return {} # calculate features features = pd.DataFrame([ extract_features(videofilename, self.features_used(), ffprobe_result, bitstream_parser_result_file) ]) features.to_pickle(feature_cache) else: logging.info("features are already cached, extraction skipped") features = pd.read_pickle(feature_cache) logging.info("features extracted") per_sequence = self._calculate(features, model_coefficients, rf_model, display_res, device_type) per_second = per_sample_interval_function(per_sequence["final_pred"], features) return { "video_full_path": videofilename, "video_basename": os.path.basename(videofilename), "per_second": [float(x) for x in per_second], "per_sequence": float(per_sequence["final_pred"].values[0]), "debug": { "baseline": float(per_sequence["baseline"].values[0]), "coding_deg": float(per_sequence["coding_deg"].values[0]), "upscaling_deg": float(per_sequence["upscaling_deg"].values[0]), "temporal_deg": float(per_sequence["temporal_deg"].values[0]), "rf_pred": float(per_sequence["rf_pred"].values[0]), }, "date": str(datetime.datetime.now()), }