Matlab MemMapFile for a three dimensional matrix - arrays

I have a three dimensional matrix called "Shanto" of size (232,232,3052).
I want to memory map this, and am using the following command:
fileID = fopen('Shanto.dat','w');
fwrite(fileID, Shanto, 'single');
fclose(fileID)
m = memmapfile('Shanto.dat')
However, when I try to access m.Data, I am given a 657083392 x 1 uint8 array.
How do I make it such that I can retain the (232,232,3052) shape of the original matrix?
Thanks,
Ben

When loading your .dat file you can specify the shape/format (the default is uint8 actually).
You also need to specify the correct data format using fwrite:
fileID = fopen('Shanto.dat','w');
fwrite(fileID, Shanto, 'uint8'); %// Instead of 'single' as before.
fclose(fileID)
m = memmapfile('Shanto.dat','Format',{'uint8',[232 232 3052],'MyFancyName'})
You can then access the corresponding 3D array using m.Data.MyFancyName
More info here

Related

Displaying a matrix obtained from a vectorised structure

I am trying to extract the coordinates located in the variable x within a .mat structure. I would like to print them as a three column matrix. Let's say:
-5543837.67700032 -2054567.16633347 2387852.25825667
4641938.565315761 393003.28157792 4133325.70392322
-3957408.7414133 3310229.46968631 3737494.72491701
1492206.38965564 -4458130.51073730 4296015.51539152
4075539.69798060 931735.497964395 4801629.46009471
3451207.69353006 3060375.44622100 4391915.05780934
I know that I can get them with
file=load('./filee_scan.mat')
stat = [file.scan.stat]';
x = [stat.x]';
But I get something like:
-5543837.67700032
-2054567.16633347
2387852.25825667
4641938.565315761
393003.28157792
4133325.70392322
% :: and so on
I would like to print them as I showed at the beginning (x as a vector of 3 coordinates and one line per station) but I don't know how to treat them. I have tried with loops but I really don't know how to express them.
How can I display my coordinates as an n -by- 3 matrix?
This is the scan file:
This is x:
[stat.x].' gives you a flattened vector, as you've seen. You can reshape() that vector to the desired format:
x = reshape(x,3,[]).';
This reshapes first to 3 rows and n columns (your number of stations), then transposed to have n rows of 3 columns.
For a short introduction on how reshape works, see this answer of mine.

How do i store sequence of 2D matrices into a 3D array in Matlab?

I have these series of 2D CT images and i have been able to read them into Matlab using "imread". The issue however is that i need the image read-in as a single 3D matrix rather than stack of several 2D matrices. I have been made aware that it is possible to store the number of 2D layers as the 3rd dimension, but i have no idea how to do this as i am still a learner.
The code i have for reading in the 2D stack are as follows:
a = dir('*.tif');
for i = 1: numel(a)
b = imread(a(i).name); %read in the image
b_threshold = graythresh(b); %apply threshold
b_binary = im2bw(b, b_threshold); %binarize image
[m, n] = size(b); %compute the size of the matrix
phi(i) = ((m*n) - sum((b_binary(:))))/(m*n); %compute the fraction of pore pixels in the image
phi(:,i) = phi(i); %store each of the above result
end
I have added just a single image although several of these are needed. Nevertheless, one can easily duplicate the image to create a stack of 2D images. For the code to work, it is however important to rename them in a numerical order.pore_image
Any help/suggestions/ideas is welcomed. Thanks!
You can simply assign along the third dimension using i as your index
stack_of_images(:,:,i) = b_binary
Well, the first advice is try to don't use the variable i and j in matlab because they are reserved (have a look here and here).
After it depends on along which dimension you want to store the 2D images:
if you want to store the images along the first dimension just use this code:
a = dir('*.tif');
for ii = 1: numel(a)
b = imread(a(ii).name); %read in the image
b_threshold = graythresh(b); %apply threshold
b_binary = im2bw(b, b_threshold); %binarize image
[m, n] = size(b); %compute the size of the matrix
phi(ii) = ((m*n) - sum((b_binary(:))))/(m*n); %compute the fraction of pore pixels in the image
phi(:,ii) = phi(ii); %store each of the above result
matrix_3D_images(ii,:,:)=b_binary; %adding a new layer
end
If you want to store the images along other dimensions it is easy to do: just change the posizion of the "pointer" ii:
matrix_3D_images(:,ii,:)=b_binary; or
matrix_3D_images(:,:,ii)=b_binary;

Matlab access vectors from a multi-dimensional array

I have a 4D matrix of size 300x200x3x20 where 300x200 is the size of one video frame, 3 is the number of channels (Red-Green-Blue channels) and 20 is the number of frames.
I want to extract all the color vectors from this matrix and store them in a 2D array of size 3x1,200,000 (300 x 200 x 20 = 1,200,000) where each row represents a component of the RGB color space and each column contain the RGB values of one pixel in the original matrix.
Besides, I want to carry out pixel-wise operations on this data such as extracting visual features but I cannot find a way to effectively access vectors along the third dimension.
How could I efficiently do these, possible without using loops?
Try this code -
IN = your_4D_data;
OUT = reshape(permute(IN,[3 1 2 4]),3,numel(IN)/3);
help reshape says:
B = reshape(A,m,n,p,...) or B = reshape(A,[m n p ...]) returns an n-dimensional array with the same elements as A but reshaped to have the size m-by-n-by-p-by-.... The product of the specified dimensions, m*n*p*..., must be the same as numel(A).
is this what you are looking for?
also, you can adress pixels like this: Matrix(i,j,:,k) which gives you the 3 colorchanels of pixel i,j in frame k.

MATLAB using 2D Array

i want to use a 2D array to store all the values of img1, img2 and the compared vlaue of img1 and img2,
I want to achive the algorithm likes:
% read in the images from a folder one by one:
somefolder = 'folder';
filelist = dir([somefolder '/*.jpg']);
s=numel(filelist);
C = cell(length(filelist), 1);
for k=1:s
C{k}=imread([somefolder filelist(k).name]);
end
%choose any of the two images to compare
for t=1:(s-1)
for r=(t+1):s
img1=C{r};
img2=C{t};
ssim_value[num][1]=img1; % first img
ssim_value[num][2]=img2; % second img
ssim_value[num][3]=mssim; % ssim value of these two images
end
end
So, there is error about using the 2D array (ssim_value) that I used, what is the correct way of initialization it, and how to achieve the purpose that save the values that I want to store.
Could someone help me. Thanks in advance.
I'm assuming that "num" is a number that you will supply, like 5 or something. You cannot mix types in arrays as you do in Python. Also, as #Schorsch pointed out, you use parenthesis to index arrays in Matlab.
The two-dimensional array you are trying to form needs to be a 2-D cell array. For example:
a = {{"a",3},{"two",[1,2,3]};
In this case, a{1,2} = 3, and a{2,1} = "two".
You may not know in advance how many files are in the directory, so pre-initializing the cell array may not be possible in advance. In any case, Matlab arrays only need to be pre-initialized for performance reasons, and you can easily find information on initializing arrays in Matlab.
In light of this, I'm pretty sure what you are trying to accomplish is:
%choose any of the two images to compare
ssim_value = {};
for t=1:(s-1)
for r=(t+1):s
img1=C{r};
img2=C{t};
ssim_value{num,1}=img1; % first img
ssim_value{num,2}=img2; % second img
ssim_value{num,3}=mssim; % ssim value of these two images
end
end

Storing integers in cell arrays in Matlab

I have a problem when using cell arrays in an m-file. I create a number of cell arrays using the function given in here. What I store on each of these arrays is numerical values being read from a text file (I convert them to string before I put them into the arrays). The problem is that the some numbers doesn't seem to be strored in the arrays correctly:
The text file contains that:
1976787196
8
1976945848
8
1977105448
8
And the contents of a cell array in which the above is store are the following:
Columns 1 through 3
1976787196 681405151445000 1976945848
Columns 4 through 6
685476780441608 1977105448 685476780441608
As you can see, instead of stroring 8, I get a very big integer.
Actually, I want all the contents of the cell arrays that I create to contain only 32-bit integers. Can I specify that requirement somehow? Thanks in advance!
It depends how you read the data from text file. Try using TEXTSCAN function. Format string '%u32' specifies that you want to read unsigned 32-bit integer data.
filename = 'test.txt';
fid = fopen(filename,'r');
x = textscan(fid,'%u32','delimiter','\t','CollectOutput',1);
x = x{1};
fclose(fid);

Resources