I have a question about how to load in data from multiple directories, but the files I need to load all have the same name. Here's what I have thus far:
for i = 1:numel(smoothlist1) % loop through smoothing directories
path2 = sprintf('%s%s/Trade-off_Curves',path1,smoothlist1(i).name);
cd(path2);
disp(['Changed directories into ', path2]);
data{i} = load('results.xy');
end
I loop through each directory in a list I call smoothlist1.
Within each 'smoothlist1 directory, I change directories into ~/smoothlist1/Curves/. Within this directory, there is a file called results.xy. I need to load each of the results.xy file from each ~smoothlist1/Curves directory, but I am unsure how to do that. What I have above just loads in the final results.xy file in the last smoothlist1/Curves/ directory.
So the question is, how do I loop through loading in that results.xy file from multiple directories? I have tried doing data(j) = results.xy, where I add a counter for j, but that did not work. I would like to load these results.xy files into separate filenames as well.
Thank you for your help.
Related
I have a lot of videos to run which are kept in the diffrent folder than my current directory of Matlab and VideoReader is not taking the directory address of the video. Need help in creating video object of video kept in a diffrent folder.
filePattern = fullfile(pwd, 'videoDir\videoname.mp4');
fileList = dir (filePattern );
video_name =fileList.name;
obj = VideoReader(video_name);
The .name field of the directory structure is only the final part of the name - it does not include any folders or subfolders. Your very first line defines the entire absolute path and filename for the video file. You can pass that to VideoReader directly.
filePattern = fullfile(pwd, 'videoDir\videoname.mp4');
obj = VideoReader(filePattern);
In fact, there's no reason you need the 'fullfile' call unless you are going to want to reference this file from a different directory at some later date.
obj = VideoReader('videoDir/videoname.mp4');
For a more flexible version of this, consider we have a bunch of *.mp4 files in a bunch of sub-directories and we want to step through all of them.
Directory = dir('*/*.mp4'); % this command works on Windows or Linux
for jj = 1:length(Directory)
obj(jj) = VideoReader(fullfile(Directory(jj).folder,Directory(jj).name));
end
I write code where I load a lot of project data. I want to keep my pathnames in the code relative to some location of this project on the disk, i.e. not having it configured or hard-coded.
Is there function in matlab to do some like this?
In python I would write:
ROOT = os.path.dirname(__file__)
The best way to do this is to combine fileparts with mfilename('fullpath'). (All examples assume the executing m-file containing these statements lives in /home/suever/code/stackoverflow.m)
mfiledir = fileparts(mfilename('fullpath'));
/home/suever/code
Then you can use fullfile to construct any paths you need from that. Now if you have a file (data.mat) stored in the same directory:
filename = fullfile(mfiledir, 'data.mat');
/home/suever/code/data.mat
Of if the file is actually in the parent directory.
filename = fullfile(mfiledir, '..', 'data.mat');
/home/suever/data.mat
If you want just the parent directory that an m-file is in, you can apply fileparts twice and only keep the second output.
[~, reldir] = fileparts(fileparts(mfilename('fullpath')));
code
I would recommend the use of full paths in the first examples as those are completely independent of the user's current working directory.
A better recipe to organize your code is to have a function like this:
function [ path ] = get_path()
path = [regexprep(mfilename('fullpath'), ['\' filesep '[\w\.]*$'],'') filesep];
end
You drop it inside +foo/get_path.m file and than call something like foo.get_path() that returns the path to +foo folder.
1) I have an original directory called "Original_file" that contains several number of images. The code below serves to read those images from the directory, converts them to greyscale, then write them into new directory called "Target_File".
Target_File='modified_images';
mkdir(Target_File);
directory='original_images';
dnames = {directory};
cI = cell(1,1);
c{1} = dir(dnames{1});
cI{1} = cell(length(c{1}),1);
for j = 1:length(c{1}),
cI{1}{j} = double(imread([dnames{1} '/' c{1}(j).name]))./255;
cI{1}{j} = rgb2gray(cI{1}{j});
imwrite(cI{1}{j}, fullfile(Target_File, ['image' num2str(j) '.jpg']));
end
2) From the "Target_File": The code below serves to select randomly a specific number of images and put them in a training file.
Train_images='training_file';
mkdir(Train_images);
ImageFiles = dir('Target_File');
totalNumberOfFiles = length(ImageFiles)-1;
scrambledList = randperm(totalNumberOfFiles);
numberIWantToUse = 5; % for example 5
loop_counter = 1;
for index = scrambledList(1 :numberIWantToUse)
baseFileName = ImageFiles(index).name
str = fullfile('Target_File', baseFileName);
image = imread(str);
imwrite( image, fullfile(Train_images, ['image' num2str(index) '.jpg']));
loop_counter = loop_counter + 1;
end
What I want in this question ?
A) If we consider that we have a directory that contains several number of folders (folder1, folder2, ...., foldern). Each of these folders contains several images. So how can I edit my code in 1) in order to apply the same concept and get a new directory "Target_File" that contains the same number of folders, but each folder becomes containing the greyscale images?
Then, from the Target_File created in A) : I want to select (randomly as in 2)) from each folder in Target_File, a specific number of images and put them in training file, and the remaining images in testing file. This procedure is repeated for all folders in the directory.
So if the directory contains 3 folders, each of these folders is split into training and test files. So the first folder is split into train1 and test1, the second directory into train2 and test2, the third directory into train3 and test3, etc. So how to edit my code in 2) ?
Any help will be very appreciated.
You can use the dir command to get a list of sub-directories, and then loop through that list with calls to mkdir to create each one in turn. After that, it is just a matter of matching the file paths so you can save the greyscale image loaded from a source subfolder to its corresponding target folder.
Specifically, D = dir('directory') will return a struct where each element of the structure is an element stored in 'directory'. D(i).isdir will be 1 if D(i).name corresponds to the name of one of your subfolders (note that you will need to ignore D(1:2), as those are the folder navigation tags . and ..). So, get your list of directory contents, and then loop through those calling mkdir if D(i).isdir is 1.
I am not sure I understand the rest of your question, but if you just need a random subsample of the entire image set (regardless of subfolder it is stored in), while you are making your subfolders above you can also make secondary calls of dir to the subfolders to get a list of their contents. Loop through and check whether each element is an image, and if it is save it to an array of image path names. When you have compiled this master list, you can grab a random subset from it.
I have one dir with 50 folders, and each folder has 50 files. I have a script to read all files in each folder and save the results, but I need to type the folder name every time. Is there any loop or batch tools I can use? Any suggestions or code greatly appreciated.
There may be a cleaner way to do it, but the output of the dir command can be assigned to a variable. This gives you a struct, with the pertinent fields being name and isdir. For instance, assuming that the top-level directory (the one with 50 files) only has folders in it, the following will give you the first folder's name:
folderList = dir();
folderList(3).name
(Note that the first two entries in the folderList struct will be for "." (the current directory) and ".." (the parent directory), so if you want the first directory with files in it you have to go to the third entry). If you wish to go through the folders one by one, you can do something like the following:
folderList = dir();
for i = 3:length(folderList)
curr_directory = pwd;
cd(folderList(i).name); % changes directory to the next working directory
% operate with files as if you were in that directory
cd(curr_directory); % return to the top-level directory
end
If the top-level directory contains files as well as folders, then you need to check the isdir of each entry in the folderList struct--if it is "1", it's a directory, if it is "0", it's a file.
I have 4 folders in the same directory where each folder contains ~19 .xls files. I have written the code below to obtain the name of each of the folders and the name of each .xls file within the folders.
path='E:\Practice';
folder = path;
dirListing = dir(folder);
dirListing=dirListing(3:end);%first 2 are just pointers
for i=1:length(dirListing);
f{i} = fullfile(path, dirListing(i,1).name);%obtain the name of each folder
files{i}=dir(fullfile(f{i},'*.xls'));%find the .xls files
for j=1:length(files{1,i});
File_Name{1,i}{j,1}=files{1,i}(j,1).name;%find the name of each .xls file
end
end
Now I'm trying to import the data from excel into matlab by using xlsread. What I'm struggling with is knowing how to load the data into matlab within a loop where the excel files are in different directories (different folders).
This leaves me with a 1x4 cell named File_Name where each cell refers to a different folder located under 'path', and within each cell is then the name of the spreadsheets wanting to be imported. The size of the cells vary as the number of spreadsheets in each folder varies.
Any ideas?
thanks in advance
I'm not sure if I'm understanding your problem, but all you have to do is concatenate the strings that contain directory (f{}) and the file name. Modifying your code:
for i=1:length(dirListing);
f{i} = fullfile(path, dirListing(i,1).name);%obtain the name of each folder
files{i}=dir(fullfile(f{i},'*.xls'));%find the .xls files
for j=1:length(files{1,i});
File_Name{1,i}{j,1}=files{1,i}(j,1).name;%find the name of each .xls file
fullpath = [f{i} '/' File_Name{1,i}{j,1}];
disp(['Reading file: ' fullpath])
x = xlsread(fullpath);
end
end
This works on *nix systems. You may have to join the filenames with a '\' on Windows. I'll find a more elegant way and update this posting.
Edit: The command filesep gives the forward or backward slash, depending on your system. The following should give you the full path:
fullpath = [f{i} filesep File_Name{1,i}{j,1}];
Take a look at this helper function, written by a member of the matlab community.
It allows you to recursively search through directories to find files that match a certain pattern. This is a super handy function to use when looking to match files.
You should be able to find all your files in a single call to this function. Then you can loop through the results of the rdir function, loading the files one at a time into whatever data structure you want.