-- M module extracted from ITU-T J.249 (01/2010)
function [one, two, three] = dll_model(control, varargin) % DLL_MODEL % Complete VQM model calculations. % % To Initialize: % [model_tslice_sec, model_planes] = dll_model('initialize', model_name, durration, fn); % 'model_name' is the name of the model to be run: % 'Fast' Fast Low-Bandwidth Model % 'fn' is 1 for original and 2 for processed -- either is okay -- where % function dll_video has been initialized on this computer for (fn). % 'fn' presumed for following 'tslice' and 'get' calls, until next 'initialize'. % 'durration' is the % % To Calculate features for next time-slice % where y (if 'model_planes' == 'y') % or y, cb, cr, & fps (if 'model_planes' == 'ycbcr'): % [ready_for_vqm] = dll_model('tslice', y); % [ready_for_vqm] = dll_model('tslice', y, cb, cr, fps); % % To Get features % [features] = dll_model('get'); % % To Complete VQM model calculations. % [vqm, pars, par_names] = dll_model('vqm', source_features, proc_features); % 'source_features' is the 'features' return value from dll_features(fn=1) % for general & developer's models. For Lowbw & Fast models, % 'source_features' is the file name containing compressed % features. % 'proc_features' is the 'features' return value from dll_features(fn=2) % Function 'dll_features' must already have been run & retreived with % dll_model('get') for fn=1 (source_features) and fn=2 (processed % featues). persistent data; one = NaN; two = NaN; three = NaN; if strcmp(control,'initialize'), if strcmp(varargin{1}, 'Fast'), [data,one,two] = model_run_Callback_initialize_fastlowbw(varargin{2}, varargin{3}); else error('model name not recognized'); end data.model = varargin{1}; elseif strcmp(control,'tslice'), if strcmp(data.model,'Fast'), [data, one] = model_run_Callback_feature_fastlowbw(data, varargin{1}, varargin{2}, ... varargin{3}, varargin{4}); else error('model name not recognized'); end elseif strcmp(control,'vqm'), if strcmp(data.model,'Fast'), file_name = varargin{1}; [orig_features.si_orig, orig_features.part_si_min, orig_features.part_si_max, ... orig_features.hv_feat_orig, orig_features.part_hv_min, orig_features.part_hv_max, ... orig_features.y_orig, ... orig_features.cb_orig, orig_features.cr_orig, orig_features.part_c_min, ... orig_features.part_c_max, orig_features.part_c, ... orig_features.ati_orig, orig_features.part_ati_min, orig_features.part_ati_max, ... orig_features.part_ati, orig_features.code_ati ] ... = model_lowbw_compression('uncompress', file_name); [fps] = dll_video('fps'); [one, two, three] = model_run_Callback_vqm_fastlowbw(varargin{2}, orig_features, fps); else error('model name not recognized'); end elseif strcmp(control,'get'), one = data; end %%%%%%%%%%%%%%%%%%%%%%%%% function [data,model_tslice_sec, model_planes] = model_run_Callback_initialize_fastlowbw(durration, fn); % figure out side & control option. data.destination = (fn == 2); model_tslice_sec = 1.0; model_planes = 'ycbcr'; data.tslice_total = floor(durration / model_tslice_sec); data.tslices = 0; if data.destination, model_fastlowbw_features_shift('clear'); else model_fastlowbw_features('clear'); end % set lowbw SROI [image_size.rows,image_size.cols] = dll_video('size',fn); [filter_size, extra] = adaptive_filter(image_size); [pvr] = dll_calib_video('pvr'); [valid, cvr, sroi] = model_lowbw_sroi(extra, pvr.top, pvr.left, pvr.bottom, pvr.right); dll_calib_video('sroi', sroi, extra+1); %%%%%%%%%%%%%%%%%%%%%%%%% function [data, ready_for_vqm] = model_run_Callback_feature_fastlowbw(data, y, cb, cr, fps); % process next Time-slice if data.tslices == data.tslice_total, data.tslices = 0; end % cut out SROI +/- 6 pixels [rows,cols,time] = size(y); image_size.rows = rows; image_size.cols = cols; [filter_size,extra] = adaptive_filter(image_size); [valid, pvr, sroi] = model_lowbw_sroi(extra, 1, 1, rows, cols); if ~valid, report_Callback('add', 'Valid Region too small. Low Bandwidth Model cannot execute.'); stop_Callback('button'); return; end [image_size.rows,image_size.cols,junk] = size(y); y = y(pvr.top:pvr.bottom, pvr.left:pvr.right,:); cb = cb(pvr.top:pvr.bottom, pvr.left:pvr.right,:); cr = cr(pvr.top:pvr.bottom, pvr.left:pvr.right,:); % compute features. [filter_size, extra] = adaptive_filter(image_size); if data.destination, model_fastlowbw_features_shift ('memory', y, cb, cr, fps, filter_size, extra); else % discard one pixel on all sides, then compute features [row,col,time] = size(y); y = y(2:row-1, 2:col-1, :); cb = cb(2:row-1, 2:col-1, :); cr = cr(2:row-1, 2:col-1, :); model_fastlowbw_features ('memory', y, cb, cr, fps, filter_size, extra); end % update number of tslices destination. data.tslices = data.tslices + 1; if data.tslices == data.tslice_total, if data.destination, [data.data] = model_fastlowbw_features_shift ('eof'); else [data.si_std data.hv_ratio data.y_mean data.cb_mean data.cr_mean data.ati_rms] ... = model_fastlowbw_features ('eof'); end ready_for_vqm = 1; else ready_for_vqm = 0; end %%%%%%%%%%%%%%%%%%%%%%%%% function [vqm_value, pars, par_names] = model_run_Callback_vqm_fastlowbw(proc, src, fps); [row,col,TIME_DELTA] = size(src.si_orig); for loop = 1:9, % calculate model do_test_print = 0; [data(loop).vqm, data(loop).hv_loss_par, data(loop).hv_gain_par,data(loop).si_loss_par, ... data(loop).si_gain_par, ... data(loop).color_comb_par, data(loop).noise_par, data(loop).error_par] = ... model_fastlowbw_parameters (... proc.data(loop).si_std, proc.data(loop).hv_ratio, proc.data(loop).y_mean, ... proc.data(loop).cb_mean, proc.data(loop).cr_mean, proc.data(loop).ati_rms, ... src.si_orig, src.hv_feat_orig, src.y_orig, src.cb_orig, src.cr_orig, src.ati_orig, ... fps, src.part_si_min, src.part_si_max, src.part_hv_min, src.part_hv_max, ... src.part_c_min, src.part_c_max, src.part_c, src.part_ati_min, src.part_ati_max, ... src.part_ati, src.code_ati, 0, TIME_DELTA); end % select smallest average VQM score shift for shift=1:9, vqm_mean(shift) = mean(data(shift).vqm); end [junk shift] = min(vqm_mean); row = floor((shift-1)/3)-1; col = mod(shift-1,3)-1; % keep only the last sample; above function produces an entire % time-history and we only want the ending number. num = length(data(shift).vqm); % select & copy data to return. pars = [data(shift).hv_loss_par(num), data(shift).hv_gain_par(num), ... data(shift).si_loss_par(num), data(shift).si_gain_par(num), ... data(shift).color_comb_par(num), data(shift).noise_par(num), ... data(shift).error_par(num), row, col]; par_names = {'hv_loss' 'hv_gain' 'si_loss' 'si_gain' 'color_comb' 'noise' 'error' 'vshift' 'hshift'}; vqm_value = data(shift).vqm(num);