parse_video(); %% function parse_video(resize_shape, crop_flag) % % Parsing video (*.mp4/*.avi) file(s) into image (*.jpg) files % % Written by Hio-Been Han, hiobeen.han@kaist.ac.kr % % 2020-09-30 % if nargin < 1, resize_shape = [448 448]; end if nargin < 2, crop_flag = false; end %% (1) Get file info & set save directory [file_list, vid_directory] = uigetfile('*.mp4','MultiSelect','on'); if ischar(file_list), file_list = {file_list}; end img_directory = [ 'data/frames/']; if ~isdir(img_directory), mkdir(img_directory); end convert_resolution = sprintf( '%dx%d', resize_shape(1),resize_shape(2)); save_format = '.jpg'; %% (2) Parse video into JPEG files for fileIdx = 1:length(file_list) % Set save directory fname = file_list{fileIdx}; uniqname = fname(1:end-4); fileformat = fname(end-3:end); vidname = [vid_directory uniqname]; save_directory = [img_directory uniqname '/']; if ~isdir(save_directory), mkdir(save_directory); end % Read frames v = VideoReader( [ vidname fileformat ]); nFrames = v.Duration * v.FrameRate; for frameIdx = 1:nFrames if v.hasFrame frame = v.readFrame(); % Set ROI if frameIdx == 1 if crop_flag mask = image_ROI_selection(frame, ['Select ROI to save' ... ' [Occlusion => Right Click]']); else mask = logical(ones([size(frame,1), size(frame,2)])); end idx_x = find( nanmean(mask,2) ); idx_y = find( nanmean(mask,1) ); original_resolution = sprintf( '%dx%d', size(frame,1), size(frame,2)); end % Save frame % frame_valid = rgb2gray( frame(idx_x,idx_y,:) ); frame_valid = rgb2gray( frame(:,60:end-60,:) ); imgname_write = [num2str(sprintf('frame-%06d',frameIdx))... '-' uniqname '-from' original_resolution '-to' convert_resolution save_format]; imwrite( imresize( frame_valid, resize_shape ), [ save_directory imgname_write ] ) end end end end %% Subfunc function mask = image_ROI_selection(I, textInput) if nargin == 1, textInput = ''; end figure(1), set(gcf, 'Color', [1 1 1]); colormap(gray); imshow(uint8(I), 'DisplayRange', [], 'InitialMagnification',600/max(size(I))*100 ); title( textInput ) %%-- Display instructions to user %title('click points to make an initial contour, right click to close contour and finish'); disp('click points to make an initial contour,'); disp('right click to close contour and finish'); %%-- begin getting points [y1 x1 b] = ginput(1); xi = x1; yi = y1; if(b ~= 1) return; end [ny nx c] = size(I); mask = zeros(ny,nx); while(1) x2 = x1; y2 = y1; [y1 x1 b] = ginput(1); if(b ~= 1), x1 = xi; y1 = yi; end lx = x2-x1; ly = y2-y1; len = ceil((lx^2+ly^2)^(1/2))+1; x = round(x1:(lx)/(len-1):x2); y = round(y1:(ly)/(len-1):y2); %make another one for y if(length(x) == 0), x = round(x1) * ones(1,len); end if(length(y) == 0) y = round(y1) * ones(1,len); end this_index2 = sub2ind(size(mask),x, y); if size(this_index2) == [1 1] title('Try Again!', 'FontSize', 18) sprintf Try_Again! end try mask(this_index2) = 1; end idx = find(mask==1); backup_mask = mask; %%-- draw the users line in the image (color or grayscale) if(c-1) Ir = I(:,:,1); Ig = I(:,:,2); Ib = I(:,:,3); Ir(idx) = 0; Ig(idx) = 255; Ib(idx) = 0; I(:,:,1) = Ir; I(:,:,2) = Ig; I(:,:,3) = Ib; else I(idx) = 255; end imshow(uint8(I),'DisplayRange', [], 'InitialMagnification', 600/max(size(I))*100); title( textInput ) if(b ~= 1) break; end end mask = bwfill(mask, 'holes'); % mask = ~mask; end