how to rename images using a loop?

Hello. I have 150 images (images_0, images_1, images_2, ......, images_140) which are saved in 4 folders called : dataset_1, dataset_2, dataset_3 and dataset_4.
I use this code to rename images
mainDirectory = 'C:\Users\Desktop\data';
subDirectory = dir([mainDirectory '/dataset_*']);
for m = 1 : length(subDirectory)
subFolder = dir(fullfile(mainDirectory, subDirectory(m).name,'*.png'));
fileNames = {subFolder.name};
for iFile = 1 : numel( subFolder )
newName = fullfile(mainDirectory, subDirectory(m).name, sprintf('%00d.png',(iFile) ) );
movefile( fullfile(mainDirectory, subDirectory(m).name, fileNames{ iFile }), newName );
end
end
This code works well, but I'm new in MATLAB and I want to change the newName as follows : (number of the dataset)_(name of the image)
For example : 1_images_0, 1_images_1, 2_images_0, 2_images_1, ...
Please, any idea how can I change the newName to rename the images? Please help me and thanks in advance.

6 Comments

I'm not 100% clear on how your code works, but I think the easiest way would be to just concatenate the strings.
Inside the iFile = 1 loop:
newFileName = strcat(num2str(m), '_images_', num2str(iFile),'.png');
newName = fullfile(mainDirectory, subDirectory(m).name, newFileName);
Does that do what you intended? The '_images_','.png' part is hardcoded in this example for clarity, but you could replace it with fileNames{ iFile } and remove the last part if you want to be more flexible.
it not work, that is not the solution that I want.
Why doesn't the solution from jgg not work as expected or isn't the solution that you want? An alternative is to just replace your sprintf call
sprintf('%00d.png',(iFile) )
with
sprintf('%d_images_%00d.png',m,iFile);
No, this is not the solution. when I use "sprintf('%d_images_%00d.png',m,iFile);", the result is wrong, for example the folder dataset_2, the names of the images are: 4_images_1 .... then the result must be 2_images_1
Sorry, I'm not clear what's wrong with the solution I suggested? Are your folders not arranged in order (so dataset 2 is folder 4 for instance?). If so, you should be able to easy adjust the code I gave with a simple lookup matrix.
Or just remove the dataset_ portion and convert the remainder to a string. For example,
folderName = 'dataset_42';
folderId = str2num(strrep(folderName,'dataset_',''));
Or use regexp to do something similar.

Sign in to comment.

 Accepted Answer

This will do it:
% Start with a folder and get a list of all subfolders.
% Finds and prints names of all files in
% that folder and all of its subfolders.
% Similar to imageSet() function in the Computer Vision System Toolbox: http://www.mathworks.com/help/vision/ref/imageset-class.html
clc; % Clear the command window.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
% Define a starting folder.
start_path = pwd; % %'C:\Users\Desktop\data';
if ~exist(start_path, 'dir')
start_path = matlabroot;
end
% Ask user to confirm or change.
uiwait(msgbox('Pick a starting folder on the next window that will come up.'));
topLevelFolder = uigetdir(start_path);
if topLevelFolder == 0
return;
end
% Get list of all subfolders.
allSubFolders = genpath(topLevelFolder);
% Parse into a cell array.
remain = allSubFolders;
listOfFolderNames = {};
while true
[singleSubFolder, remain] = strtok(remain, ';');
if isempty(singleSubFolder)
break;
end
listOfFolderNames = [listOfFolderNames singleSubFolder];
end
numberOfFolders = length(listOfFolderNames)
% Process all image files in those folders.
for k = 1 : numberOfFolders
% Get this folder and print it out.
thisFolder = listOfFolderNames{k};
fprintf('Processing folder %s\n', thisFolder);
% Get ALL files in this folder.
filePattern = sprintf('%s/*.*', thisFolder);
baseFileNames = dir(filePattern);
numberOfImageFiles = length(baseFileNames);
if numberOfImageFiles >= 1
% Go through all those files.
for f = 1 : numberOfImageFiles
existingFullFileName = fullfile(thisFolder, baseFileNames(f).name);
if isdir(existingFullFileName)
% Skip folders . and ..
continue;
end
% Get the last character of the folder. It should be a number from 1 to 4.
lastDigit = thisFolder(end);
% Create a new name for it.
newBaseFileName = sprintf('%s_images_%d.png', lastDigit, f-1);
newFullFileName = fullfile(thisFolder, newBaseFileName);
fprintf(' Renaming file %s to %s\n', existingFullFileName, newFullFileName);
% Do the actual renaming.
movefile(existingFullFileName, newFullFileName);
end
else
fprintf(' Folder %s has no files in it.\n', thisFolder);
end
end

9 Comments

thank you very much for your answer, it works for this example. but when I used an other database that contains 14 files (14 dataset), I did not get the right result. the program running until the 9 first datasets but then it renames pictures from 0 as here:
1_images_1,......
2_images_1,......
3_images_1,......
4_images_1,......
5_images_1,......
6_images_1,......
7_images_1,......
8_images_1,......
9_images_1,......
% the error begin here
0_images_1,......% but the right name : 10_images_1,......
1_images_1,......% but the right name : 11_images_1,......
2_images_1,......% but the right name : 12_images_1,......
3_images_1,......% but the right name : 13_images_1,......
4_images_1,......% but the right name : 14_images_1,......
please help me how do it?
Get the number from after the "dataset_" like this
% Get the string from after the "dataset_"
% It should be an integer number.
% Use str2double() to get it as a number.
lastDigits = str2double(thisFolder(9:end));
% Create a new name for it.
newBaseFileName = sprintf('%d_images_%d.png', lastDigits, f-1);
Note how I used %d instead of %s in sprintf() now that lastDigits is a number not a single character.
I'm sorry for the late reply but when I used this code. the name of the images become:
NaN_images_1
NaN_images_2
NaN_images_3
NaN_images_4
........................
how can I correct this problem please and thanks in advance
Replace this line
lastDigits = str2double(thisFolder(9:end));
with these
fprintf('Folder = %s\n', thisFolder);
fprintf('The last digits = %s\n', thisFolder(9:end));
lastDigits = str2double(thisFolder(9:end));
fprintf('That converts to %d.\n', lastDigits);
What do you learn in the command window? What does it print out? I think thisFolder must not have the format you said it did.
I found the same result, a part of the output command window is in the attached picture.
according to you, what is the problem?
Try this:
% Start with a folder and get a list of all subfolders.
% Finds and prints names of all files in
% that folder and all of its subfolders.
% Similar to imageSet() function in the Computer Vision System Toolbox: http://www.mathworks.com/help/vision/ref/imageset-class.html
clc; % Clear the command window.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
% Define a starting folder.
start_path = 'd:\data'; % %'C:\Users\Desktop\data';
if ~exist(start_path, 'dir')
start_path = matlabroot;
end
% Ask user to confirm or change.
uiwait(msgbox('Pick a starting folder on the next window that will come up.'));
topLevelFolder = uigetdir(start_path);
if topLevelFolder == 0
return;
end
% Get list of all subfolders.
allSubFolders = genpath(topLevelFolder);
% Parse into a cell array.
remain = allSubFolders;
listOfFolderNames = {};
while true
[singleSubFolder, remain] = strtok(remain, ';');
if isempty(singleSubFolder)
break;
end
listOfFolderNames = [listOfFolderNames singleSubFolder];
end
numberOfFolders = length(listOfFolderNames)
% Process all image files in those folders.
for k = 1 : numberOfFolders
% Get this folder and print it out.
thisFolder = listOfFolderNames{k};
fprintf('Processing folder %s\n', thisFolder);
% Get ALL files in this folder.
filePattern = sprintf('%s/*.*', thisFolder);
baseFileNames = dir(filePattern);
numberOfImageFiles = length(baseFileNames);
if numberOfImageFiles >= 1
% Go through all those files.
for f = 1 : numberOfImageFiles
existingFullFileName = fullfile(thisFolder, baseFileNames(f).name);
if isdir(existingFullFileName)
% Skip folders . and ..
continue;
end
% Get the last character of the folder. It should be a number from 1 to 4.
lastDigit = thisFolder(end);
% Get the base file name
[folder, baseFileName, ext] = fileparts(existingFullFileName);
% Create a new name for it.
newBaseFileName = sprintf('%s_%s%s', lastDigit, baseFileName, ext);
newFullFileName = fullfile(thisFolder, newBaseFileName);
fprintf(' Renaming file %s to %s\n', existingFullFileName, newFullFileName);
% Do the actual renaming.
movefile(existingFullFileName, newFullFileName);
end
else
fprintf(' Folder %s has no files in it.\n', thisFolder);
end
end
Unfortunately, when I tested the latter code. the result is true only for these folders(1 to 9) but for others folder (10 to 14), the result is
0_SentenceImage_0, 0_SentenceImage_1
1_SentenceImage_0, 1_SentenceImage_1
2_SentenceImage_0, 2_SentenceImage_1
3_SentenceImage_0, 3_SentenceImage_1
4_SentenceImage_0, 4_SentenceImage_1
the used database is attached. please, can you specify exactly what is the error? and thanks in advance.
Originally you said it only went up to 4 but now you say it can go past 9 and be two or more digits. The code I wrote was for what you said originally. If you want a more general solution, then replace this line
% Get the last character of the folder. It should be a number from 1 to 4.
lastDigit = thisFolder(end);
with this code to extract everything after the underline.
% Get the last characters of the folder, after the only underline.
% It should be a number.
underlineLocation = strfind(thisFolder, '_');
lastDigit = thisFolder((underlineLocation +1):end);
Of course this will also fail if you present thisFolder that has no underlines or more than 1 underline. You'd need more code to detect and handle those situations.
thank you very much, that is the solution that I'm looking for

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!