Use writetable inside loop in matlab - matlab

I'm trying to use writetable command inside a loop. Any help?

MonthNames=['JAN'; 'FEB'; 'MAR'; 'APR'; 'MAY'; 'JUN'; 'JUL'; 'AUG'; 'SEP'; 'OCT'; 'NOV'; 'DEC'];
for sensorIndex = 1:numel(sensor)
for monthIndex = 1:numel(MonthNames)
% Get the current sensor
k = sensor(sensorIndex);
% Get the file(s?) associated with that sensor
S = dir(fullfile(path, '*', sprintf('sensor%d.xls', k));
% Create an output filename
filename = sprintf('sensor%d_%s.xls', k, MonthNames(monthIndex));
% do your stuff
F = fullfile(S(k).folder,S(k).name);
data = readtable(F);
writetable(data, filename);
end
end
Doing it this way lets you optionally not have ALL months. Lots of ways to code it, but my personal preference is to keep loop variables as indices and grab the current variable inside the loop using that index.

Related

How can I loop through and process files from a directory individually?

I'm trying to write a function that iteratively loops through a bunch of .txt files in a directory and processes them individually. After a file has been processed I would like to plot output variables, then on the next iteration plot the new variables on the same graph. My code is shown below however does not seem to be working, it returns a 'output argument 'output1' (and maybe others) not assigned during call to function2.
Currently my code looks something like this:
function [output1, output2, fig] = Processing(Folder_1,Folder_2,Folder_3)
%% Read in all the Data
% Initialise Loop to process each file independently
for i = 1 : length(Text_Files1)
Sorted_Index1 = Indices1(i);
Path1 = fullfile(Folder_1,Text_Files1(Sorted_Index1).name);
Table1 = readtable(Path1);
Sorted_Index2 = Indices2(i);
Path2 = fullfile(Folder_2,Text_Files2(Sorted_Index2).name);
Table2 = readtable(Path2);
Sorted_Index3 = Indices3(i);
Path3 = fullfile(Folder_3,Text_Files3(Sorted_Index3).name);
Table3 = readtable(Path3,'Delimiter',';');
%% Process Data through the Loop
[HR] = function1(processed_data)
[output1 output2] = function2(HR, Time);
hold on
fig = figure('Visible', false);
subplot(10,10,1:90)
plot(output2, output1, 'Color', [0.92 0.47 0.44], 'LineWidth', 1.5);
end
end
%% Function 2:
function [output1, output2] = function2(t, y, z)
segment = 1:z:max(y);
% Iterate through each time segment and calculate average t value
for x = 1:length(segment)-1
SegmentScores = find(y > segment(x) & ...
y < segment(x+1));
output1(x) = mean(y(SegmentScores));
output2(x) = Segment(x+1);
end
end
The problem is that you're calling function2(HR, Time) with two inputs, while it needs three function2(t, y, z).
For that reason, I'm assuming that inside function2 segment is an empty array, and thus the loop for x = 1:length(segment) - 1 is not entered at all.
Since the definition of output1 and output2 is only inside the loop, they will never be created and thus the error.
If you provide three inputs to your function2, the problem will be solved. Just pay attention to the order in which you provide them (for example, I'm assuming your Time input should be the same as t in the function, so it should be the first input to be passed).

For loop iteration through .txt files

I have a function that is part of an object that I have name TestData. Here are the properties and its constructor:
classdef TestData
properties
metaData = []; % stores meta data in Nx2 array
data = []; % stores data in PxQ array
colLabels = []; % labels columns
colUnits = []; % provides units
temp = []; % temporary to bypass setters while structuring data
end
methods
%% Constructor
function this = TestData(varargin) % Will take in a variable number of inputs
if (nargin == 0)
return;
end
if (nargin == 1 && ischar(varargin{1})) % Case of the input being a file (.txt, .s*p, etc..)
this = readDataFromFile(this, varargin{1});
return;
elseif (nargin == 4) % Case of the input being raw data. Note that the order matters.
this.metaData = varargin{1};
this.colLabels = varargin{2};
this.colUnits = varargin{3};
this.data = varargin{4};
return
else
error('Not enough input arguments.');
end
end
Now, let us say that I have 42 text files that I want to pass into the object. I have created a function for this called extractData that sifts through the data and finds a user input x-axis and y-axis. It does so by first calling a function readDataFromFile, which sets the property arrays that are outlined in the code above. It is a fairly long function and I won't include it for the time being, but I will say that I do know it is working.
The problem: I make an object of the class called myTestData and perform this operation in the CW, myTestData=myTestData.extractData('Tip Type','Tip S/N'). This will look for the Tip Type and Tip S/N. As you can see in the code, the type and S/N are in column 3 of the matrix. If the string is found, it takes the row it was found on, accesses column 3 of that row, and places that value into the temp array. In my case, the type is passive and the S/N is AM66191. It will write this to the temp array, but then on the second iteration of the for loop it will write something else over the first row and the passive and AM66191 will be displayed on the second row. It will do this all the way until the end, where on row 42 I will see the type and S/N, but all the other rows are just garbage. I have attached an image of what the temp array looks like after the second iteration of the for loop. Here is the code for the extractData function:
function this = extractData(this, xAxis, yAxis)
s = dir('*.txt'); % Gather all text files
disp(length(s))
for i=1:length(s) % Loop through and gather data until last element of strcuct
j = 1;
fid = s(i).name; % Open file in read-only mode
this = this.readDataFromFile(fid);
disp(fid)
x = this.metaData(find(contains(this.metaData(:,1), xAxis)),3);
this.temp(i,j) = x;
disp(this.temp(i,j))
j = j+1;
y = this.metaData(find(contains(this.metaData, yAxis)),3); %#ok<*FNDSB>
this.temp(i,j) = y;
disp(this.temp(i,j))
end %for
end %extractData

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

Modifying a matrix entry based on the file loaded

I have a 30 files like this:
1-1.jpg, 1-2.jpg, ..., 1-10.jpg
2-1.png, 2-2.png, ..., 2-10.png
3-1.gif, 3-2.gif, ..., 3-10.gif
Now I want to use a switch case in this way:
When I load 1-1.jpg to 1-10.jpg I get 1 for last column of my matrix
When I load 2-1.png to 2-10.png I get 2 for last column of my matrix
When I load 3-1.gif to 3-10.gif I get 3 for last column of my matrix
How can I do this? I don't want to use for loops because it will slow down the code significantly. For just one file I did this:
switch Filename
case {'1.jpg'}
Matrix(end) = 1;
case {'2.png'}
Matrix(end) = 2;
case {'3.gif'}
Matrix(end) = 3;
end
You don't need a for loop or a switch statement. You can just do this every time you load and process a file (using strtok and str2double):
intString = strtok(Filename, '.-'); % Get leading integers of file name string
Matrix(end) = str2double(intString); % Convert string to integer and store in matrix
If you don't want to use the leading integers as the identifying label to put in Matrix, but instead want to use the file extension, you can do it using the functions fileparts and ismember like so:
extList = {'.jpg'; '.png'; '.gif'}; % Create a list of valid extensions
[~, ~, ext] = fileparts(Filename); % Get the file extension
[~, index] = ismember(ext, extList); % Find its index in the list
Matrix(end) = index;
And the identifying label for each file type will be its position in extList.

use of strcat function

I would like to check that I have
workingDir = C:\Users\~\Temp\workspace_folder;
for i=1:2
% do an action which generates folder C:\Users\~\Temp\workspace_folder_1 first iteration
% and increment for each iteration
x = strcat(workingDir,'_',i);
end
it gives only
x = C:\Users\~\Temp\workspace_folder_ , why do it doesn't print me the iteration value?
I expected to have
C:\Users\~\Temp\workspace_folder_1
C:\Users\~\Temp\workspace_folder_2
Thanks
you need to convert i to string using int2str