-- M module extracted from ITU-T J.249 (01/2010)

function [orig_pixels, orig_horiz_profile, orig_vert_profile] = ... dll_lowbw_calib_original(fn, seed_state, num_sec) % DLL_LOWBW_CALIB_ORIGINAL % Calcualte original features needed for low bandwidth calibration. % SYNTAX % [orig_pixels, orig_horiz_profile, orig_vert_profile] = ... % fast_calibration(fn, seed_state, num_sec) % DESCRIPTION % Calcualte original features needed for low bandwidth calibration: % estimate spatial registration and scaling registration for each processed % clip. Video clip must be temporally registered first. % 'fn' is the file identifier from dll_video, which should always be fn=1. % 'seed_state' is as returned by dll_lowbw_initialize, which should be % called anew each time this function is called. % 'num_sec' is the number of seconds of video from file fn=1 that should % be used for calibration. % % Return values 'orig_pixels', 'orig_horiz_profile', and % 'orig_vert_profile' are required by function dll_lowbw_calib_processed. num_sec = floor(num_sec); % set up constants. max_scale = 100; % maximum scaling search, 10% [rows,cols, fps] = dll_video('size', fn); durration = floor( dll_video('total_frames',1) / fps ); if durration < num_sec, num_sec = durration; end if rows <= 216, max_shift_horiz = 4; % maximum search in any direction, in # pixels max_shift_vert = 4; max_scale_horiz = 60; % maximum scaling search, max_scale_vert = 40; elseif rows <= 384, max_shift_horiz = 8; max_shift_vert = 8; max_scale_horiz = 60; max_scale_vert = 40; else max_shift_horiz = 20; max_shift_vert = 20; max_scale_horiz = 100; max_scale_vert = 60; end % error checks & corrections if mod(max_shift_horiz,2), max_shift_horiz = max_shift_horiz + 1; end if mod(max_shift_vert,2), max_shift_vert = max_shift_vert + 1; end % compute PVR and OROI given the above. max_pixels_horiz = max_shift_horiz + (max_scale_horiz / 1000) * cols; max_pixels_horiz = ceil(max_pixels_horiz); max_pixels_horiz = max_pixels_horiz + mod(max_pixels_horiz,2); max_pixels_vert = max_shift_vert + (max_scale_vert / 1000) * rows; max_pixels_vert = ceil(max_pixels_vert); max_pixels_vert = max_pixels_vert + mod(max_pixels_vert,2); [pvr, oroi] = find_pvr_oroi_guess(rows, cols, max_pixels_horiz, max_pixels_vert); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Algorithm: % % Use one frame every second (approx). % horizontal and vertical profiles AND % 80% as many randomly subsampled pixels as there are profile pixels % - randomly distributed over all frames % Search over ALL frames simultaneously. % Search original +- 0 second (yes! ZERO); % shift processed +- 20 pixels/lines for NTSC (as specified else) % scale processed by +/- 10% for NTSC (as specified else) % rescale using nearest neighbor % % When have final scale & shift, compute luminance gain & offset with % those pixels & profiles, too. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Choose the % of pixels to be used. rows = oroi.bottom - oroi.top + 1; cols = oroi.right - oroi.left + 1; [list_row, list_col, list_time, list_o] = ... sas_choose_pixels (seed_state, rows, cols, num_sec, max_pixels_horiz, max_pixels_vert); % load frames dll_video('set_rewind', fn); for loop = 1:num_sec, y(:,:,loop) = dll_video('sec', fn, 0, 1.0/fps); % don't reframe if loop ~= num_sec, dll_video('discard', fn, (fps-1)/fps); end end dll_video('rewind', fn); y = double(y); % cut out OROI orig = y(oroi.top:oroi.bottom, oroi.left:oroi.right, :); % Compute original profiles. [orig_horiz_profile, orig_vert_profile] = sas_profile_images(orig); % reshape rows & columns into one dimension. [rows,cols,time] = size(orig); orig_y = reshape(orig, rows*cols*time,1); clear orig; %list of coordinates for profiles list_horiz_profile = (1:cols) + max_pixels_horiz; list_vert_profile = (1:rows) + max_pixels_vert; % pick our original pixels orig_pixels = orig_y(list_o); % % % Limit precision on return variables % % orig_pixels = char(orig_pixels); % % orig_horiz_profile = uint16( round(orig_horiz_profile * 257)); % % orig_vert_profile = uint16( round(orig_vert_profile * 257)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [pvr] = find_pvr_guess(rows, cols); % return the best guess for pvr based only on image size. % i.e., discard overscan. % 'fchoice' is 1 for 'field' or 0 for 'frame' depending on which is desired. if (rows == 486 | rows == 480 ) ... & cols == 720, pvr.top = 19; pvr.bottom = 486 - 18; pvr.left = 23; pvr.right = 720 - 22; elseif rows == 576 & cols == 720, pvr.top = 15; pvr.bottom = 576 - 14; pvr.left = 23; pvr.right = 720 - 22; else pvr.top = 1; pvr.bottom = rows; pvr.left = 1; pvr.right = cols; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [pvr, oroi] = find_pvr_oroi_guess(rows, cols, max_pixels_horiz, max_pixels_vert); % Find best guess at PVR and OROI, given image size and % size of maximum search ('max_pixels_horiz'), in pixels. pvr = find_pvr_guess(rows, cols); oroi.top = pvr.top + max_pixels_vert; oroi.bottom = pvr.bottom - max_pixels_vert; oroi.left = pvr.left + max_pixels_horiz; oroi.right = pvr.right - max_pixels_horiz; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [list_row, list_col, list_time, list_o] = ... sas_choose_pixels (seed_state, rows, cols, time, max_pixels_horiz, max_pixels_vert); % Choose 80% as many random points as profile points. need = ceil(0.80 * (rows+cols)*time ); rand('state', double(seed_state)); list_row = round(rand(1,need) * (rows) + 0.5); list_col = round(rand(1,need) * (cols) + 0.5); list_time = round(rand(1,need) * (time) + 0.5); % limit to range available. 'rand' is unlikely to exceed that range, but % it is possible. list_row = max( min(list_row,rows), 1); list_col = max( min(list_col,cols), 1); list_time = max( min(list_time,time), 1); list_o = (list_time-1)*rows*cols + (list_col-1)*rows + list_row; % change coordinates to be for processed, where there are more rows & % columns. list_row = list_row + max_pixels_vert; list_col = list_col + max_pixels_horiz; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [horiz_profile, vert_profile] = sas_profile_images(y); % Compute the horizontal profile for each frame (averaging each column). % Put all such together into one giant image. % Return that image in profile_image. [rows,cols,time] = size(y); horiz_profile = zeros(cols, time); vert_profile = zeros(rows, time); for cnt = 1:time, horiz_profile(:,cnt) = mean(y(:,:,cnt))'; vert_profile(:,cnt) = mean(y(:,:,cnt), 2); end