Recursively read images from subdirectories - matlab

I am stuck on something that is supposed to be so simple.
I have a folder, say main_folder with four sub folders, say sub1, sub2, sub3 and sub4 each containing over 100 images. Now am trying to read and store them in an array. I have looked all over the internet and some MATLAB docs:
here, here and even the official doc.
My code is like this:
folder = 'main_folder/**'; %path containing all the training images
dirImage = dir('main_folder/**/*.jpg');%rdir(fullfile(folder,'*.jpg')); %reading the contents of directory
numData = size(dirImage,1); %no. of samples
arrayImage = zeros(numData, 133183); % zeros matrix for storing the extracted features from images
for i=1:numData
ifile = dirImage(i).name;
% ifolder = dirImage(i).folder;
I=imread([folder, '/', ifile]); %%%% read the image %%%%%
I=imresize(I,[128 128]);
...
If I try the code in the above snippet, the images are not read.
But if I replace the first two lines with something like:
folder = 'main_folder/'; %path containing all the training images
dirImage = dir('main_folder/sub1/*.jpg'); %rdir(fullfile(folder,'*.jpg'));
then all images in sub1 are read. How can I fix this? Any help will be highly appreciated. I want to read all the images in the four sub folders at once.
I am using MATLAB R2015a.

I believe you will need to use genpath to get all sub-folders, and then loop through each of them, like:
dirs = genpath('main_folder/'); % all folders recursively
dirs = regexp(dirs, pathsep, 'split'); % split into cellstr
for i = 1:numel(dirs)
dirImage = dir([dirs{i} '/*.jpg']); % jpg in one sub-folder
for j = 1:numel(dirImage)
img = imread([dirs{i} '/' dirImage(j).name]);
% process img using your code
end
end

Related

Batch process and name/save images in a separate folder

I am running a script to create masks of 41 Controls, both Positive and Negative, for a total of 82 images. I don't know how to save the masks with names similar to the original .png files, such as "Masked Control_1 Positive", "Masked Control_1 Negative", etc to Control_41. I also don't know how to save these to a separate folder within my current folder. Thank you!
I have also included a screenshot of the current directory.
% GlassBrains_Controls2Mask.m
clear;
Files = dir('Control_*');
Controls_Results_Structure = struct('BW',[],'maskedRGBImage',[]);
for i = 1:length(Files)
RGB = imread(Files(i).name);
[Output_BW, Output_maskedRGBImage] = GlassBrainMask(RGB);
Controls_Results_Structure(i).BW = Output_BW;
Controls_Results_Structure(i).maskedRGBImage = Output_maskedRGBImage;
end
save("Controls_Results_Structure")
% Save the results
mkdir "Masked Glass Brains (Controls)"
for i = 1:length(Files)
Image_Number = i;
save(Controls_Results_Structure(Image_Number).BW);
end
Please notice that save() stores workspace variables in MAT files, which are generally meant to be opened with MATLAB only, not with image viewers and such. PNG files like those you are reading with imread() can be created with imwrite():
% Save the results
outdir='./Masked Glass Brains (Controls)';
[mkdir_status,~,~]=mkdir(outdir);
assert(mkdir_status,'Error creating output folder.');
clear mkdir_status;
for i=1:length(Files)
imwrite( Controls_Results_Structure(i).BW, ...
sprintf('%s/Masked %s',outdir,Files(i).name) ... %alternative: [outdir '/Masked ' Files(i).name]
);
end
To customize the image file that imwrite() creates from the output of GlassBrainMask(), see: https://www.mathworks.com/help/matlab/ref/imwrite.html

How to read multiple jpg images in matlab [duplicate]

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.

how to insert noise and save multiple images in different folders using a loop?(matlab)

I am new in image processing and I want help. I have a folder (dataset) that contains 1000 images and I want to insert noise 'salt & pepper' with different density noise (0.01,0.02 and 0.03) , I used this line to do this:
im = imread('C:\Users\SAMSUNG\Desktop\AHTD3A0002_Para1.tif');
J = imnoise(im,'salt & pepper',0.01);
Please help me to do this : I want to save the result in 3 folder ( data1 contains images after noise with d=0.01, data2 contains images after noise with d=0.02 and data3 contains images after noise with d=0.03).
any suggestation and thanks in advance
Following code will allow you to select the folder and create the noised pictures in 3 different folders. It will only select the '*.tif' files which you can modify in the code. And if you need to create more noise levels, create a loop to name the folders and files dynamically.
% get dir
folderX = uigetdir();
% get files
picFiles = dir('*.tif');
% loop over the files and save them with the noise
for ii = 1:length(picFiles)
currentIm = imread([folderX, '\', picFiles(ii).name]);
% create folders if not exist
if ~exist([folderX,'\noise_0.01\'], 'dir')
% create folders
mkdir([folderX,'\noise_0.01\']);
end
if ~exist([folderX,'\noise_0.02\'], 'dir')
% create folders
mkdir([folderX,'\noise_0.02\']);
end
if ~exist([folderX,'\noise_0.03\'], 'dir')
% create folders
mkdir([folderX,'\noise_0.03\']);
end
J1 = imnoise(currentIm,'salt & pepper',0.01);
imwrite(J1,fullfile([folderX, '\noise_0.01\', picFiles(ii).name]));
J2 = imnoise(currentIm,'salt & pepper',0.02);
imwrite(J2,fullfile([folderX, '\noise_0.02\', picFiles(ii).name]));
J3 = imnoise(currentIm,'salt & pepper',0.03);
imwrite(J3,fullfile([folderX, '\noise_0.03\', picFiles(ii).name]));
end
An easy solution with 2 for loop.
%save the noise parameter.
noise = [0.01,0.02,0.03];
for i = 1:1000
%we generate the filename (you can adapt this code)
imname = fullfile('C:\Users\SAMSUNG\Desktop\',sprintf('AHTD3A0002_Para%d.tif',i))
%read the image.
im = imread(imname);
for j = 1:length(noise)
%apply the noise
J = imnoise(im,'salt & pepper',noise(j));
%save image in the right folder
imwrite(J,fullfile('C:\Users\SAMSUNG\Desktop',sprintf('folder%d',j)));
end
end

How to read numbered sequence of .dat files into MATLAB

I am trying to load a numbered sequence of ".dat" named in the form a01.dat, a02.dat... a51.dat into MATLAB. I used the eval() function with the code below.
%% To load each ".dat" file for the 51 attributes to an array.
a = dir('*.dat');
for i = 1:length(a)
eval(['load ' a(i).name ' -ascii']);
end
attributes = length(a);
I ran into problems with that as I could not easily manipulate the data loaded with the eval function. And I found out the community is strongly against using eval. I used the csvread() with the code below.
% Scan folder for number of ".dat" files
datfiles = dir('*.dat');
% Count Number of ".dat" files
numfiles = length(datfiles);
% Read files in to MATLAB
for i = 1:1:numfiles
A{i} = csvread(datfiles(i).name);
end
The csvread() works for me but it reads the files but messes up the order when it reads the files. It reads a01.dat first and then a10.dat and a11.dat and so on instead of a01.dat, a02.dat... The contents of each files are signed numbers. Some are comma-delimited and single column and this is an even split. So a01.dat's contents are comma-delimited and a02.dat's content are in a single column.
Please how do I handle this?
Your problem seems to be sorting of the files. Drawing on a question on mathworks, this should help you:
datfiles = dir('*.mat');
name = {datfiles.name};
[~, index] = sort(name);
name = name(index);
And then you can loop with just name:
% Read files in to MATLAB
for i = 1:1:numfiles
A{i} = csvread(name{i});
end

Subset folder contents Matlab

I have about 1500 images within a folder named 3410001ne => 3809962sw. I need to subset about 470 of these files to process with Matlab code. Below is the section of code prior to my for loop which lists all of the files in a folder:
workingdir = 'Z:\project\code\';
datadir = 'Z:\project\input\area1\';
outputdir = 'Z:\project\output\area1\';
cd(workingdir) %points matlab to directory containing code
files = dir(fullfile(datadir, '*.tif'))
fileIndex = find(~[files.isdir]);
for i = 1:length(fileIndex)
fileName = files(fileIndex(i)).name;
Files also have ordinal directions attached (e.g. 3410001ne, 3410001nw), however, not all directions are associated with each root. How can I subset the folder contents to include 470 of 1500 files ranging from 3609902sw => 3610032sw? Is there a command where you can point Matlab to a range of files in a folder, rather than the entire folder? Thanks in advance.
Consider the following:
%# generate all possible file names you want to include
ordinalDirections = {'n','s','e','w','ne','se','sw','nw'};
includeRange = 3609902:3610032;
s = cellfun(#(d) cellstr(num2str(includeRange(:),['%d' d])), ...
ordinalDirections, 'UniformOutput',false);
s = sort(vertcat(s{:}));
%# get image filenames from directory
files = dir(fullfile(datadir, '*.tif'));
files = {files.name};
%# keep only subset of the files matching the above
files = files(ismember(files,s));
%# process selected files
for i=1:numel(files)
fname = fullfile(datadir,files{i});
img = imread(fname);
end
Something like this maybe could work.
list = dir(datadir,'*.tif'); %get list of files
fileNames = {list.name}; % Make cell array with file names
%Make cell array with the range of wanted files.
wantedNames = arrayfun(#num2str,3609902:3610032,'uniformoutput',0);
%Loop through the list with filenames and compare to wantedNames.
for i=1:length(fileNames)
% Each row in idx will be as long as wantedNames. The cells will be empty if
% fileNames{i} is unmatched and 1 if match.
idx(i,:) = regexp(fileNames{i},wantedNames);
end
idx = ~(cellfun('isempty',idx)); %look for unempty cells.
idx = logical(sum(,2)); %Sum each row