Variable as argument for imread in Matlab? - image

I am trying to run an image analysis script on ~5,000 files in Matlab. I'm trying to run the main part of the script inside a for loop and iterate across every file name. I've listed the directory as a a variable and have come up with something like the following:
images = dir
images.name
imagesdim = size(images)
imageslength = imagesdim(1)
for i = 1:imageslength
cimg = imread(images(i,1).name);
etc etc
end
However, this doesn't seem to be an acceptable input argument for imread. Is there any way I can format this list so that I can use a variable here, or will I have to copy this argument 5,000 times?

I do this in directories of images using the function form of the dir command. For example, if you are working with TIFF files:
dir_items = dir('*.tiff');
file_names = {dir_items.name};
disp('Using .tiff files found in current directory:')
disp(file_names');
for k = 1:length(file_names)
disp(file_names{k})
cimg = imread(file_names{k});
end
If you can't use the wildcard filter like "*.tiff", then you have to check the isdir field of each struct in the array, like so:
dir_items = dir;
for k = 1:length(dir_items)
if dir_items(k).isdir==1
fprintf(1,'%s is a directory (ignore)\n',dir_items(k).name)
else
disp(dir_items(k).name)
cimg = imread(dir_items(k).name)
end
end

A much easier way of iterating through a folder, or nested folder of images in MATLAB is to use imageDatastore.
imds = imageDatastore(desiredDirectory,"FileExtensions",[".tif",".tiff"]);
while hasdata(imds)
img = read(imds);
% Your code that operates on img
end

Related

How do I create a function that takes a .mat file and saves a pngs for each of the arrays?

I want to automate the imwrite function so that I can automatically create 184 pngs from my .mat data. I want to make a loop so that for each loop, the mat array increases in time by 1, and the save name increases by 1.
The inputs should look like this:
imwrite(stim_windows(:,:,1), 'C:\Users\mattmd\Downloads\Retinotopy-master\Retinotopy-master\Presentation\subjects\0007\pRF\221117\run49.1.png')
imwrite(stim_windows(:,:,2), 'C:\Users\mattmd\Downloads\Retinotopy-master\Retinotopy-master\Presentation\subjects\0007\pRF\221117\run49.2.png')
etc.
I tried making this function here:
function wewrite = wewrite(mypath, number_of_files)
global imwrite()
s = 1;
while s < number_of_files
filename = [mypath,(s),'.png'];
imwrite(:,:,s), filename;
s=s+1;
end
When I try inputting:
wewrite('C:\Users\mattmd\Downloads\Retinotopy-master\Retinotopy-master\Presentation\subjects\0007\pRF\221117\0007_stimulus_window_bar_run_49.mat',184)
It tells me that it's an invalid expression.
Any help is greatly appreciated!!

How do you change parts of a string with a list variable in a for loop?

I want to open many files to do an analysis through python.
The title changes in three ways, ID, intervention and drug_type
So I define the path where the files are and create three list variables which contain the names I want to swap parts of the string with.
path = r'R:\Storage\healthsciences\SPRH\pwelch'
ID = ['P1','P2','P3','P4','P5']
intervention = ['intervention1','intervention2']
drug_type = ['drug1','drug2','drug3','drug4']
filename = P1_intervention1_drug2_pwelch_output
How would I get the different sections to change in a for loop?
So..
filename =
[ID]'_'[intervention]'_'drug_type'_pwelch_output.mat'
with each list variable changing as it loops over
Any push in the right direction is much appreciated :)
ids = ['P1','P2','P3','P4','P5']
interventions = ['intervention1', 'intervention2']
drug_types = ['drug1','drug2','drug3','drug4']
for id in ids:
for intervention in interventions:
for drug_type in drug_types:
filename = f"{id}_{intervention}_{drug_type}_pwelch_output.mat"
# use the filename

How to rename many images after processing with different parameters

Hello dear programmers,
I have a sequence of images and I would like to perform dilation on each of them with different dilation parameters. Then, I would like to save the processed images with new name including both the old name and the corresponding dilation parameter. My codes are as follows.
Input_folder =
Output_folder =
D = dir([Input_folder '*.jpg']);
Inputs = {D.name}';
Outputs = Inputs; % preallocate
%print(length(Inputs));
for k = 1:length(Inputs)
X = imread([Input_folder Inputs{k}]);
dotLocations = find(Inputs{k} == '.');
name_img = Inputs{k}(1:dotLocations(1)-1);
image1=im2bw(X);
vec = [3;6;10];
vec_l = length(vec);
for i = 1:vec_l
%se = strel('disk',2);
fprintf(num2str(vec(i)));
se = strel('diamond',vec(i)); %imdilate
im = imdilate(image1,se);
image2 = im - image1;
Outputs{k} = regexprep(Outputs{k}, name_img, strcat(name_img,'_', num2str(vec(i))));
imwrite(image2, [Output_folder Outputs{k}])
end
end
As it can be seen, I would like to apply dilation with parameters 3,6 and 10. Let us assume that an image has as name "image1", after processing it, I would like to have "image1_3", "image1_6" and "image1_10". However, I am getting as results "image1_3", "image1_6_3" and "image1_10_6_3". Please, how can I modify my codes to fix this problem?
This is because you rewrite each item of the Outputs variable three times, each time using the previous value to create a new value. Instead, you should use the values stored in Inputs new names. Another mistake in your code is that the size of Inputs and Outputs are equal, while for every file in the input folder, three files must be stored in the output folder.
I also suggest using fileparts function, instead of string processing, to get different parts of a file path.
vec = [3;6;10];
vec_l = length(vec);
Outputs = cell(size(Inputs, 1)*vec_l, 1); % preallocate
for k = 1:length(Inputs)
[~,name,ext] = fileparts([Input_folder Inputs{k}]);
% load image
for i = 1:vec_l
% modify image
newName = sprintf('%s_%d%s', name, vec(i), ext);
Outputs{(k-1)*vec_l+i} = newName;
imwrite(image2, [Output_folder newName])
end
end

Matlab: reading images from folder does not return filenames in order

I am reading jpg files from a folder. My code is as follows:
inputImg= dir('C:\Documents and Settings\Administrator\Desktop\TestImages\*.jpg');
inputDir = 'C:\Documents and Settings\Administrator\Desktop\TestImages\';
inputN = {inputImg.name};
for i = 1:numel(dstNFiles)
dstFileName = dstImageFiles(i).name;
dstName = strcat(dstDir,dstFileName);
image = imread(dstName);
%% do some work here
end
All those jpg images in my forlder are orderly named in the manner "01.jpg, 02.jpg,...200.jpg". But I found that it is not reading these files in order. I tried to print the dstFileName, and it gives totally random ordered filenames, like:
01.jpg, 02.jpg, 03.jpg, 04.jpg,05.jpg,06.jpg,07.jpg,08.jpg,09.jpg,10.jpg,100.jpg,101.jpg,11.jpg, ... 199.jpg,200.jpg, 24.jpg,25.jpg,...
How could I solve this? Thanks.
The file list is in the correct alphabetic order!
Consider using padding when saving.
Ie. save 10.jpg as 0010.jpg
If you can't change the file name you have to write your own ordering function.

Load all the images from a directory

I have certain images in a directory and I want to load all those images to do some processing. I tried using the load function.
imagefiles = dir('F:\SIFT_Yantao\demo-data\*.jpg');
nfiles = length(imagefiles); % Number of files found
for i=1:nfiles
currentfilename=imagefiles(i).name;
I2 = imread(currentfilename);
[pathstr, name, ext] = fileparts(currentfilename);
textfilename = [name '.mat'];
fulltxtfilename = [pathstr textfilename];
load(fulltxtfilename);
descr2 = des2;
frames2 = loc2;
do_match(I1, descr1, frames1, I2, descr2, frames2) ;
end
I am getting an error as unable to read xyz.jpg no such file or directory found, where xyz is my first image in that directory.
I also want to load all formats of images from the directory instead of just jpg...how can i do that?
You can easily load multiple images with same type as follows:
function Seq = loadImages(imgPath, imgType)
%imgPath = 'path/to/images/folder/';
%imgType = '*.png'; % change based on image type
images = dir([imgPath imgType]);
N = length(images);
% check images
if( ~exist(imgPath, 'dir') || N<1 )
display('Directory not found or no matching images found.');
end
% preallocate cell
Seq{N,1} = []
for idx = 1:N
Seq{d} = imread([imgPath images(idx).name]);
end
end
I believe you want the imread function, not load. See the documentation.
The full path (inc. directory) is not held in imgfiles.name, just the file name, so it can't find the file because you haven't told it where to look. If you don't want to change directories, use fullfile again when reading the file.
You're also using the wrong function for reading the images - try imread.
Other notes: it's best not to use i for variables, and your loop is overwriting I2 at every step, so you will end up with only one image, not four.
You can use the imageSet object in the Computer Vision System Toolbox. It loads image file names from a given directory, and gives you the ability to read the images sequentially. It also gives you the option to recurse into subdirectories.

Resources