Locate the indexes of rows in Matlab - matlab

I have stored in a struct file in matlab a database and the correspondant label files. In order to read my database matrix from the struct into a matrix I am using the following matlab command:
train_data_matrix = (cat(1, train_data.f2));
The size of the train_data struct is 883. However since there are some empty samples in the end the size of the train_data_matrix is 833. My problem is that I have annotation for all the samples. Thereby the size of the annotation is 883x1 How can I remove from the annotation vector the rows that are empty in the database matrix?

You can use isempty to check for missing values and remove them
% Store data in a cell array (preserves missing values)
tmp = {train_data.f2};
% Create a logical array that is TRUE where the missing values are
toremove = cellfun(#isempty, tmp);
% Convert to an array (removes missing values as you've mentioned)
data = cat(1, tmp{:});
% Create an array of annotations (after removing the ones that are missing data)
annotations = cat(1, train_data(~toremove).annotations);

Related

Storing image data as a row vector

I have multiple images in a folder, and for each image, I want to store the data(pixel values) as a row vector. After I store them in a row vector I can combine these row vectors as one multi dimensional array. e.g. the data for the first image will be stored in row 1, the data for the second image will be stored in row 2 and so on. And any time I want to access a particular image data, let us say I want the third image, I can do something like this race(3,:).
I am currently getting the error:
Dimensions of matrices being concatenated are not consistent.
The error occurs here race = [race; imagevec] I am lost in how to correct this, unless imagevec = I(:)' is not converting the matrix to a row vector .
race = []; % to store all row vector
imagevec = []; % to store row vector
path = 'C:\Users\User_\somedir\'; % directory
pathfile = dir('C:\Users\User_\somedir\*.jpg'); % image file extension in directory
for i = 1 : length(path)
filename = strcat(path,pathfile(i).name); % get the file
I = imread(filename); % read file
imagevec = I(:)'; % convert image data to row vector
race = [race; imagevec]; % store row vector in matrix
end
Using a cell array instead of a matrix will allow you to index in this way even if your images are of different sizes.
You don't even have to turn them into a row vector to store them all in the same structure. You can do something like this:
path = 'C:\Users\User_\somedir\'; % directory
pathfile = dir([path,*.jpg']); % image file extension in directory
race = cell(length(pathfile),1);
for i = 1 : length(pathfile)
filename = strcat(path,pathfile(i).name); % get the file
I = imread(filename); % read file
race{i} = I; % store in cell array
end
Then when you want to perform some operation, you can simply index into the cell array. You could even turn it into a row vector, if you wanted to, as follows.
thisImage = race{3}(:)';
If you are using a matrix to store the results, all rows of a matrix must be the same length.
Cell arrays are similar to arrays except the elements need not be the same type / size.
You can accomplish what you are looking for using a cell array. First, initialize race to:
race = {};
Then try:
race = {race{:}, imagevec};

Adding size information of dataset to file name

I have several datasets, called '51.raw' '52.raw'... until '69.raw' and after I run these datasets in my code the size of these datasets changes from 375x91x223 to sizes with varying y-dimensions (i.e. '51.raw' output: 375x45x223; '52.raw' output: 375x50x223, ... different with each dataset).
I want to later save the '.raw' file name with this information (i.e. '51_375x45x223.raw') and also want to use the new dataset size to later reshape the dataset within my code. I have attempted to do this but need help:
for k=51:69
data=reshape(data,[375 91 223]); % from earlier in the code after importing data
% then executes code with dimensions of 'data' chaging to 375x45x223, ...
length=size(data); dimensions.([num2str(k)]) = length; %save size in 'dimensions'.
path=['C:\Example\'];
name= sprintf('%d.raw',k);
write([path name], data);
% 'write' is a function to save the dat in specified path and name (value of k). I don't know how to add the size of the dataset to the name.
Also later I want to reshape the dataset 'data' for this iteration and do a reshape with the new y dimensions value.
i.e. data=reshape(data,[375 new y-dimension 223]);
Your help will be appreciated. Thanks.
You can easily convert your dimensions to a string which will be saved as a file.
% Create a string of the form: dim1xdim2xdim3x...
dims = num2cell(size(data));
dimstr = sprintf('%dx', dims{:});
dimstr = dimstr(1:end-1);
% Append this to your "normal" filename
folder = 'C:\Example\';
filename = fullfile(folder, sprintf('%d_%s.raw', k, dimstr));
write(filename, data);
That being said, it is far better include this dimension information within the file itself rather than relying on the filename.
As a side note, avoid using names of internal functions as variable names such as length, and path. This can potentially result in strange and unexpected behavior in the future.
Update
If you need to parse the filename, you could use textscan to do that:
filename = '1_2x3x4.raw';
ndims = sum(filename == 'x') + 1;
fspec = repmat('%dx', [1 ndims]);
parts = textscan(filename, ['%d_', fspec(1:end-1)]);
% Then load your data
% Now reshape it based on the filename
data = reshape(data, parts{2:end});

Copy a data from a file into a structure

I need help in designing a data structure to store the storm data from the file. I am going to use these field names: code, amount, duration, and intensity. The intensity is the rainfall amount divided by the duration.(what should I do to in order to calculate the intensity?) I loaded the data into the variable "mydata", then copied my data into a vector of structs called "vecdata".
My final vector of structures should have the same number of elements as the number of rows in the data file. Additionally, it should have the 4 fields with the field names I mentioned above.
% Creating an example data file
anum = randi([3,10]);
thedata = [randi([1,350],anum,1),rand(anum,1)*5,rand(anum,1)*15];
save mydata.dat thedata -ascii
clear
% loaded the data using the load function into "mydata":
mydata = load('mydata.dat')
% Tried to copy the data from "mydata" into a vector of structures called "vecdata":
vecdata = [struct('code','amount','duration','intensity')];
This is a very general question. How can I copy the data from the file above? Rows of mydata must match the # of elements in vecdata. How do I check this?
%first of all, calculate the missing intensity
mydata(:,end+1)=mydata(:,3)./mydata(:,2);
%define the fieldnames for your struct
labels={'code','amount','duration','intensity'};
%there is no array2struct, so we convert to cell first and use cell2struct.
cell2struct(num2cell(mydata),labels,2)

Create an array of 'Geostruct' Data in Matlab

Right now I am creating mapstructs in Matlab and then exporting them individually as shape files using the shapewrite() function.
However, instead of exporting them individually I want to store all of them into an array and then save it at the end as one single shapefile which holds all of the points from the mapstructs stored in the array.
My problem is I don't know how to initialize an array to hold these mapstructs. I've tried
`a = struct(sizeofarray)`
but it isn't compatible with mapstructs. I would appreciate any help!
You can store any kind of data in a cell array:
a = cell(sizeofarray,1);
You can then assign them like this:
a{1} = firstmapstruct;
a{2} = secondmapstruct;
However, if I understand you correctly you have mapstructs from the MATLAB Mapping Toolbox and want to concat structs of this form:
firstmapstruct =
609x1 struct array with fields:
Geometry
BoundingBox
X
Y
STREETNAME
RT_NUMBER
CLASS
ADMIN_TYPE
LENGTH
So you should probably do
a = firstmapstruct;
a(end+1:end+numel(secondmapstruct))= secondmapstruct;
and so on...
If all of your individual mapstructs have the same fields, you should be able to initialize a structure array by replicating one of your mapstructs using the function REPMAT:
a = repmat(mapstruct1,1,N); %# A 1-by-N structure array
Then just fill in each element as needed:
a(2) = mapstruct2; %# Assign another mapstruct to the second array element
a(3).X = ...; %# Assign a value to the X field of the third element
a(3).Y = ...; %# Assign a value to the Y field of the third element
You can find out more information about Geographic Data Structures in this documentation.

Possibly incorrect Matlab error: "Subscripted assignment dimension mismatch"

Matlab is giving me the error, "Subscripted assignment dimension mismatch" however I don't think there should be an issue. The code is below but basically I have a temp matrix that mimics the dimensions of another matrix, testData (actually a subset of it). I can assign the output of imread to the temp matrix but not to a subset of testData that has the same dimensions. I can even use the size function to prove they are the same dimensions yet one works and one doesn't. So I set temp = imread and then testData = temp and it works. But why should I have to do that?
fileNames = dir('Testing\*.pgm');
numFiles = size(fileNames, 1);
testData = zeros(32257, numFiles);
temp = zeros(32256, 1);
for i = 1 : numFiles,
fileName = fileNames(i).name;
% Extracts some info from the file's name and stores it in the first row
testData(1, i) = str2double(fileName(6:7));
% Here temp has the same dimensions as testData(2:end, i)
% yet testData(2:end, i) = imread(fileName) doesn't work
% however it works if I use temp as a "middleman" variable
temp(:) = imread(fileName);
testData(2:end, i) = temp(:);
end
If the file that you're reading is a color image, imread returns an MxNx3 array. You can't assign a 3D array to a 1D vector without reshaping it, even if it contains the same number of elements. That's probably why you get the error when you try to assign the output of imread directly to testData. However, when you use an intermediate variable and collapse it into a column vector, the assignment works because now you're assigning a 1D vector to another 1D vector of equal size.
If you don't want to use an additional step, try this
testData(2:end,i)=reshape(imread(fileName),32256,1);