Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
ARM-Stator-Vanes-Deliverables/Batch_Bitmask_Images.m
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
130 lines (111 sloc)
4.91 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% Script to batch bitmask-process images. | |
% Christian Schirmer | |
% Updated 21. Jan. 2021 | |
close all; clear all; | |
%% Setup Batch Processing File Locations | |
% Define base project directory | |
base_dir = fullfile('C:\Users\cks11003\University of Connecticut\UConn DSCLab - General\Projects\ARM Inspection Stator Vanes\Image Data\UW_Validation_Images'); | |
% Define Folder Location of Images to be Processed | |
% Note: Raw part image files should have the following format, | |
% corresponding to unique part ID and waypoint number: | |
% [part_(partID)_subregion_(waypoint#)] | |
% (Parenthesis should be excluded in the filename) | |
img_input_dir = fullfile(base_dir, 'Test Blade Images'); | |
% Define Folder Location of Bitmasks | |
% Note: Bitmask files should have the following format, corresponding to | |
% bitmask section id: [POSE(bmskID).JPG], where (bmskID) is replaced with | |
% bitmask ID. | |
bmsk_input_dir = fullfile(base_dir, 'Bitmasks'); | |
% Define Folder Location to Deposit Processed Images Into | |
% Note: Processed files will have the following format: | |
% [part_(partID)_region_(bmskID).jpg] | |
img_output_dir = fullfile(base_dir, 'Bitmasked Test Images\Unsorted_Test'); | |
%% Calibration Setup | |
% Note: 'bitmask ID' and 'pose' are used interchangably here. Discrete | |
% positions of the blade/robot in front of the camera are referred to as | |
% 'waypoints'. | |
% Define mappings of waypoints to poses (bitmask IDs) | |
% poses_in_waypoints{waypointIdx} contains list of poses (bitmask IDs) | |
% corresponding to that waypoint. | |
poses_in_waypoints = {[], [1], [4], [5], [2], [3], [6 11], [9],... | |
[7 8], [10], [12], [21 22 23], [15 16 19 20], [14 18], [13 17]}; | |
%% Aggregate Images | |
% Get list of images to load, as well as part number and pose number | |
disp('Aggregating list of images to process..'); | |
imgs_2_process = {}; | |
img_file_list = dir(fullfile(img_input_dir, '*.JPG')); | |
% Aggregate list of images to process, as well as corresponding waypoints | |
% and poses. | |
for i = 1:length(img_file_list) | |
imgs_2_process{end+1} = struct(); | |
% Get Filename | |
imgs_2_process{end}.imgFile = fullfile(img_file_list(i).folder, img_file_list(i).name); | |
% Get Part ID | |
name_idcs = find(img_file_list(i).name=='_',2,'first'); | |
imgs_2_process{end}.partNumber = img_file_list(i).name(((name_idcs(1)+1):(name_idcs(2)-1))); | |
% Get Waypoint Number | |
imgs_2_process{end}.waypoint = str2num(img_file_list(i).name(find((img_file_list(i).name=='_'),1,'last')+1:end-4)); | |
imgs_2_process{end}.poses = poses_in_waypoints{imgs_2_process{end}.waypoint}; | |
end | |
fprintf('%i images queued for processing.\n',length(img_file_list)); | |
%% Load bitmasks | |
bmsk_file_list = dir(fullfile(bmsk_input_dir, '*.jpg')); | |
fprintf('Loading %i bitmask files...\n', length(bmsk_file_list)); | |
bmsks = containers.Map('KeyType', 'uint32', 'ValueType', 'any'); | |
for i = 1:length(bmsk_file_list) | |
bmsk_id = uint32(str2num(bmsk_file_list(i).name(strfind(bmsk_file_list(i).name, 'POSE')+4:end-4))); | |
bmsks(bmsk_id) = imread(fullfile(bmsk_file_list(i).folder, bmsk_file_list(i).name)); | |
fprintf('%i ', i); | |
end | |
fprintf('Done.\n'); | |
%% Process the images | |
% Create output directory, if it does not yet exist | |
if(~exist(img_output_dir, 'dir')) | |
mkdir(img_output_dir); | |
end | |
fprintf('Processing %i Images..\n', length(imgs_2_process)); | |
for i = 1:length(imgs_2_process) | |
% Load the image | |
if(length(imgs_2_process{i}.poses)>0) | |
raw_img = imread(imgs_2_process{i}.imgFile); | |
end | |
% Process with appropriate bitmasks | |
for pose = imgs_2_process{i}.poses | |
% Process Image | |
prcd_img = cropBitmaskedImg(applyBitmask(raw_img, bmsks(pose), 0)); | |
% Write Processed Image Back to Folder | |
imwrite(prcd_img,... | |
fullfile(img_output_dir,... | |
['part_' imgs_2_process{i}.partNumber '_region_' num2str(pose) '.jpg'])); | |
end | |
if(mod(i,15)==0) fprintf('%i\n', i); else fprintf('%i ', i); end | |
end | |
fprintf('\n Complete. \n'); | |
%% Helper Functions | |
function img_out = applyBitmask(img, bmsk, transparency) | |
if(strcmp(class(bmsk),'logical')) | |
bmsk = uint8(bmsk*255); | |
bmsk = cat(3,bmsk,bmsk,bmsk); | |
end | |
% Limit transparency value to [0..1] | |
transparency = max([min([transparency, 1]) 0]); | |
compositeImage = uint8(bmsk*(1-transparency) + img*transparency); | |
img_out = compositeImage.*(uint8(~logical(bmsk(:,:,1)))) + img.*uint8(logical(bmsk(:,:,1))); | |
end | |
function img_out = cropBitmaskedImg(img_bmsk) | |
xmmymm = getBitmaskBounds(img_bmsk); | |
xmin = xmmymm(1); xmax = xmmymm(2); | |
ymin = xmmymm(3); ymax = xmmymm(4); | |
img_out = img_bmsk(ymin:ymax,xmin:xmax,:); | |
end | |
function xmmymm = getBitmaskBounds(img_bmsk) | |
if(strcmp(class(img_bmsk),'logical')) | |
bmsk = uint8(img_bmsk*255); | |
img_bmsk = cat(3,bmsk,bmsk,bmsk); | |
end | |
xmin = find(max(sum(img_bmsk,3),[],1),1,'first'); | |
xmax = find(max(sum(img_bmsk,3),[],1),1,'last'); | |
ymin = find(max(sum(img_bmsk,3),[],2),1,'first'); | |
ymax = find(max(sum(img_bmsk,3),[],2),1,'last'); | |
xmmymm = [xmin xmax ymin ymax]; | |
end |