How to use reshape on a 4D matrix after using fread on a RGB RAW file? - matlab

The following code correctly loads an mp4 file and stores it in a 3D matrix.
r = 1;
fileName = testDummyMP4;
readerobj = VideoReader(fileName, 'tag', 'myreader1');
F = get(readerobj, 'numberOfFrames');
tampon = single(read(readerobj,1));
tampon = imresize(tampon(:,:,1),r);
I = zeros(size(tampon,1),size(tampon,2),F,'uint8');
for k = 1:F
disp(['Open: ' num2str(round(100*k/F)) '%'])
vidFrames = single(read(readerobj,k));
I(:,:,k) = imresize(vidFrames(:,:,2),r);
end;
imagesc((I(:,:,1)));
This is the output
I'm trying to reverse engineer this code so that it produces the same sort of result for but for a .raw 8bit rbg file. Following the answers from this question I tried the following:
You can download the 'M1302000245_1436389857.982603.raw' rbg file here
Or Google Drive version here
Ix = 256;
Iy = 256;
SF = 30; % Sample frequency
RecordingTime = 30;
Iz = SF*RecordingTime
testDummy = 'M1302000245_1436389857.982603.raw'
fin = fopen(testDummy, 'r');
I = fread(fin, Ix*Iy*3*Iz, 'uint8');
fclose(fin);
I = reshape(I, [Ix Iy 3 Iz]); % The rbg should be 256x256x3x900
% I've tried each of the following manipulations before calling imagesc to no avail
% I = flipdim(imrotate(I, -90),2);
% I=impixel(I)
% I=I'
imagesc((I(:,:,1))); % view first slice
This gives:
What am I doing wrong?
Additional info:
Recordings are taken using raspberry pi cameras with the following python code
class BrainCamera:
def __init__(self):
self.video_format = "rgb"
#self.video_quality = 5
# Set up the settings of the camera so that
# Exposure and gains are constant.
self.camera = picamera.PiCamera()
self.camera.resolution = (256,256)
self.camera.framerate = 30
sleep(2.0)
self.camera.shutter_speed = self.camera.exposure_speed
self.camera.exposure_mode = 'off'
g = self.camera.awb_gains
self.camera.awb_mode = 'off'
self.camera.awb_gains = g
self.camera.shutter_speed = 30000
self.camera.awb_gains = (1,1)
def start_recording(self, video_name_path):
self.camera.start_recording(video_name_path, format=self.video_format)
self.camera.start_preview()
def stop_recording(self):
self.camera.stop_recording()
self.camera.stop_preview()
# Destructor
def __del__(self):
print ("Closed Camera")
self.camera.close()

I don't get the output you have, but I get some reasonable image:
%your vode from above, ending with I=fread(...)
I=uint8(I)
I2=reshape(I, 3, Ix ,Iy, []);
I2=permute(I2,[3,2,1,4]);
imagesc(I2(:,:,:,1));
implay(I2);

With Daniel's help I got the following working. Additionally a co-worker found out how to get the number of frames of a .raw rbg video. This we needed since it turns out assuming noFrame = SF*RecordingTime was a bad idea.
testDummy = 'M1302000245_1436389857.982603.raw'
testDummyInfo = dir(testDummy);
noFrames = testDummyInfo.bytes/(256*256*3); % In my question Iz = noFrames
fin = fopen(testDummy, 'r');
I = fread(fin, testDummyInfo.bytes, 'uint8');
fclose(fin);
I=uint8(I);
I2=reshape(I, 3, Ix ,Iy, noFrames);
I2=permute(I2,[3,2,1,4]);
imagesc(I2(:,:,2,1)); % Throw out unnecessarry channels r and b. Only want GFP signal
to produce:

Related

How can I read specific images from TID2013 dataset in MATLAB?

How can I read specific images from TID2013 dataset in MATLAB? I written the following code but it start from first to end of the list. The images are in this format: ixx.yy.z.bmp means xx is the number of image, yy is the model of the noise and z is the level of the noise. I just want to work with models 1,2 in level 4,5 but I don't know how to do it. please someone help me! By the way there are 25 reference images, 24 models of noise and 5 level of each model of noise that I wrote them vertically in info1.txt , info2.txt , info3.txt respectively.
clc; clear; close all;
% read Original images
cd 'C:\Users\Desktop'
for NO1 = 1:25
in1 = fopen('info1.txt');
xx = fgets(in1);
A = imread(strcat('C:\Users\Desktop\reference_images\',xx,'.bmp'));
A = rgb2gray(A);
end
% read distorted images
for NO1 = 1:25
in1 = fopen('info1.txt');
xx = fgets(in1);
for NO2 = 1:24
in2 = fopen('info2.txt');
yy = fgets(in2);
for NO3 = 1:5
in3 = fopen('info3.txt');
z = fgets(in3);
B = imread(strcat('C:\Users\Desktop\distorted_images\',xx,yy,z,'.bmp'));
B = rgb2gray(B);
C = imadjust(B);
% Write restored images
imwrite(C,['C:\Users\Desktop\restored_images\','i',sprintf('%02d',NO1),'_',sprintf('%02d',NO2),'_',num2str(NO3),'.bmp']);
end
end
end
The only thing you need to do is to change values of your for loops. Note that in matlab, in contrast with most other languages, for-loops are not restricted to specific step length and can be any vectors.
imageNames = textread('info1.txt', '%s');
noiseModels = textread('info2.txt', '%s');
noiseLevels = textread('info3.txt', '%s');
imageIndices = 1:25;
modelIndices = [1, 2, 7:8];
levelindices = [4 5];
sourceDir = 'C:\Users\Desktop\distorted_images\';
destDir = 'C:\Users\Desktop\restored_images\';
for ii = imageIndices
name = imageNames{ii};
for jj = modelIndices
model = noiseModels{jj};
for kk = levelindices
level = noiseLevels{kk};
sourcePath = sprintf('%s%s%s%s.bmp', sourceDir, name, model, level)
destPath = sprintf('%si%02d_%02d_%02d.bmp', destDir, ii, jj, kk)
B = imread(sourcePath);
B = rgb2gray(B);
C = imadjust(B);
imwrite(C, destPath);
end
end
end

MATLAB to Scilab conversion: mfile2sci error "File contains no instruction"

I am very new to Scilab, but so far have not been able to find an answer (either here or via google) to my question. I'm sure it's a simple solution, but I'm at a loss. I have a lot of MATLAB scripts I wrote in grad school, but now that I'm out of school, I no longer have access to MATLAB (and can't justify the cost). Scilab looked like the best open alternative. I'm trying to convert my .m files to Scilab compatible versions using mfile2sci, but when running the mfile2sci GUI, I get the error/message shown below. Attached is the original code from the M-file, in case it's relevant.
I Searched Stack Overflow and companion sites, Google, Scilab documentation.
The M-file code follows (it's a super basic MATLAB script as part of an old homework question -- I chose it as it's the shortest, most straightforward M-file I had):
Mmax = 15;
N = 20;
T = 2000;
%define upper limit for sparsity of signal
smax = 15;
mNE = zeros(smax,Mmax);
mESR= zeros(smax,Mmax);
for M = 1:Mmax
aNormErr = zeros(smax,1);
aSz = zeros(smax,1);
ESR = zeros(smax,1);
for s=1:smax % for-loop to loop script smax times
normErr = zeros(1,T);
vESR = zeros(1,T);
sz = zeros(1,T);
for t=1:T %for-loop to carry out 2000 trials per s-value
esr = 0;
A = randn(M,N); % generate random MxN matrix
[M,N] = size(A);
An = zeros(M,N); % initialize normalized matrix
for h = 1:size(A,2) % normalize columns of matrix A
V = A(:,h)/norm(A(:,h));
An(:,h) = V;
end
A = An; % replace A with its column-normalized counterpart
c = randperm(N,s); % create random support vector with s entries
x = zeros(N,1); % initialize vector x
for i = 1:size(c,2)
val = (10-1)*rand + 1;% generate interval [1,10]
neg = mod(randi(10),2); % include [-10,-1]
if neg~=0
val = -1*val;
end
x(c(i)) = val; %replace c(i)th value of x with the nonzero value
end
y = A*x; % generate measurement vector (y)
R = y;
S = []; % initialize array to store selected columns of A
indx = []; % vector to store indices of selected columns
coeff = zeros(1,s); % vector to store coefficients of approx.
stop = 10; % init. stop condition
in = 0; % index variable
esr = 0;
xhat = zeros(N,1); % intialize estimated x signal
while (stop>0.5 && size(S,2)<smax)
%MAX = abs(A(:,1)'*R);
maxV = zeros(1,N);
for i = 1:size(A,2)
maxV(i) = abs(A(:,i)'*R);
end
in = find(maxV == max(maxV));
indx = [indx in];
S = [S A(:,in)];
coeff = [coeff R'*S(:,size(S,2))]; % update coefficient vector
for w=1:size(S,2)
r = y - ((R'*S(:,w))*S(:,w)); % update residuals
if norm(r)<norm(R)
index = w;
end
R = r;
stop = norm(R); % update stop condition
end
for j=1:size(S,2) % place coefficients into xhat at correct indices
xhat(indx(j))=coeff(j);
end
nE = norm(x-xhat)/norm(x); % calculate normalized error for this estimate
%esr = 0;
indx = sort(indx);
c = sort(c);
if isequal(indx,c)
esr = esr+1;
end
end
vESR(t) = esr;
sz(t) = size(S,2);
normErr(t) = nE;
end
%avsz = sum(sz)/T;
aSz(s) = sum(sz)/T;
%aESR = sum(vESR)/T;
ESR(s) = sum(vESR)/T;
%avnormErr = sum(normErr)/T; % produce average normalized error for these run
aNormErr(s) = sum(normErr)/T; % add new avnormErr to vector of all av norm errors
end
% just put this here to view the vector
mNE(:,M) = aNormErr;
mESR(:,M) = ESR;
% had an 'end' placed here, might've been unmatched
mNE%reshape(mNE,[],Mmax)
mESR%reshape(mESR,[],Mmax)]
figure
dimx = [1 Mmax];
dimy = [1 smax];
imagesc(dimx,dimy,mESR)
colormap gray
strESR = sprintf('Average ESR, N=%d',N);
title(strESR);
xlabel('M');
ylabel('s');
strNE = sprintf('Average Normed Error, N=%d',N);
figure
imagesc(dimx,dimy,mNE)
colormap gray
title(strNE)
xlabel('M');
ylabel('s');
The command used (and results) follow:
--> mfile2sci
ans =
[]
****** Beginning of mfile2sci() session ******
File to convert: C:/Users/User/Downloads/WTF_new.m
Result file path: C:/Users/User/DOWNLO~1/
Recursive mode: OFF
Only double values used in M-file: NO
Verbose mode: 3
Generate formatted code: NO
M-file reading...
M-file reading: Done
Syntax modification...
Syntax modification: Done
File contains no instruction, no translation made...
****** End of mfile2sci() session ******
To convert the foo.m file one has to enter
mfile2sci <path>/foo.m
where stands for the path of the directoty where foo.m is. The result is written in /foo.sci
Remove the ```` at the begining of each line, the conversion will proceed normally ?. However, don't expect to obtain a working .sci file as the m2sci converter is (to me) still an experimental tool !

Turning a plot3 into a surf in MATLAB

I have several csv files and I plotted them using plot3 to create the following image:
Now I would like to turn this into a surface plot because I would like to colour the plot according to height. I made the following with scatter3:
clearvars;
files = dir('*.csv');
name = '\epsilon_{y} over time for Vertical section';
des_col_1 = 'Vertical section.epsY []';
des_col_2 = 'Length [mm]';
set(gca,'FontSize',20)
a = gca;
ii = 1;
x_data = [];
y_data = [];
z_data = [];
tStart = tic;
for file = files'
csv = xlsread(file.name);
[n,s,r] = xlsread(file.name);
des_cols = {des_col_1,des_col_2};
colhdrs = s(1,:);
[~,ia] = intersect(colhdrs, des_cols);
colnrs = flipud(ia);
file.name = n(:,colnrs);
file.name = file.name(1:end,:);
x_data = [x_data; file.name(:,2)];
y_data = [y_data; ones(size(file.name(:,2))).*ii];
z_data = [z_data; file.name(:,1)];
ii = ii+1;
end
tEnd = toc(tStart);
fprintf('%d minutes and %f seconds\n',floor(tEnd/60),rem(tEnd,60));
view(40,40);
zlabel({'True strain (%)'});
xlabel({'Length along sample (mm)'});
ylabel({'Stage'});
title({name});
scatter3(a,x_data,y_data,z_data,10,z_data);
colormap(jet); %# or other colormap
which gives me this
That was made with a smaller set of data than the first one as a test. It does almost what I want but I was wondering if there was a way to generate a true 3D surface from all my data. I can create a matrix with x, y, and z values for all points and I tried to replace scatter3(a,x_data,y_data,z_data,10,z_data); with
[X,Y] = meshgrid(x_data,y_data);
f = scatteredInterpolant(x_data,y_data,z_data);
Z = f(X,Y);
surf(a,X,Y,Z);
but the plot that I get does not look very good
I'm pretty sure there's something wrong with the interpolation but I'm not very good with surfaces so I don't know how to correct it.
The reason surf is giving you the error is you are creating long nx1 arrays Where n = number of points per file times number of files. For x,y,& z_data and you need them into a matrix instead. So try the following changes:
for file = files'
<snipped out for length>
x_data = [x_data; file.name(:,2).'];
y_data = [y_data; ones(1,numel(file.name(:,2))).*ii];
z_data = [z_data; file.name(:,1).'];
ii = ii+1;
end
This should make x, y, and z_data the size nxm (n = number of files, m = number points per file).
Then you should be able to just do
surf(x_data,y_data,z_data)

Plot graph with 2 variables in matlab

I'm planning to plot a graph of velocity against time using matlab. The change of time is 0.05 and total time 15. When time change, the graph will change and save a figure of that. I had mat file which contained all the data for time and velocity.
E.g, t=0, v=0, plot and save, t=0.05, v=1, plot and save until t=15.
I tried to use v=v+1 (which acts like i++) but failed to read the value of v in 2nd row. Any other method to do so?
Thank You.
The code is
i = 001
dt = t(2,1) - t(1,1);
k = dt*(i-1);
filename1 = 'front_data';
matFileName = sprintf('%s.mat', filename1);
matData = load(matFileName);
t = matData.time;
fv = matData.front_velocity;
fig = figure%('visible', 'off');
s = t(1,1);
fv = fv(1,1);
lot (s,fv,'*')
pic_filename = sprintf('front_data%02d.jpeg', k);
print(fig,pic_filename,'-djpeg')
istart = 002
iend = 301
for i = istart:iend
k = dt*(i-1);
t = t+dt
filename1 = 'front_data';
matFileName = sprintf('%s.mat', filename1);
matData = load(matFileName);
t = matData.time;
fv = matData.front_velocity;
v = fv(1,1);
v = v+1;
h = figure
axis([0 15 0 0.6])
plot(t,v,'*')
pic_filename = sprintf('front_data%02d.jpeg', k);
print(h,pic_filename,'-djpeg')
end
And the example I refer is the [https://www.mathworks.com/matlabcentral/answers/110632-how-to-increment-a-variable]
I reduced your example to the essential parts.
istart = 2;
iend = 301;
counter=istart;
%load data
% filename1 = 'front_data';
% matFileName = sprintf('%s.mat', filename1);
% matData = load(matFileName);
% t = matData.time;
% fv = matData.front_velocity;
%for demonstaration
t=0:.05:15;
fv=rand(size(t));
for i = istart:iend
%update
time = t(istart:counter);
values = fv(istart:counter);
%plot
plot(time,values,'*')
%increase index
counter=counter+1;
end
As you are loading always the same data in the loop you can do it once outside the loop, and for plotting you just update the length of your vector to be plotted. You could also just append the new value to the actual list.

Running matlab code through a folder

I have the following code for which instead of loading one image at a time, I'd like to run through every image in a folder (the defective folder in this code). I'd like the output to be an array containing the values of 'G' for each of the input images. I'm not too sure how to go about this - so any points appreciated. Many thanks!
%PCA code,
img = imread('C:\users\m7-miller\desktop\250images\defective\inkblob01.png');
img_gray = rgb2gray(img);
img_gray_double = im2double(img_gray);
figure,
set(gcf,'numbertitle','off','name','Grayscale Image'),
imshow(img_gray_double)
%find mean of the image
img_mean = mean(img_gray_double);
[m n] = size(img_gray);
%Make column vector of mean image value
new_mean = repmat(img_mean,m,1);
%Mean corrected image
Corrected_img = img_gray_double - new_mean;
%Covariance matrix of corrected image
cov_img = cov(Corrected_img);
%Eigenvalues of covariance matrix - columns of V are e-vectors,
%diagonals of D e-values
[V, D] = eig(cov_img);
V_T = transpose(V);
Corrected_image_T = transpose(Corrected_img);
FinalData = V_T * Corrected_image_T;
% Image approximation by choosing only a selection of principal components
PCs = 3;
PCs = n - PCs;
Reduced_V = V;
for i = 1:PCs,
Reduced_V(:,1) =[];
end
Y=Reduced_V'* Corrected_image_T;
Compressed_img = Reduced_V*Y;
Compressed_img = Compressed_img' + new_mean;
figure,
set(gcf,'numbertitle','off','name','Compressed Image'),
imshow(Compressed_img)
% End of image compression
% Difference of original image and compressed
S = (img_gray_double - Compressed_img);
figure,
set(gcf,'numbertitle','off','name','Difference'),
imshow(S)
% Sum of the differences
F = sum(S);
G = sum(F)
Are you looking for the dir command?
files = dir('*.png');
for n=1:size(files,1)
filename = files(n).name;
img = imread(filename);
....
G = sum(F);
end