Looping VideoReader in Matlab for processing - matlab

I've looked everywhere and I still cannot seem to successfully loop MATLAB's videoreader. I am trying to use MATLAB to process videos and convert them to saved image sequences which I can analyze by binary pixel properties for areas and such. I'm really new to MATLAB so any help would most certainly help.
Here is my code thus far for the image sequence creation. Also this is in R2015a.
function VideoToImageSequence(dirname,doall)
% load up the set of global variables
global settings
inpath = [settings.inpath, '\' , settings.dirname, '\'];
outpath = inpath;
%list of files
list = dir([inpath, '\*.avi']);
N =length(list);
display(['Found ', mat2str(N), ' movies in ', inpath]);
%Main converter
for i= 1:N
rootname{i} = list(i).name(1:end-4);
savefile = [rootname{i}, '.mat'];
if exist([inpath, savefile], 'file') && doall==0
display(['Found analyzed file ', savefile, ' .... skipping']);
else
%Directory
addpath(genpath([settings.inpath,'\', settings.dirname,'\' ,rootname{i}]));
workingDir = [settings.inpath,'\' , settings.dirname, '\' , rootname(i)];
cd([settings.inpath, '\', settings.dirname, '\'])
filename= rootname(i) ;
VideoFile = VideoReader(filename) ;
ii = 1;
%Spits out image sequence
while hasFrame(VideoFile(i))
img = readFrame(VideoFile(i));
filename = [sprintf('%03d',ii) '.jpg'];
fullname = fullfile(workingDir,'images',filename);
imwrite(img,fullname) % Write out to a JPEG file (img1.jpg, img2.jpg, etc.)
ii = ii+1;
end
end
end
Any help you can give would be awesome! Thanks.

Related

Open multiple files in Matlab

I have multiple files that I want to open using fopen. The files have a similar pattern, I have tried to use a for loop as follows, but it does not work. Any ideas how to open each file. Thanks in advance.
for ii = 0:12
file = fprintf('population_%d.dat', ii); % -----> File names
generations_fid = fopen(file); % Question ???
matrix = {};
while ~feof(generations_fid)
generations = cell2mat(textscan(generations_fid, repmat('%f', 1, (3))));
if isempty(generations)
fgetl(generations_fid);
else
matrix{end+1} = generations;
end
end
end
You want to be using sprintf to dynamically generate the file name, not fprintf.
file = sprintf('population_%d.dat', ii);
It's also good practice to open your file with the required permissions. In your case, it looks like you're reading, so you should use
generations_fid = fopen(file, 'r');

Matlab help to read multiple file images and save the final image to directory

im trying to do some facial recognition as im currently trying to figure out an idea i want to put in place
Ive never had to read multiple images from a folder before and i gave it my best shot but have come across an error that i cant seem to work ou
myPath = 'C:\Users\Callum\Desktop\Msc Computer Science\CN7023\CW\Faces_easy\';
a = dir(fullfile(myPath, '*.jpg'));
fileName = arrayfun( #(x) fullfile( myPath, x.name ), a, 'UniformOutput', false );
for k = 1:length(fileName)
I = imread(fileName{k});
end
// Code to add in
files = dir('C:\Users\Callum\Desktop\Msc Computer Science\CN7023\CW\Faces_easy\*.jpg');
files_len = numel(files);
result = cell(files_len,2);
for ii = 1:files_len
file = fullfile(files(ii).folder,files(ii).name);
img = imread(file);
result(ii,:) = {file perform_analysis(img)}; % or whatever your function is called
end
//
faceDetect = vision.CascadeObjectDetector();
bbox=step(faceDetect,I);
face=imcrop(I,bbox);
centerx=size(face,1)/2+bbox(1);
centery=size(face,2)/2+bbox(2);
eyeDetect = vision.CascadeObjectDetector('RightEye');
eyebox=step(eyeDetect,face);
n=size(eyebox,1);
e=[];
for it=1:n
for j=1:n
if (j > it)
if ((abs(eyebox(j,2)-eyebox(it,2))<68)&& (abs(eyebox(j,1)-eyebox(it,1))>40))
e(1,:)=eyebox(it,:);
e(2,:)=eyebox(j,:);
d=1;break;
end
end
end
if(d == 1)
break;
end
end
eyebox(1,:)=e(1,:);
eyebox(2,:)=e(2,:);
c=eyebox(1,3)/2;
d=eyebox(1,4)/2;
eyeCenter1x=eyebox(1,1)+c+bbox(1);
eyeCenter1y=eyebox(1,2)+d+bbox(2);
e=eyebox(2,3)/2;
f=eyebox(2,4)/2;
eyeCenter2x=eyebox(2,1)+e+bbox(1);
eyeCenter2y=eyebox(2,2)+f+bbox(2);
ndetect=vision.CascadeObjectDetector('Nose','MergeThreshold',16);
nosebox=step(ndetect,face);
noseCenterx=nosebox(1,1)+(nosebox(1,3)/2)+bbox(1);
noseCentery=nosebox(1,2)+(nosebox(1,4)/2);
m=[1,noseCentery,size(face,1),((size(face,2))-noseCentery)];
mouth=imcrop(face,m);
mdetect=vision.CascadeObjectDetector('Mouth','MergeThreshold' ,20);
mouthbox=step(mdetect,mouth);
for it=1:size(mouthbox,1)
if(mouthbox(it,2)>20)
mouthbox(1,:)=mouthbox(it,:);
break;
end
end
mouthbox(1,2)=mouthbox(1,2)+noseCentery;
noseCentery=noseCentery+bbox(2);
mouthCenterx=mouthbox(1,1)+(mouthbox(1,3)/2)+bbox(1);
mouthCentery=mouthbox(1,2)+(mouthbox(1,4)/2)+bbox(2);
shape=[centerx centery;eyeCenter1x eyeCenter1y;eyeCenter2x eyeCenter2y;noseCenterx noseCentery;mouthCenterx mouthCentery];
imshow(I);
hold on;
plot(shape(:,1),shape(:,2),'+','MarkerSize',10);
eyebox(1,1:2)=eyebox(1,1:2)+bbox(1,1:2);
eyebox(2,1:2)=eyebox(2,1:2)+bbox(1,1:2);
nosebox(1,1:2)=nosebox(1,1:2)+bbox(1,1:2);
mouthbox(1,1:2)=mouthbox(1,1:2)+bbox(1,1:2);
all_points=[eyebox(1,:);eyebox(2,:);nosebox(1,:);mouthbox(1,:)];
dpoints=size(all_points,1);
label=cell(dpoints,1);
i=1;
for i = 1: dpoints
label{i}= num2str(i);
end
videoout=insertObjectAnnotation(I,'rectangle',all_points,label,'TextBoxOpacity',0.3,'Fontsize',9);
imshow(videoout);hold on;plot(shape(:,1),shape(:,2),'+','MarkerSize',10);
dt=delaunayTriangulation(shape(:,1),shape(:,2));
imshow(videoout);hold on;triplot(dt);hold off
So i have changed it to what i currently have and it works but only on the last image, i want to make it do it on all images in a folder... I have 435 images in the folder it is calling, i dont want to all open as a figure once done, i would like them to save to a certain folder or workspace if that is possible
Print "fileName{k}" to verify if you are getting the required path for file.
secondly do not update fileName inside loop, you need to use different variable here inside loop.
If you want to perform your analysis on every image, you have to put your logics inside the loop itself and collect their result into a cell array or something across the lines. For instance, you can also simplify your folder search:
files = dir('C:\Users\Callum\Desktop\Msc Computer Science\CN7023\CW\Faces_easy\*.jpg');
files_len = numel(files);
result = cell(files_len,2);
for ii = 1:files_len
file = fullfile(files(ii).folder,files(ii).name);
img = imread(file);
result(ii,:) = {file perform_analysis(img)}; % or whatever your function is called
end
Once this is done, every row of the result variable will contain the file name in the first column and the analysis outcome in the second column.
EDIT
files = dir('C:\Users\Callum\Desktop\Msc Computer Science\CN7023\CW\Faces_easy\*.jpg');
files_len = numel(files);
for ii = 1:files_len
file = fullfile(files(ii).folder,files(ii).name);
I = imread(file);
faceDetect = vision.CascadeObjectDetector();
bbox=step(faceDetect,I);
face=imcrop(I,bbox);
centerx=size(face,1)/2+bbox(1);
centery=size(face,2)/2+bbox(2);
eyeDetect = vision.CascadeObjectDetector('RightEye');
eyebox=step(eyeDetect,face);
n=size(eyebox,1);
e=[];
for it=1:n
for j=1:n
if (j > it)
if ((abs(eyebox(j,2)-eyebox(it,2))<68)&& (abs(eyebox(j,1)-eyebox(it,1))>40))
e(1,:)=eyebox(it,:);
e(2,:)=eyebox(j,:);
d=1;break;
end
end
end
if(d == 1)
break;
end
end
eyebox(1,:)=e(1,:);
eyebox(2,:)=e(2,:);
c=eyebox(1,3)/2;
d=eyebox(1,4)/2;
eyeCenter1x=eyebox(1,1)+c+bbox(1);
eyeCenter1y=eyebox(1,2)+d+bbox(2);
e=eyebox(2,3)/2;
f=eyebox(2,4)/2;
eyeCenter2x=eyebox(2,1)+e+bbox(1);
eyeCenter2y=eyebox(2,2)+f+bbox(2);
ndetect=vision.CascadeObjectDetector('Nose','MergeThreshold',16);
nosebox=step(ndetect,face);
noseCenterx=nosebox(1,1)+(nosebox(1,3)/2)+bbox(1);
noseCentery=nosebox(1,2)+(nosebox(1,4)/2);
m=[1,noseCentery,size(face,1),((size(face,2))-noseCentery)];
mouth=imcrop(face,m);
mdetect=vision.CascadeObjectDetector('Mouth','MergeThreshold' ,20);
mouthbox=step(mdetect,mouth);
for it=1:size(mouthbox,1)
if(mouthbox(it,2)>20)
mouthbox(1,:)=mouthbox(it,:);
break;
end
end
mouthbox(1,2)=mouthbox(1,2)+noseCentery;
noseCentery=noseCentery+bbox(2);
mouthCenterx=mouthbox(1,1)+(mouthbox(1,3)/2)+bbox(1);
mouthCentery=mouthbox(1,2)+(mouthbox(1,4)/2)+bbox(2);
shape=[centerx centery;eyeCenter1x eyeCenter1y;eyeCenter2x eyeCenter2y;noseCenterx noseCentery;mouthCenterx mouthCentery];
imshow(I);
hold on;
plot(shape(:,1),shape(:,2),'+','MarkerSize',10);
eyebox(1,1:2)=eyebox(1,1:2)+bbox(1,1:2);
eyebox(2,1:2)=eyebox(2,1:2)+bbox(1,1:2);
nosebox(1,1:2)=nosebox(1,1:2)+bbox(1,1:2);
mouthbox(1,1:2)=mouthbox(1,1:2)+bbox(1,1:2);
all_points=[eyebox(1,:);eyebox(2,:);nosebox(1,:);mouthbox(1,:)];
dpoints=size(all_points,1);
label=cell(dpoints,1);
i=1;
for i = 1: dpoints
label{i}= num2str(i);
end
videoout=insertObjectAnnotation(I,'rectangle',all_points,label,'TextBoxOpacity',0.3,'Fontsize',9);
imshow(videoout);hold on;plot(shape(:,1),shape(:,2),'+','MarkerSize',10);
dt=delaunayTriangulation(shape(:,1),shape(:,2));
imshow(videoout);hold on;triplot(dt);hold off
end

File Importing Sequence changed using parfor (different results using parfor and for)

I have an issue with the file importing when converting my for loop into parfor and would appreciate any help I can get.
The structure of my code is as following:
myFolder = '../Test';
if option1 == 1
ext = 'EW';
filePattern1 = fullfile(myFolder, '*.EW1'); % input motion
datFiles1 = dir(filePattern1);
filePattern2 = fullfile(myFolder, '*.EW2'); % surface motion
datFiles2 = dir(filePattern2);
elseif option1 == 2
ext = 'NS';
filePattern1 = fullfile(myFolder, '*.NS1'); % input motion
datFiles1 = dir(filePattern1);
filePattern2 = fullfile(myFolder, '*.NS2'); % surface motion
datFiles2 = dir(filePattern2);
end
parfor k = 1:length(datFiles1)
baseFileName1 = datFiles1(k).name;
baseFileName2 = datFiles2(k).name;
fullFileName1 = fullfile(myFolder, baseFileName1);
fullFileName2 = fullfile(myFolder, baseFileName2);
%display file importing sequence
fprintf(1, 'Now processing %s\n', baseFileName1);
record1 = load(baseFileName1);
fprintf(1, 'Now processing %s\n', baseFileName2);
record2 = load(baseFileName2);
npts2 = length(record2(:,1));
%this is the end of file importing part and the following is to process the imported data, and as that is not relevant to this issue, I didn’t show them.
end
The datFiles1 and datFiles2 look like this:
And datFiles2 goes with the same sequence except with EW2 extensions.
Then it should display as in Filename1.EW1, Filename1.EW2, Filename2.EW1, Filename2.EW2, Filename3.EW1, Filename3.EW2, Filename4.EW1, Filename4.EW2 …
As like this: (if I only use for loop)
However, if I use parfor, the sequence is messed up as it seems like it randomly imports some file and then follows the sequence again
[enter image description here][3]
The first 4 lines are right. Then the 6th line starts to show an error when it should have been MYGH050008281720.EW2
The key is to process each pair of EW1, EW2 files(with same filenames) in a loop. Is there any other way to import files in parfor? Thanks!

Undefined function or variable using parfor in matlab

I'm unable to execute the following code:
parallel_mode = true; %To process multiple images at the same time
parallel_degree = 4; %Number of threads that will be created
if parallel_mode
if matlabpool('size') == 0
matlabpool(parallel_degree);
elseif matlabpool('size') ~= parallel_degree
matlabpool close;
matlabpool(parallel_degree);
end
end
%Loading dictionary
try
load(dictionary_path);
catch
error(['Was impossible to load the dictionary in path: ' dictionary_path ', Please, check the path. ' ...
'Maybe you should use dictionary_training function to create it.'])
end
%% Processing test images
test_images = dir([test_im_path, pattern]);
num_test_images = size(test_images,1);
%Pre-allocating memory to speed-up
estimated_count = zeros(1,num_test_images);
true_count = zeros(1,num_test_images);
estimated_upper_count = zeros(1,num_test_images);
estimated_lower_count = zeros(1,num_test_images);
true_upper_count = zeros(1,num_test_images);
true_lower_count = zeros(1,num_test_images);
%Calculating dimensions of the image subregion where we can count
im_test = imread([test_im_path test_images(1).name]);
dis = round(patch_size/2);
dim_x = dis:size(im_test,2)-dis+1;
dim_y = dis:size(im_test,1)-dis+1;
toGaussian = fspecial('gaussian', hsize, sigma);
parfor a=1:num_test_images
disp(['Processing image #' num2str(a) ' of ' num2str(num_test_images) '...']);
im_test = imread([test_im_path test_images(a).name]);
[~, name, extension] = fileparts(test_images(a).name);
im_ground_truth = imread([ground_truth_path name 'dots' extension]);
disp('Extracting features...');
features = extract_features(im_test, features_type, dic_signal, sparsity, patch_size, mean_rem_flag);
features = full(features); %ND-sparse arrays are not supported.
%Re-arranging features
features = reshape(features', size(dim_y,2), size(dim_x,2), dic_size);
%Normalizing features
max_factors_3D = repmat(max_factors_depth, [size(features,1), size(features,2)]);
max_offset_3D = repmat(max_offset_depth, [size(features,1), size(features,2)]);
features = (features-max_offset_3D)./max_factors_3D;
%%Some stuff
....
end
When i execute it i get:
Undefined function or variable 'dic_signal'.
when it arrives to the extract_features function. However, in the single thread version (with for instead of parfor) it works correctly.
Someone can give me any hint?.
Thank you.
EDIT:
dic_signal is defined and correctly loaded in load(dictionary_path);
I suspect the load command doesn't load the variables in the workers workspace, only on your MATLAB instance workspace, which is why it works in a normal for loop, but not with a parfor loop. You might want to try instead:
pctRunOnAll load(dictionary_path)
to ensure the correct data is loaded into the workspace of each of the workers.

how to save files in a loop in Matlab?

I have some geotif files and I am trying to create a mosaic out of them. I have tried to put the images beside each other first in a row and then tried to join the in columns and have the final mosaic. I would like to have the output file with the save number of the loop (outimage1,outimage2,..). I would like to know how should I introduce the output file with the sequence of the loop number.
I would be happy if someone help me find my mistake in the following code.
close all;
clear all;
clc;
path = 'E:\MATLAB\...\tifs\';
path2 = 'E:\MATLAB\...\tifs\out\';
matfiles = dir(fullfile('E:', 'MATLAB',...,'tifs','*.tif'));
files = {matfiles.name};
lf=length(files);
image_row = [];
for L=1:11
for k=1:14:lf
fname = matfiles(k).name;
fullname = horzcat (path,fname);
infile = imread (fullname);
image_row= [image_row,infile];
[~, ~, ext] = fileparts(fname);
outimage = fullfile( path2, sprintf('outimage%d%s', L, ext) );
imwrite(image_row,outimage);
end
end
Yours assistant is highly appreciated.
I am not familiar with a matlab syntax k. format(fname).
If you want to do string formatting in Matlab - read this first.
A solution for your problem might be
outimage = fullfile( path2, sprintf('outimage_%03d_%s', k, fname ) );
EDIT:
following comment by OP, get the file format (tif):
[~, ~, ext] = fileparts(fname);
outimage = fullfile( path2, sprintf('outimage%d.%s',ext) );