How to rename many images after processing with different parameters - image

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

Related

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

Fast string splitting in MATLAB

I've been using MATLAB to read through a bunch of output files and have noticed that it was reading the files fairly slowly in comparison to a reader that I wrote in Python for the same files (on the order of 120s for MATLAB, 4s for Python on the same set). The files have a combination of letters and numbers, where the numbers I actually want each have a unique string on the same line, but there is no real pattern to the rest of the file. Is there a faster way to read in non-uniformly formatted text files in MATLAB?
I tried using the code profiler in MATLAB to see what takes the most time, and it seemed to be the strfind and strsplit functions. Deeper down, the strfun\private\strescape seems to be the culprit which takes up around 50% of the time, which is called by strsplit function.
I am currently using a combination of strfind and strsplit in order to search through a file for 5 specific strings, then convert the string after it into a double.
lots of text before this
#### unique identifying text here
lots of text before this
sometext X = #####
Y = #####
Z = #####
more text = ######
I am iterating through the file with approximately the following code, repeated for each number that is being found.
fid=fopen(filename)
tline=fgets(fid)
while ischar(tline)
if ~isempty(strfind(tline('X =')))
tempstring=strsplit(tline(13:length(tline)),' ');
result=str2double(char(tempstring(2)));
end
tline=fgets(fid);
end
I'm guessing this will be a bit faster, but maybe not by much.
s = fileread('texto');
[X,s] = strtok(strsplit(s, "X = "){2}); X = str2num(X);
[Y,s] = strtok(strsplit(s, "Y = "){2}); Y = str2num(Y);
[Z,s] = strtok(strsplit(s, "Z = "){2}); Z = str2num(Z);
Obviously this is highly specific to your text example. You haven't given me any more info on how the variables might change etc so presumably you'll have to implement try/catch blocks if files are not consistent etc.
PS. This is octave syntax which allows chaining operations. For matlab, split them into separate operations as appropriate.
EDIT: ach, nevermind, here's the matlab compatible one too. :)
s = fileread('texto');
C = strsplit(s, 'X = '); [X,s] = strtok(C{2}); X = str2num(X);
C = strsplit(s, 'Y = '); [Y,s] = strtok(C{2}); Y = str2num(Y);
C = strsplit(s, 'Z = '); [Z,s] = strtok(C{2}); Z = str2num(Z);

Reading multiple images in IDL

I am writing a program in IDL that requires reading n images (each of m pixels) from a directory, convert them to grayscale, concatenate each image as a single vector, and then form a an m * n matrix from the data.
So far I have managed to read and convert a single image to a grayscale vector, but I can't figure out how to extend this to reading multiple image files.
Can anyone advise on how I could adapt my code in order to do this?
(The image files will all be of the same size, and stored in the same directory with convenient filenames - i.e. testpicture1, testpicture2, etc)
Thanks
pro readimage
image = READ_IMAGE('Z:\My Documents\testpicture.jpg')
redChannel = REFORM(image[0, *, *])
greenChannel = REFORM(image[1, * , *])
blueChannel = REFORM(image[2, *, *])
grayscaleImage = BYTE(0.299*FLOAT(redChannel) + $
0.587*FLOAT(greenChannel) + 0.114*FLOAT(blueChannel))
imageVec = grayscaleImage[*]
end
Use FILE_SEARCH to find the names and number of the images of the given name:
filenames = FILE_SEARCH('Z:\My Documents\testpicture*.jpg', count=nfiles)
You will probably also want to declare an array to hold your results:
imageVec = bytarr(m, nfiles)
Then loop over the files with a FOR loop doing what you are doing already:
for f = 0L, nfiles - 1L do begin
; stuff you are already doing
imageVec[*, f] = grayscaleImage[*]
endfor

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.

Inserting multiple links into an image in Matlab?

This question is built off of this previous question 'here' I want to make 256 points on the image that all lead to different pdf documents based on the location of the *. I dont want to have to code in 256 separate filepaths. I have attempted some code below and have not been having any luck so far.
for i = 1:256
text(x(i),y(i),'*', 'ButtonDownFcn',['open(''' file ''');']);
end
function [filePath] = file()
%h = impoint;
%position = getPosition(h);
filePath = strcat('C:\Documents and Settings\Sentinelle\Desktop\LCModel\sl5_knt1\sl5_',x(1),'-',y(i),'.pdf');
end
It seems to me that your code is wrong in several places:
the file() function doesn't know the values of x and y
the file() function doesn't use the current value of i
the file path uses x(1) idependently of the value of i
You probably want
for i = 1:256
text(x(i), y(i), '*', 'ButtonDownFcn', ['open(''' file(x(i),y(i)) ''');']);
end
function [filePath] = file( x, y )
filePath = strcat('C:\Documents and Settings\Sentinelle\Desktop\LCModel\sl5_knt1\sl5_',x,'-',y,'.pdf');
end
Assuming x(i) and y(i) are integers, this should work:
prefix = 'C:\Documents and Settings\Sentinelle\Desktop\LCModel\sl5_knt1\sl5_'
for i = 1:256
filePath = [prefix num2str(x(i)) '-' num2str(y(i)) '.pdf'];
text(x(i),y(i),'*', 'ButtonDownFcn',['open(''' filePath ''');']);
end
If they aren't integers, you need to specify how the floating point number will be converted to a string. You can do that with the second argument of num2str, type:
help num2str
for details and browse from there.

Resources