How to make an animation from multiple results? - matlab

I have some calculation with matrices and have set my loop to run for (let's say) 50 times.
I also assigned a color to each value so I can get a picture in the end of these matrices based on their values.
What I don't know is - how to make an animation from this multiple images I get in each turn.
Is it possible?!

The following code is what I have used previously to produce an .avi file
n = 15;
p = randperm(n);
figure('Color','white');
fcount = 0;
for k = 1:n-1
% produce the plot
[idx,idx] = min(p(k:n));
p(idx+k-1) = p(k);
p(k) = k;
plot(p,'*')
% Make sure plot updates before we capture the contents
pause(0.1)
F(k) = getframe(gcf); %#ok
end
movie2avi(F,'so1.avi','fps',2,'quality',100);
However, there seems to be some issues with the avi codec now for use with Windows XP, for example see this thread.
http://www.mathworks.com/matlabcentral/newsreader/view_thread/271172
I had the same problem; the avi file produced with the default Indeo codec would not run in Windows Media Player. Using a different codec, such as
movie2avi(F,'so1.avi','fps',2,'quality',100,'compression','Cinepak');
solved the problem. You may need to experiment to find a working combination.
Hth, Darren

I'm not sure what you're trying to do. One option is to use the MS-GIF animator, although 50 images is a bit much. See http://en.wikipedia.org/wiki/Microsoft_GIF_Animator for info. Considering the number of images, you might want to create a powerpoint document.

Related

Faster way to load .csv files in folder and display them using imshow in MATLAB

I have a piece of MATLAB code that works fine, but I wanted to know is there any faster way of performing the same task, where each .csv file is a 768*768 dimension matrix
Current code:
for k = 1:143
matFileName = sprintf('ang_thresholded%d.csv', k);
matData = load(matFileName);
imshow(matData)
end
Any help in this regard will be very helpful. Thank You!
In general, its better to separate the loading, computational and graphical stuff.
If you have enough memory, you should try to change your code to:
n_files=143;
% If you know the size of your images a priori:
matData=zeros( 768, 768,n_files); % prealocate for speed.
for k = 1:n_files
matFileName = sprintf('ang_thresholded%d.csv', k);
matData(:,:,k) = load(matFileName);
end
seconds=0.01;
for k=1:n_Files
%clf; %Not needed in your case, but needed if you want to plot more than one thing (hold on)
imshow(matData(:,:,k));
pause(seconds); % control "framerate"
end
Note the use of pause().
Here is another option using Matlab's data stores which are designed to work with large datasets or lots of smaller sets. The TabularTextDatastore is specifically for this kind of text based data.
Something like the following. However, note that since I don't have any test files it is sort of notional example ...
ttds = tabularTextDatastore('.\yourDirPath\*.csv'); %Create the data store
while ttds.hasdata %This turns false after reading the last file.
temp = read(ttds); %Returns a Matlab table class
imshow(temp.Variables)
end
Since it looks like your filenames' numbering is not zero padded (e.g. 1 instead of 001) then the file order might get messed up so that may need addressed as well. Anyway I thought this might be a good alternative approach worth considering depending on what else you want to do with the data and how much of it there might be.

How do I control which channel sound is played through using MATLAB?

I'm a novice MATLAB user, so apologies if the question is very basic. I need a .wav sound file to be played in a single, specific channel -- let's say the left channel. As it is, my code reads in the sound file, and I add in a column of zeros to nullify the channel I don't want, like so:
currentDir = pwd;
soundFile = [currentDir '\sound1.wav']; % load the file
[y, Fs] = audioread(soundFile); % read the file in
soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = 0; % nullifies the right channel
sound = audioplayer(soundData,Fs);
play(sound);
As it stands, the code currently produces a sound that is full volume in the left speaker, and half volume (but still very much audible) in the right speaker. I have tried this with at least 20 .wav files, with the same result.
In case it's relevant, this happens even when I write in code that explicitly matches the length of the sound variable in 0s, like so:
[y, Fs] = audioread(soundFile);
silentChannel = zeros(size(y));
soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = silentChannel(:,2); % nullifies the right channel
Does anybody know what I'm doing wrong, or have any thoughts?
Your code is definitely correct and it should only play audio in the left channel. I suspect that the problem is caused by a sound-card/driver issues. Allow me suggest the following troubleshooting steps:
Save your output as a wav file using audiowrite('output.wav', soundData, Fs). Play this using a different audio player, such as Audacity. If you still hear output in both channels, it must be a sound-card/driver issue.
Assuming that you are using a Windows PC (going by the syntax in your file path), make sure all sound enhancements are disabled. How to do this depends on the PC. If there is a third-party app controlling the playback settings, you'd have to use that. Otherwise find the settings shown in the picture below in the Control Panel.
In MatLab the expected method for playing sound is the method sound(data,Fs)
To control the channel the sound emits on, you'll want to know how sound() reads data.
data is a matrix with the columns representing channels, and with the rows holding the samples of the waveform for a given sampling fequency Fs
here is a simple implementation.
function treismanwolfe()
close all
clear all
clc
Fs = 40000;
tau = 2*pi();
t = 0:tau/(Fs-1):tau/2;
left = sin(t).*(sin(t*200)+sin(t*1600));
left= left/max(abs(left));
left = left'; %turn column vector into row
right = sin(t).*(sin(t*800)+sin(t*400));
right= right/max(abs(right));
right = right'; %turn column vector into row
data = [left,right*0]; %multiply either by 0 to nullify
sound(data,Fs); %so you can hear it.
end
I hope this works for you. Enjoy!
When I run your code the audio output is only audible in the left channel as you have specified.
#Austin Kootz' version with the sound()-function is just as good and also produces what you're looking for, but with audioplayer-object you have the ability to stop the playback in the middle of the playback (as you probably know)
Have you tried converting your .wav to another format to see if that makes a change?

Using repmat() to equalise the length of two audio files Matlab

Having a slight issue with the repmat() function.
I've got two audio files that I'm using for cross synthesis in Matlab, I want to make the second audio file repeat so it's the same length as the first one.
Currently I'm doing
c = size(y());
rep = y2(1:end,:);
y(1:end,:) = repmat(rep,1, c(1))
Yet it's not making a 1D matrix, any suggestions?
y and y2 are just the y values of each song converted to mono.
Thanks!
I actually managed to solve it myself, turns out I was using them in the wrong order, needed to be repmat(rep c(1), 1)!

Read and process multiple .TIFF files using MATLAB

I have problem on read and process multiple tiff file using MATLAB since I am beginner in MATLAM software. I have 300 of tiff images with same dimension. I want to loop the process, however, I cannot get it. Until now, I only change the file-name every time to read and process. I still don't get where should start. Can anyone help me. Here I attach my coding.
filename=('brd06330_s0239.tif');
fileinfo=imfinfo(filename);
Nfiles=numel(fileinfo);
Cloud=cell(Nfiles,1);
for n=1:Nfiles
A=imread(filename);
[rimg cimg]=size(A);
% Read by band (for this task only use band 1)
B1Channel = A(:, :, 1);
% A=imread(filename);
% [rimg cimg]=size(A);
%for channel 1
W_countB1 = sum(sum(B1Channel == 0)) % W= water
NW_countB1 = sum(sum(B1Channel > 0)) % NW= non water (cloud and land)
end
%save in text format(excel)
d=[W_countB1,NW_countB1]
colname={W_countB1,NW_countB1}
xlswrite('brd06330_s0239',d)
try dir('*.tif'), that will get you a list of all TIFFs in your directory, then you can loop the whole thing like you wanted.
it would look something like:
files=dir('*.tif');
for i=1:length(files)
A=imread(file(i).name);
%//... whatever you want to do with your TIFFs
end
hope that helps.

Simultaneous playback of multiple videos with MATLAB

I searched the internet and stack overflow but could not find a solution or even helpful hints to my problem.
I need to write a specialised video annotation software in MATLAB which has to be capable to play multiple videos (at least 2) simultaneously on a GUI. The video files are XVID-encoded. Up to now, I basically just adjusted the mathworks.com example for video playback (xylophon.avi, see movie() description).
I am familiar with the mmreader, VideoReader, movie and implay functions but still I am facing two issues:
Even if I read in only a small number of frames (like in the xylophon.avi example), my progam soon exceeds available memory. Also, it takes quite long to read in even relatively few frames (say 100).
The movie() function is sycnhronous, so the second video does not start until the first video completed. How can I call two movie()-functions concurrently? Or is there another way to show two (or more) videos simultaneously?
Any suggestions? Thanks!
First of all MATLAB is not multithreaded. Doing two things in parallel will be difficult. Try to breakout to Java. Matlab uses JIDE as their graphical front-end which is built on Swing. Use MATLAB Builder JA in order to compile your MATLAB code to Java, or add your own 'Panels' to the IDE as shown in this question.
You could display the videos in two different windows and start the playback simultaneously by giving the videos a handle and calling its undocumented play function. This removes any struggle you might have with videos of unequal length as well.
handle1 = implay('file1.mp4');
handle2 = implay('file2.mp4');
handle1.Parent.Position = [100 100 640 480];
handle2.Parent.Position = [740 100 640 480];
play(handle1.DataSource.Controls)
play(handle2.DataSource.Controls)
In principle, you can display each video frame as an image and alternate updating each video, but getting it to play at exactly the right frame rate might be difficult.
Try something like the following. This probably won't work as-is, but you should be able to update it.
v1 = VideoReader(firstVideo)
v2 = VideoReader(secondVideo)
i1 = 0;
i2 = 0;
while i1 < v1.NumberOfFrames && i2 < v2.NumberOfFrames
if i1 < v1.NumberOfFrames
i1 = i1+1;
subplot(1,2,1)
image(v1.read(i1))
end
if i2 < v2.NumberOfFrames
i2 = i2+1;
subplot(1,2,2)
image(v2.read(i2))
end
drawnow
end