Matlab: labeling images stored in a single file based on image name - matlab

I was assigned a matlab assignment where I was given 25000 pictures of cats and dogs all stored in one folder. My question is how can I use the imagedatastore function on matlab to store these files into one single variable containing two labels (cats and dogs). Each image stored in the file follow the following format:
cat.1.png,
cat.2.png,
.....,
cat.N.png,
dog.1.png,
dog.2.png,
.....,
dog.N.png,
Ideally I think labeling them based on image name would probably be the best approach to this. How ever I've tired doing this using various implementations methods but I keep failing. Any advice on this would be greatly appreciated!

The steps for both image data stores are the same:
Find all the image files with a matching name with dir.
Rebuild the full path to these files with fullfile.
Create the image data store with the files.
My code assumes that you are running the script in the same folder in which images are located. Here is the code:
cats = dir('cat.*.png');
files_cats = fullfile({cats.folder}.', {cats.name}.');
imds_cats = imageDatastore(files_cats);
dogs = dir('dog.*.png');
files_dogs = fullfile({dogs.folder}.', {dogs.name}.');
imds_dogs = imageDatastore(files_dogs);
You could also use the short path:
imds_cats = imageDatastore('cat.*.png');
imds_dogs = imageDatastore('dog.*.png');
If you want to use a single image data store and split files into categories within it (without using folder names, since all your files seem to be located in the same directory):
cats = dir('cat.*.png');
cats_labs = repmat({'Cat'},numel(cats),1);
dogs = dir('dog.*.png');
dogs_labs = repmat({'Dog'},numel(dogs),1);
labs = [cats_labs; dogs_labs];
imds = imageDatastore({'cat.*.png' 'dog.*.png'},'Labels',labs);

Related

Save variables as mat files on S3

I would like to save variables as mat files on s3. The example on the official site shows "tall table" only. Maybe I can use the "system" command overstep MATLAB but I am looking for a straight forward solution.
Any suggestion?
It does look like save does not support saving to remote filesystems.
You can, however, write matrices, cells, tables and timetables.
An example which uses writetable:
LastName = {'Smith';'Johnson';'Williams';'Jones';'Brown'};
Age = [38;43;38;40;49];
T = table(Age,LastName)
writetable(T,'s3://.../table.txt')
Note:
To write to a remote location, filename must contain the full path of
the file specified as a uniform resource locator (URL) of the form:
scheme_name://path_to_file/my_file.ext
To obtain the right URL of the bucket, you can navigate to the contents of the s3 bucket, select a file in there, choose Copy path and remove the name of the file (e.g table.txt).
The alternative is, as you mentioned, a system call:
a = rand(5);
save('matExample','a');
system('aws s3api put-object --bucket mybucket --key=s3mat.mat --body=matExample.mat')
the mat file matExample.mat is saved as s3.mat on the server.

How to create a MLImageClassifier in Xcode 10

I'm trying to build a Machine Learning - Image Recognition using Create ML in Xcode 10.1 Playground but I'm having some problems to put my data in the model.
I have a folder with images numbered from 1 to 1336 and a .csv file with 2 columns (the image name and the image classification).
I don't know exactly how to put this in the model.
I have this until now:
import Cocoa
import CreateML
let data = try MLDataTable(contentsOf: URL(fileURLWithPath: "/Users/x/Desktop/CoreML/project/file.csv"))
let(trainingData, testingData) = data.randomSplit(by: 0.8, seed: 1)
let Classifier = try MLImageClassifier *need help here*
let evaluationMetrics = sentimentClassifier.evaluation(on: testingData)
let evaluationAccuracy = (1 - evaluationMetrics.classificationError) * 100
let metaData = MLModelMetadata(author: "x", shortDescription: "Model", version: "1.0")
try classifier.write(to: URL(fileURLWithPath: "/Users/x/Desktop/CoreML/project/XClassifier.mlmodel"))
I believe it is not possible to feed labels to MLImageClassifier via .csv or any other separate file. You have only two options: use file names as labels or use directories as labels (probably preferable in your case of many images):
let model = try MLImageClassifier(trainingData: .labeledDirectories(at: trainingDir))
let evaluation = model.evaluation(on: .labeledDirectories(at: testingDir))
You will need to put images into subdirectories named as labels in your .csv file.
I was just struggling with this myself. Here is a solution to re-organise data for CreateML. All credit goes to Tony T1 who came up with this script.
Place images and CSV file into a single folder.
In Automator, create a new workflow like this:
Run the workflow. Select your CSV and watch the images get sorted into their respective folders!
The script is as follows:
cd "${1%/*}"
while read line
do
FolderName=${line%;*}
ImageName=${line#*;}
mkdir "$FolderName"
mv "$ImageName" "$FolderName"
done < "$1"
DF20 is the starting folder, you can change that to whatever you wish
my CSV was separated by ";". If your CSV is separated by ",", change that symbol in the script (e.g. FolderName=${line%,*} )
In my CSV, classes were columnA and images columnB. Switch this around depending on your case.

How to combine several PNG images as layers in a single XCF image?

I have several PNG images, which I need to combine as individual layers in a new GIMP XCF image. I need to perform this task many times, so a script based solution would be best.
So far i tried to play around with the batch mode of GIMP, but failed miserably.
Instead of script-fu, which uses Scheme, I'd recommend using the GIMP-Python binding for this, since it is far easier to manipulate files and listings.
If you check filters->Python->Console you will b dropped into an interactive mode - at the bottom of it, there will be a "Browse" button which lets you select any of GIMP's procedures in its API and paste it directly in this console.
There is as an API call to "load a file as a layer" - pdb.gimp_file_load_layer -
this however, brings the image to memory, but do not add it to the image - you have to call
pdb.gimp_image_insert_layer afterwards
You can type this directly in the interactive console, or,check one of my other GIMP-related answers, or some resource on GIMP-Python on the web to convert it to a plug-in, which won't require pasting this code each time you want to perform the task:
def open_images_as_layers(img, image_file_list):
for image_name in image_file_list:
layer = pdb.gimp_file_load_layer(image_name)
pdb.gimp_image_insert_layer(img, layer, None, 0)
img = gimp.image_list()[0]
image_list = "temp1.png temp2.png temp3.png"
open_images_as_layers(img, image_list.split())
The second to last line img = ... picks a needed reference to an open image
in GIMP - you could also create a new image using pdb calls if you'd prefer
(example bellow).
The file list is a hardcoded space separated string in the snippet above,
but you can create the file list in any of the ways allowed by Python.
For example, to get all the ".png" file names in a
c:\Documents and Settings\My user\Pictures folder, you could do:
from glob import glob
image_list = glob("c:/Documents and Settings/My user/Pictures/*png")
To create an image programatically:
img = gimp.Image(1024, 768)
pdb.gimp_display_new(img)

load files from two different folders in matlab

Hi and I am little bit new in matlab.
I have two different folders in my laptop, each one contains about 400 different files. I want to load all these files (400 from first folder and 400 from second folder), I tried like that but doesn't work:
folder1=('E:\results\1\');
folder2=('E:\results\2\');
data=load([folder1,'*.m']);
data1=load([folder2,'*.m']);
and then I want to take first file from folder1 and subtracted from first file from folder1 and save it in new folder. and do that for all other files ... etc
can some expert give me any suggerstion!!
thanks in advance.
Pretty sure load takes one file at a time. Try a simple variant like this:
folder1=('E:\results\1\');
folder2=('E:\results\2\');
files1 = dir( [folder1,'*.m'] );
files2 = dir( [folder2,'*.m'] );
data = cell(length(files1),1); % I don't know what's in the mat files, but let's start with a cell array
data1 = cell(length(files2),1);
for ii=1:length(files1)
data{ii} = load(fullfile(folder1,files1(ii).name));
end
for ii=1:length(files2)
data1{ii} = load(fullfile(folder2,files2(ii).name));
end
There are other, more one liner ways, but this is a fairly pedantic.

Open .mat file in matlab or unix - new user

I am going through someone's data analysis files (created in an older version of matlab) and trying to find out what a particular .mat file is that was used in a matlab script.
I am trying to load a .mat file in matlab. I want to see what is in it.
When I type...
load ('file.mat')
the file loads and I see two variables appear in the workspace. jobhelp and jobs.
When I try to open jobs by typing the following in the matlab command window...
jobs
the response is..
jobs =
[1x1 struct]
Does this mean that there is only a 1 x 1 structure in the .mat file? If so, how in the world do I see what it is? I'm even happy to load it in unix, but I don't know how to do that either. Any help would be greatly appreciated as I have a few files like this that I can't get any information from.
Again, a new user, so please make it simple.
Thanks
It means that jobs is a cell array {} and within this cell array is a structure defined
To see the structure and its contents type jobs{1}
I think you are dealing with a SPM5 Batch-File. This variable is an image of the tree-like structure you can see in the Batch-Editor of SPM. Your job consists of one subitem (stats) which could have various subsubitems (like fMRI model specification, model estimation and so on).
To access this structure on the command line just proceed like Nick said:
Each level is a separate cell array that you can access with {#} after the name of the level. Example: jobs{1} shows you that there is a subitem named stats.
Subitems in structs are accessed with a dot. Example: jobes{1}.stats{1} shows you the subitems of the stats-entry.
Notice that there could be more than one entry on each layer: A stats module could (and probably would) contain various subitems. You can access them via jobs{1}.stat{2}, jobs{1}.stats{3} and so on.
The last layer would be the interesting one for you: The structures in here is an image of the options you can choose in the batch-editor.