How to take image from multi folders?

Hi everybody
I have a few thousand folders, each folder contains 2 images with information in their name, i want to take randomly 1 image from each folder and put all the taken images into one new folder in desktop for further calculation, please help, thank you very much.

4 Comments

Use the ** expansion for dir, after which you can use rand. What did you try?
I got the info by using dir, and still trying to find the way to pick image from each files, should i write by function ? please help thank you
You mean you want to read an image? If you know the file names you can just use imread.
Read image is the next step of computing these files, the main thing i want to do is taking 1 random image from each subfolder, and there are 2900 subfolders in 1 folder to add to path in matlab :((((((

Sign in to comment.

 Accepted Answer

Monalisa Pal
Monalisa Pal on 21 Jun 2020
Edited: Monalisa Pal on 22 Jun 2020
Hi,
'fetching a random image' part of the following code may help you
clearvars -global
clearvars
close all
clc
% creating destination folder
destination = 'destinationfolder';
mkdir(destination);
n_folders = 10; % say there are 10 folders
for i = 1:n_folders
% fetching the contents of the folders
foldername = ['folder_', num2str(i), '/'];
path = [foldername, '*.png']; % or other imgfile extensions
contents = dir(path);
% fetching a random image
if numel(contents) < 2
error([foldername, ' has only ', num2str(numel(contents)), ' image files']);
end
img_index = randi([1, numel(contents)], 1);
disp(['From ', foldername, ' copying ', contents(img_index).name]);
source = [foldername, contents(img_index).name];
copyfile(source, destination);
end

20 Comments

I got the error using rand
It showed "Error using randi
First input must be a positive scalar integer value IMAX, or two integer values [IMIN IMAX] with IMIN less than or equal to IMAX."
One of your folders has no .png files in it. You should adjust the .png in the code to the extension that is appropriate to your situation.
If some of your directories have no files of appropriate file extension, then how would you like to select randomly from the zero files in the directory?
Thank you Mr. Walter
i put the expansion from the one below but still got the same error.
path = [foldername, '\.(jpg|gif|png|jpeg|bmp)'];
most of the subfolders contains .jpg images, thank you for ur help
exts = {'*.jpg', '*.gif', '*.png', '*.jpeg', '*.bmp'};
for i = 1:n_folders
% fetching the contents of the folders
foldername = ['folder_', num2str(i), '/'];
contents = celllfun(@(E) dir( fullfile(foldername, E) ), exts, 'uniform', 0);
if isempty(contents)
fprintf('caution: folder "%s" had no useable images\n', foldername);
continue;
end
% fetching a random image
img_index = randi([1, numel(contents)], 1);
filename = fullfile(foldername, contents(img_index).name);
copyfile(filename, destination);
end
Thank you so much for pointing it out. I edited the above code to provide an error check.
Could you please check the following two things?
1) What is the extension for your image files? I used .png in the path. If it is different for you, kindy edit that line.
2) Does all your folders have atleast 2 images? I understand it is difficult to check manually. I have added an error check, it will tell you the name of the folder which has less than 2 images.
Let me know if the fix works or if it gives more errors.
Thank you, Ms. Monalisa Pal and Mr. Walter Roberson, i belive that this one should be right
clear;
clearvars -global
clearvars
close all
clc
% creating destination folder
destination = 'Images_place';
mkdir(destination);
n_folders = 2950; % say there are 10 folders
exts = {'*.jpg', '*.gif', '*.png', '*.jpeg', '*.bmp'};
for i = 1:n_folders
% fetching the contents of the folders
foldername = ['Bigfolder', num2str(i), '/'];
contents = cellfun(@(E) dir( fullfile(foldername, E) ), exts, 'uniform', 0);
if isempty(contents)
fprintf('caution: folder "%s" had no useable images\n', foldername);
continue;
end
% fetching a random image
img_index = randi([1, numel(contents)], 1);
filename = fullfile(foldername, contents(img_index).name);
copyfile(filename, destination);
end
But in the line
filename = fullfile(foldername, contents(img_index).name);
i got the error showed 'Dot indexing is not supported for variables of this type'
in the 'Bigfolder' i have 2950 subfolders and each subfolder has 2 images in the range from .jpg, .png and etc
The variables may be to large to be processed
contents_parts = cellfun(@(E) dir( fullfile(foldername, E) ), exts, 'uniform', 0);
contents = vertcat(contents_parts{:});
How about this?
clearvars -global
clearvars
close all
clc
% creating destination folder
destination = 'Images_place';
mkdir(destination);
n_folders = 2950; % say there are 2950 folders
for i = 1:n_folders
% fetching the contents of the folders
foldername = ['Bigfolder', num2str(i), '/'];
contents = [dir(fullfile(foldername,'*.png')); dir(fullfile(foldername,'*.jpg')); dir(fullfile(foldername,'*.gif')); dir(fullfile(foldername,'*.jpeg')); dir(fullfile(foldername,'*.bmp'))];
% fetching a random image
img_index = randi([1, numel(contents)], 1);
filename = fullfile(foldername, contents(img_index).name);
copyfile(filename, destination);
end
Dear Ms. Monalisa, the code still got the error "Error using randi
First input must be a positive scalar integer value IMAX, or two integer values [IMIN IMAX] with IMIN less than or equal to IMAX." in the line:
img_index = randi([1, numel(contents)], 1);
contents = [dir(fullfile(foldername,'*.png')); dir(fullfile(foldername,'*.jpg')); dir(fullfile(foldername,'*.gif')); dir(fullfile(foldername,'*.jpeg')); dir(fullfile(foldername,'*.bmp'))];
is generally viable, but it gets to be a pain to extend as you add more image file types.
But no matter what you do, you should check that you got at least one image before trying to randomize over the number of images.
Dear Mr. Roberson, the code ran but i only got this sentence from the output section:
caution: folder "Bigfolder1/" had no useable images
caution: folder "Bigfolder2/" had no useable images
caution: folder "Bigfolder3/" had no useable images
caution: folder "Bigfolder4/" had no useable images
....
What do you see if you
ls Bigfolder1
Note that the code works silently, not outputing anything as it copies images, only warning when it cannot copy. You should look in destinationfolder to see whether images got copied there.
D. Frank
D. Frank on 22 Jun 2020
Edited: D. Frank on 22 Jun 2020
take random from each subfolders is really a pain :(((, but it is sure that most are .jpg in each subfolder
when i ran
ls Bigfolder
it shows all the different names of the subfolders such as:
. 19fv20 1g4kox 1jbndn 1mlwl4 1oxx2w 1tpnv5 209468 262s2b ...
and in the destination file, it is blank
ls Bigfolder1
and tell us what the output is ?
Dear Mr. Frank,
I was not familiar with cellfun. Many thanks to Mr. Roberson for mentioning it. Since you mentioned that there are definitely 2 images in each folder, I had removed the check. But it definitely helps in debugging. Incorporating his suggestions here's how the code looks like:
clearvars -global
clearvars
close all
clc
% creating destination folder
destination = 'Images_place';
mkdir(destination);
n_folders = 2950; % say there are 2950 folders
exts = {'*.jpg', '*.gif', '*.png', '*.jpeg', '*.bmp'};
for i = 1:n_folders
% fetching the contents of the folders
foldername = ['Bigfolder', num2str(i), '/'];
contents_parts = cellfun(@(E) dir( fullfile(foldername, E) ), exts, 'uniform', 0);
contents = vertcat(contents_parts{:});
% fetching a random image
if isempty(contents)
fprintf(1, 'caution: folder "%s" had no useable images\n', foldername);
continue;
end
img_index = randi([1, numel(contents)], 1);
disp(['From ', foldername, ' copying ', contents(img_index).name]);
filename = fullfile(foldername, contents(img_index).name);
copyfile(filename, destination);
end
If this doesn't work, could you please share a screenshot of your command window and workspace? I might help in debugging the code futher.
i think that i need to add to path all the subfolders in the bigfolder one
Mr. Frank, I misunderstood the directory structure earlier. Lets see if this works.
clearvars -global
clearvars
close all
clc
% creating destination folder
destination = 'Images_place';
mkdir(destination);
folder = 'Bigfolder';
sub_folders = dir(folder);
%n_folders = 2950; % say there are 2950 folders
% n_folders = numel(sub_folders) - 2;
exts = {'*.jpg', '*.gif', '*.png', '*.jpeg', '*.bmp'};
for i = 3:numel(sub_folders)
% fetching the contents of the folders
foldername = ['Bigfolder/', sub_folders(i).name, '/'];
contents_parts = cellfun(@(E) dir( fullfile(foldername, E) ), exts, 'uniform', 0);
contents = vertcat(contents_parts{:});
% fetching a random image
if isempty(contents)
fprintf(1, 'caution: folder "%s" had no useable images\n', foldername);
continue;
end
img_index = randi([1, numel(contents)], 1);
disp(['From ', foldername, ' copying ', contents(img_index).name]);
filename = fullfile(foldername, contents(img_index).name);
copyfile(filename, destination);
end
Dear Ms. Monalisa Pal and Mr. Roberson, the code ran smoothly, thank you very much for your patience and your help.

Sign in to comment.

More Answers (0)

Categories

Find more on Programming in Help Center and File Exchange

Products

Asked:

on 19 Jun 2020

Commented:

on 22 Jun 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!