Writing to text file in matlab - matlab

I want to do some operations on images and write some data into a txt file.Here is what I am doing for one image-
clc;
image=imread('im.png');
.... %do some operations
....
....
fileID=fopen('first.txt','w');
.... %write onto the txt file
....
fclose(fileID);
But I want to do this for many images.I have stored all the images in a folder.Also, I want to continue writing in the same text file immediately after where I left off for the previous image.How can I modify my code to achieve this?

Well that's pretty simple. Use a loop and loop over all of your images, do your processing on it, then append to the text file. What'll be easier is that you just open the file for your text ONCE, write for as many times as you have images, then finally close it.
Something like this:
folder = ...; %// Place folder here - Example: folder = fullfile('D:', 'images');
fileID=fopen('first.txt','w'); %// Open up the file for writing
f = dir(fullfile(folder, '*.png')); %// look for all PNG files in this folder
for idx = 1 : numel(f)
filename = fullfile(folder, f(idx).name); %// Get the file name
im = imread(filename); %// Read the image in
.... %do some operations
....
....
.... %write onto the txt file
....
fprintf(fileID, '\n\n'); %// Put two carriage returns to make way for next file
end
fclose(fileID);
The function dir scans for all files that match a particular expression. In your case, you want to find all PNG files in a particular folder of your choosing. I assume that this is stored in the variable folder. We then open up the file first before we do anything to the images, then loop over each of the found images with dir. Take note that when you use dir, it only finds the relative paths to the files (i.e. just the names themselves). If you want to locate where the actual images are, you need the absolute paths, which is why we use fullfile.
So, for each PNG image that's in the folder, load it in, do your processing on it, write to your file and I make sure that I put in two carriage returns to separate each result. You repeat this for each PNG image until you exhaust all of them from the folder. Once you're done, you close the text file.
Minor note
image is an actual function in MATLAB that visualizes a matrix of values as an image with a specified colour map. You should probably rename this variable to something else so you don't overshadow the function in case other scripts / functions you write use this function.

Related

pixelLabelDatastore from loaded image in workspace

I have multiple small *.mat files, each containing 4 input images (template{1:4} and a second channel template2{1:4}) and 4 output images (region_of_interests{1:4}), a binarized ('mask') image to train a deep neural network.
I basically followed an example on Mathworks and it suggests to use a function (in this example #matreader) to read in custom file formats.
However ...
It seems impossible to load multiple images from one *.mat file using any load function as it only allows one output, and imageDatastore doen't seem to allow loading data from workspace. How could this be achieved?
Similarly, it seems impossible to load a pixelLabelDatastore from a workspace variable. As a workaround I ended up saving the contents of my *.mat file to an image (using imwrite, saving to save_dir), and re-loading it from there (in this case, the function doesn't even allow to load *.mat files.). (How) can this be achieved without re-saving the file as image?
Here my failed attempt to do so:
%main script
image_dir = pwd; %location of *.mat files
save_dir = [pwd '/a/']; %location of saved output masks
imds = imageDatastore(image_dir,'FileExtensions','.mat','ReadFcn',#matreader); %load template (input) images
pxds = pixelLabelDatastore(save_dir,{'nothing','something'},[0 255]);%load region_of_interests (output) image
%etc, etc, go on to train network
%matreader function, save as separate file
function data=matreader(filename)
in=1; %give up the 3 other images stored in template{1:4}
load(filename); %loads template and template2, containing 4x input images each
data=cat(3,template{in},template2{in}); %concatinate 2 template input images in 3rd dimension
end
%generate example data for this question, will save into a file 'example.mat' in workspace
for ind=1:4
template{ind}=rand([200,400]);
template2{ind}=rand([200,400]);
region_of_interests{ind}=rand([200,400])>.5;
end
save('example','template','template2','output')
You should be able to achieve this using the standard load and save function. Have a look at this code:
image_dir = pwd;
save_dir = pwd;
imds = imageDatastore(image_dir,'FileExtensions',{'.jpg','.tif'});
pxds = pixelLabelDatastore(save_dir,{'nothing','something'},[0 255]);
save('images.mat','imds', 'pxds')
clear
load('images.mat') % gives you the variable "imds" and "pxds" directly -> might override previous variables
tmp = load('images.mat'); % saves all variables in a struct, access it via tmp.imds and tmp.pxds
If you only want to select the variables you want to load use:
load('images.mat','imds') % loads "imds" variable
load('images.mat','pxds') % loads "pxds" variable
load('images.mat','imds','pxds') % loads both variables
EDIT
Now I get the problem, but I fear this is not how it is going to work. The Idea behind the Datastore objects is, that it is used if the data is too big to fit in memory as a whole, but every little piece is small enough to fit in memory. You can use the Datastore object than to easily process and read multiple files on a disk.
This means for you: Simply save your images not as one big *mat file but as multiple small *.mat files that only contain one image.
EDIT 2
Is it strictly necessary to use an imageDatastore for this task? If not you can use something like the following:
image_dir = pwd;
matFiles = dir([image_dir '*.mat']);
for i=1:length(matFiles)
data = load(matFiles(i).name);
img = convertMatToImage(data); % write custom function which converts the mat input to your image
% or something like this:
% for j=1:4
% img(:,:,j) = cat(3,template{j},template2{j});
% end
% process image
end
another alternative would be to create a "image" in your 'matreader' which does not only have 2 bands but to simply put all bands (all templates) on top of each other providing a "datacube" and then in an second step after iterating over all small mat files and reading them splitting the single images out of the one bigger datacube.
would look something like this:
function data=matreader(filename)
load(filename);
for in=1:4
data=cat(3,template{in},template2{in});
end
end
and in your main file, you have to simply split the data into 4 pieces.
I have never tested it but maybe it is possible to return a cell instead of a matrix?
function data=matreader(filename)
load(filename);
data = cell(1,4)
for in=1:4
data{in}=cat(3,template{in},template2{in});
end
end
Not sure if this would work.
However, the right way to go forward from here really depends on how you plan to use the images from imds and if it is really necessary to use a imageDatastore.

How do I save nii files into one nii file using MATLAB

I have 360 3D-nifti files, I want to read all these files and save into one nifti file using Nifti Analyze tool that should yield a 4D file of large size. So far I have written following lines
clear all;
clc;
fileFolder=fullfile(pwd, '\functional');
files=dir(fullfile(fileFolder, '*.nii'));
fileNames={files.name};
for i=1:length(fileNames)
fname=fullfile(fileFolder,fileNames{i});
z(i)=load_nii(fname);
y=z(i).img;
temp(:,:,:,i) = make_nii(y);
save_nii(temp(:,:,:,i), 'myfile.nii')
fprintf('Iter: %d\n', i)
end
This code facilitates with a variable temp that is 4D struct and contains all the images. However, myfile.nii is just one single file its not all the images because its size is just 6mb it should be atleast one 1gb.
Can someone please have a look and let me know where I am wrong?
The way that you have it written, your loop is overwriting myfile.nii since you're calling save_nii every time through the loop with only the latest data. You'll want to instead call save_nii only once outside of the loop and save the entire temp variable at once.
for k = 1:numel(fileNames)
fname = fullfile(fileFolder, fileNames{k});
z(k) = load_nii(fname);
y(:,:,:,k) = z(k).img;
end
% Create the ND Nifti file
output = make_nii(y);
% Save it to a file
save_nii(output, 'myfile.nii')

How do I put a folder as an input in a matlab function?

I need a matlab function that goes through a folder and processes each file in the folder. I'd like to put, as an input, the folder name and the file name that I need to use to process each file in that folder (subtract one image from all the others in the folder). My function also calculates the SD and mean value of each image. I'd like my function to return me a matrix that shows as many rows as the number of images, with 3 columns that indicate: name, SD and mean value of each image, in order to export it to excel. This is my code so far but I'm really missing something!
thanks so much for your help! I've been working on this for days now!
function [m]=nenna(path,t) %# folder path
path=(path)
files = dir( fullfile(path,'*.jpg') ); %# list all *.xyz files
files = {files.name}'; %'# file names
data = cell(numel(files),1);%# store file contents
a=zeros(numel(files),3);
for i=1:numel(files)
fname = fullfile(path,files{i}); %# full path to file
x=imread(files);
s=imread(t);
j=imsubtract(x,s);
j=double(j);
u=std(j(:))
q=mean(j(:))
a(i)=[files(i);u;q]
end
If you want each row in a to have a string and two numbers, it should be a cell array:
...
a=[]
for i ...
...
a{i}={files{i} u q};
end
...
To get to the filenames you do
a{1}{1}
ans=
file1.jpg
To get to the numbers you do
a{1}{2},a{1}{3}
(to get std and mean of file1.jpg, resp.)
Another way to do it is to make a a struct array.

Saving image using MATLAB

I made a program in MATLAB to generate images with different specifications, but each time I change one of theses specifications I had to re-save the image under a different name and path. So, I made a for loop to change these specifications, but I don't know how I can make MATLAB save the generated image with different names and different paths...
How can I write a program to make MATLAB save multiple generated images with different names and different paths as a part of for–loop?
Put something like this at the end of your loop:
for i = 1:n
<your loop code>
file_name=sprintf('%d.jpg',i); % assuming you are saving image as a .jpg
imwrite(your_image, file_name); % or something like this, however you choose to save your image
end
If you want to save JPEG, PNG etc., then see #AGS's post. If you want to save FIG files, use
hgsave(gcf, file_name)
instead of the imwrite line. There's also
print('-djpeg', file_name) %# for JPEG file (lossy)
print('-dpng', file_name) %# for PNG file (lossless)
as an alternative for imwrite.
Since I wanted to save the plots in my loop in a specific folder in my present working directory (pwd), I modified my naming routine as follows:
for s = 1:10
for i = 1:10
<loop commands>
end
end
% prints stimuli to folder created for them
file_name=sprintf('%s/eb_imgs/%0.3f.tif',pwd,s(i)); % pwd = path of present working
% directory and s(i) = the value
% of the changing variable
% that I wanted to document
file_name = /Users/Miriam/Documents/PSYC/eb_imgs/0.700.tif % how my filename appears
print('-dtiff', '-r300', file_name); % this saves my file to my desired location
matlab matlab-path

How to tell MATLAB to open and save specific files in the same directory

I have to run an image processing algorithm on numerous images in a directory.
An image is saved as name_typeX.tif, so there are X different type of images for a given name.
The image processing algorithm takes an input image and outputs an image result.
I need to save this result as name_typeX_number.tif, where number is also an output from the algorithm for a given image.
Now..
How do I tell MATLAB to open a specific typeX file? Also note that there are other non-tif files in the same directory.
How to save the result as name_typeX_number.tif?
The results have to be saved in the same directory where the input images are present. How do I tell MATLAB NOT to treat the results that have been saved as an input images?
I have to run this as background code on a server... so no user inputs allowed.
It sounds like you are wanting to get all files in a directory whose names match a certain format, then process them all automatically. You can do this using the function DIR to get a list of file names in the current directory, then using the function REGEXP to find file names that match a certain pattern. Here's an example:
fileData = dir(); %# Get a structure of data for the files in the
%# current directory
fileNames = {fileData.name}; %# Put the file names in a cell array
index = regexp(fileNames,... %# Match a file name if it begins
'^[A-Za-z]+_type\d+\.tif$'); %# with at least one letter,
%# followed by `_type`, followed
%# by at least one number, and
%# ending with '.tif'
inFiles = fileNames(~cellfun(#isempty,index)); %# Get the names of the matching
%# files in a cell array
Once you have a cell array of files in inFiles that matches the naming pattern you want, you can simply loop over the files and perform your processing. For example, your code might look like this:
nFiles = numel(inFiles); %# Get the number of input files
for iFile = 1:nFiles %# Loop over the input files
inFile = inFiles{iFile}; %# Get the current input file
inImg = imread(inFile); %# Load the image data
[outImg,someNumber] = process_your_image(inImg); %# Process the image data
outFile = [strtok(inFile,'.') ... %# Remove the '.tif' from the input file,
'_' ... %# append an underscore,
num2str(someNumber) ... %# append the number as a string, and
'.tif']; %# add the `.tif` again
imwrite(outImg,outFile); %# Write the new image data to a file
end
The above example uses the functions NUMEL, STRTOK, NUM2STR, IMREAD, and IMWRITE.