Greg's pick this week is Using Doxygen with MATLAB by Fabrice. Ever wanted a class dependency diagram and documentation of your MATLAB Classes. How about leveraging Doxygen to document your... read more >>
]]>Greg's pick this week is Using Doxygen with MATLAB by Fabrice.
Ever wanted a class dependency diagram and documentation of your MATLAB Classes. How about leveraging Doxygen to document your development project?
Fabrice provides a simple interface to make this possible. Interestingly enough, this entry doesn't actually contain MATLAB Code!
Do you want to know how MATLAB Classes are related?
The above image shows a subset of the class hierarchy for a project I have been working on, which I was able to generate using Fabrice's tool.
The diagram depicts each class in a box. The arrow points to the parent class from which each class is inherited.
The terminus for the dependency path is a builtin class in MATLAB, which in this case is "handle".
If you use comments in MATLAB Code to document your functions and classes, then you need to apply Fabrice's extra convention of "%>" instead of just "%" to determine which comments get parsed by Doxygen.
In addition Doxygen convention is the documentation for a function by default comes before the function, which the convention in MATLAB is that it comes after the function. To make sure your documentation is available in Doxygen and using the MATLAB DOC function, then you likely want to consider using the "<" flag in your first comment after a MATLAB Function or class parameter definition.
I did make a quick modification of the Perl script in Fabrice's entry to automate that process so that "%>" was replaced by "///<" and make the assumption that MATLAB Documentation always comes after the function or parameter definition.
There is already a documentation mechanism available in MATLAB already. As well as the ability to display custom documentation as part of the MATLAB Documentation system.
You can use comments in your MATLAB code to generate documentation without any additional work. However it doesn't provide much in the way of developing dependency graphs.
Let us know here.
Get
the MATLAB code
Published with MATLAB® 8.6
Sean's pick this week is 2D Wave Equation by Daniel Armyr. GPUs MATLAB's Parallel Computing Toolbox has direct support for Graphics Processing Units (GPUs or... read more >>
]]>Sean's pick this week is 2D Wave Equation by Daniel Armyr.
MATLAB's Parallel Computing Toolbox has direct support for Graphics Processing Units (GPUs or GPGPUs) for many different computations. Since most laptops, with the exception of highend gaming ones, don't have powerful enough GPUs for scientific computing, I usually don't get to take advantage of this.
However, I've been lucky enough over the last month or so to have access to a fancy portable desktop with a Tesla K40 GPU in it. Daniel's app allows me to make waves and then compute the propagation on the cpu or gpu while measuring the difference in computational speed. (I switch to the GPU at 28s)
What did it take to switch over to the GPU from the CPU? Here's the code comparison:
Just the commands gpuArray and gather to move the arrays back and forth between the CPU and GPU. There are quite a few commands that run directly on the GPU, you can find them here. This list grows bigger with every release of MATLAB. My personal favorite is iradon which was a big bottleneck in my previous life working with CT images.
One thing I'd like to see Daniel do differently would be to check if a GPU is available. If you don't have a supported GPU, the app errors rather than failing gracefully or just disabling the GPU option. There's a convenient function, gpuDeviceCount, that you can use to see how many supported GPUs are on the machine.
if gpuDeviceCount == 0 warndlg(sprintf('You don''t have a supported GPU!\nGo talk to your IT department :)'),'No GPU Found') end
Do you use a GPU with MATLAB or have interest in trying one?
Give it a try and let us know what you think here or leave a comment for Daniel.
Get
the MATLAB code
Published with MATLAB® R2015b
Jiro's pick this week is Model Obfuscation Tool by Atsushi Ohashi.Atsushi is a fellow MathWorker working out of the Nagoya office in Japan. He's part of the Pilot Engineering group, whose role is to help our key customers overcome technical challenges through deep engagements using MathWorks tools. Being in Japan,... read more >>
]]>Jiro's pick this week is Model Obfuscation Tool by Atsushi Ohashi.
Atsushi is a fellow MathWorker working out of the Nagoya office in Japan. He's part of the Pilot Engineering group, whose role is to help our key customers overcome technical challenges through deep engagements using MathWorks tools. Being in Japan, naturally our key customers tend to be in the automotive industry, where Simulink is heavily used.
As part of his job, from time to time his group needs to obtain Simulink models from our customers. Understandably, there are cases when our customers are hesitant on providing us with the models because of the confidential information (textual) included in the models. In many of those cases, simply obfuscating the textual information was enough to appease their concerns. Atsushi's tool does exactly that. In fact, the Japan Pilot Engineering team uses his tool for that purpose, and he thought he would make it more widely available.
The tool is very easy to use. Once you install it (there is an install script), a menu item is added to the Tools menu. Selecting the "ModelObfuscationTool" will bring up a dialog window, and clicking "Run" obfuscates your Simulink model.
Atsushi has included a nice help document, which should also get you started. He does state that there are cases where the operation may not succeed, so it's always good to check that the obfuscated model still runs.
By the way, here is an incomplete list of some other obfuscation techniques.
Comments
Let us know what you think here or leave a comment for Atsushi.
Get
the MATLAB code
Published with MATLAB® R2015b
Richard's pick this week is GUI Layout Toolbox by David Sampson and Ben Tordoff. Contents Pick Example Applications using GUI Layout Toolbox Comments Pick My pick this week is the GUI Layout Toolbox for creating sophisticated MATLAB Apps that resize gracefully. Have you ever created an App in MATLAB? Have you used GUIDE to create an App or... read more >>
]]>f = figure( 'Position', 200*ones(1,4) ); vbox = uix.VBox( 'Parent', f ); axes( 'Parent', vbox ); hbox = uix.HButtonBox( 'Parent', vbox, 'Padding', 5 ); uicontrol( 'Parent', hbox, ... 'String', 'Button 1' ); uicontrol( 'Parent', hbox, ... 'String', 'Button 2' ); set( vbox, 'Heights', [1 35] )Running this code results in the App above. In the code above, we used the VBox method of the uix class to create our vertical box container, which has the figure (f) as its parent. We then create an axes object with the vertical box container as the parent. Next we add a hozizontal button box to the vertical box container. Finally, we add two buttons to the horizontal button box container. The horizontal button box container is a specialized version of the horizontal box container. It is used to arrange a row of buttons, checkboxes or similar graphical elements. All buttons are given equal size and by default are centered in the drawing area. We could have used a horizontal box container, but we would need some additional code to specify the size and position of the buttons. By default the horizontal button box centers the buttons. And finally, we set the height of the two items in the vertical container box. In this case, we specify "1" for the axes which stipulates that the size is variable and will scale to fit the region. For the second item, the horizontal button box, we specify that it has a height of 35 pixels. This maintains the buttons to be located at the bottom of the App. To demonstrate how this works with scaling, the image below shows three instances of the same App. Figure 1 is the original App as shown above. Figure 2 is the App enlarged horizontally and Figure 3 is the App enlarged vertically. As you can see in each case, the size and placement of the buttons remains the same while the axes is scaled to the specified size. In the example above, we used two boxes for the simple App. Other containers available with the toolbox are panels (including tabs) and grids. These containers allow the developer to create highly customized and complex Apps to support their applications.
Get the MATLAB code Published with MATLAB® R2015b
]]>Sean's pick this week is MATLAB Parallel Cloud by MathWorks Parallel Computing Toolbox Team. Background Have you ever wanted borrow a more powerful computer to finish a certain... read more >>
]]>Sean's pick this week is MATLAB Parallel Cloud by MathWorks Parallel Computing Toolbox Team.
Have you ever wanted borrow a more powerful computer to finish a certain task or to see how well your code scales? If you have, but do not want to deal with moving your files to another computer or don't have access to another computer with MATLAB, then MATLAB Parallel Cloud is a good option. For just a few dollars per hour, it lets you have access to 16 MATLAB parallel workers (headless MATLAB engines) on 16 physical cores on a machine running on Amazon EC2. My laptop, in comparison, has only a wimpy two cores.
MATLAB Parallel Cloud only allows for interactive use of the workers, so you can use parfor, parfeval and spmd just like always. It will not work with batch for totally offloading your work like you could do with the Distributed Computing Server.
It's also nice that I don't need to be on my corporate network to use it.
If this interests you, you need to be running R2015a or R2015b, be located in North America, and have the Parallel Computing Toolbox installed. Then just download the installer from the File Exchange. Installing requires a credit card which will be billed for every hour of usage.
Once you download it, run setupParallelCloud and then test the connection:
Now to use it, you just have to switch your default parallel cluster to MATLAB Parallel Cloud.
CAUTION As soon as you start the pool, you'll be billed for an hour and again for the next hour 60 minutes later. If you don't think you'll need it for more than an hour, it would be wise to set a pool idle timeout in parallel preferences to make sure you're not paying for unused time. I'd also be sure to always set the default pool back to Local when you're done.
For my example, I'm going to run a nonlinear integer optimization to minimize production cost for a semiconductor manufacturing plant. The model is made in SimEvents, MathWork's discrete event simulation tool that sits on Simulink.
Here's a peek at the model:
Since I'm working with a Simulink model, I need to load it into each worker's workspace. This is done with spmd, which runs the same command on each worker:
% Open the pool if there is none and supply it with the model p = gcp; p.addAttachedFiles('SemiconductorManufacturing.slx') spmd load_system('SemiconductorManufacturing.slx'); end
Now I need to set up the optimization problem. I'll use ga, the genetic algorithm optimizer in the Global Optimization Toolbox, since it can handle integer constraints. Here we will be optimizing the time between starting new lots, the number of human operators, and how many lots can be held at once.
% Options, the important one is 'UseParallel' which will evaluate the % individuals in parallel on the available workers. opts = gaoptimset('PlotFcns',{@gaplotbestf; @gaplotbestindiv},... 'Generations',20, 'StallGenLimit', 10, ... 'PopulationSize',25, 'EliteCount',1, ... 'UseParallel', true); % Lower and upper bounds on variables. % All variables must be integers lb = [50 1 10]; ub = [1000 5 3000]; IntCon = [1 2 3]; % Execute genetic algorithm solver. productionCcost calculates the final % production cost after running the model with the given parameters. finalResult = ga(@productionCost,3,[],[],[],[],lb,ub,[],IntCon,opts); % Report results disp('Results') disp('Time Between Lots') disp(finalResult(1)) disp('Number of Operators') disp(finalResult(2)) disp('Holding for Lots') disp(finalResult(3))
Optimization terminated: maximum number of generations exceeded. Results Time Between Lots 84 Number of Operators 1 Holding for Lots 13
I'm seeing a 10x speedup for the optimization over running it locally in serial.
Do you need to scale up your analysis? If so, what kind of speedups or size scaling are you looking for?
Give it a try and let us know what you think here or leave a comment for the Parallel Computing Team.
Get
the MATLAB code
Published with MATLAB® R2015b
2015 is officially over...we hope it was a great one for you. Here once again, to close out the PickoftheWeek year, a review of our Picks of the year. Happy New Year, everyone!You can read the original blog posts for each of these picks by clicking on the names of... read more >>
]]>2015 is officially over...we hope it was a great one for you. Here once again, to close out the PickoftheWeek year, a review of our Picks of the year. Happy New Year, everyone!
You can read the original blog posts for each of these picks by clicking on the names of the files and following the links to the "Pick of the Week" tag. As always, your comments are welcome.
Get
the MATLAB code
Published with MATLAB® R2016a
Title/Author/Summary/Notes  Image 

__________________________________________________________________________  
Bilateral Filtering
Implements bilateral filtering for grayscale and color images.


__________________________________________________________________________  
SCATTERBAR3
Creates a 3D bar chart where bars are placed in user specified XY locations.


__________________________________________________________________________  
polyfix(x,y,n,xfix,yfix,xder,dydx)
Fit polynomial p to data, but match exactly at one or more points


__________________________________________________________________________  
Video Processing Tutorial
Tutorial to read, process, and create video files.


__________________________________________________________________________  
nflcolor
Return NFL color values by team or city name


__________________________________________________________________________  
geosciencecommunitycodes/GISMO
GISMO  a framework for scientific research in seismology/infrasound


__________________________________________________________________________  
Snake Algorithm
The goal is to find a contour that best approximates the perimeter of an object.


__________________________________________________________________________  
Enigma
Enigma M3 Emulator


__________________________________________________________________________  
MATLAB Dependency Injection
A dependency injection framework for MATLAB.


__________________________________________________________________________  
Bubblegum plot
Scatter plot with soap bubbels


__________________________________________________________________________  
Word Data Visualisation
Makes word clouds and semantic surface visualisations from a set of documents.


__________________________________________________________________________  
BusDataStoreComparator
Compares Bus Data Store (Simulink.bus)


__________________________________________________________________________  
Plot and compare histograms; pretty by default
Compares multiple sets of data elegantly. Set bins and axis bounds to be appropriate for the data.


__________________________________________________________________________  
Detect and Track Multiple Faces
Detect and track multiple faces from live video.


__________________________________________________________________________  
Passive Mode FTP in MATLAB
These files allow users to use passive mode FTP in MATLAB.


__________________________________________________________________________  
Megan Simulator (XKCD)
Stickfigure model


__________________________________________________________________________  
STRUCT2STR
Converts a struct intoa char string and, if needed, display the string. The function allows exportin


__________________________________________________________________________  
geom2d
Geometry library for matlab. Performs geometric computations on points, lines, circles, polygons...


__________________________________________________________________________  
Bubbleplot  Multidimensional scatter plots
Visualize up to 6 dimensions of data using point clouds


__________________________________________________________________________  
Mission On Mars Robot Challenge 2015  France
Documentation, Simulation and Arduino/Raspberry Pi design and models


__________________________________________________________________________  
MIPS processor in Simulink
Implementation of singlecycle MIPS processor in Simulink


__________________________________________________________________________  
Align axes labels in 3D plot
Align the x, y and z labels of the current axes with the x, y and z axes for 3D plots.


__________________________________________________________________________  
Auto flush
Demonstrates auto flushing using an ultrasonic sensor.


__________________________________________________________________________  
Testing of Safety Critical Control Systems
This is a presentation on testing of safety critical control systems.


__________________________________________________________________________  
Short path name on Windows (COM server)
Get the short path name of files and folders on Windows


__________________________________________________________________________  
Bus Object Bus Creator
Tool to automatically populate a busCreator with BusElements names defined in a Bus Type.


__________________________________________________________________________  
Introduction to MuPAD for Plant Modeling
Introduction to MuPAD for Plant Modeling


__________________________________________________________________________  
XKCDIFY
Redraw existing plots to look like XKCD style plots


__________________________________________________________________________  
imageSetViewer
Easily create a tabpanel view of images in an imageSet


__________________________________________________________________________  
Write Cell Array to Text File
A cell array is written to a delimited output file, incl. options for appending & custom delimiters.


__________________________________________________________________________  
Cell Array to CSVfile [improved cell2csv.m]
Writes cell array content into a *.csv file.


__________________________________________________________________________  
CELLWRITE
Cellwrite writes mixed cell array data to a CSV file.


__________________________________________________________________________  
The X Collection
Collection of programs that ease interaction with Excel files.


__________________________________________________________________________  
2D Line Curvature and Normals
Accurate Curvature and Normals of a line/contour consisting of 2D points


__________________________________________________________________________  
RemoveSheet123  remove default Excel sheets
Remove default sheets ("sheet1" ,"sheet2", "sheet3") from an Excel file


__________________________________________________________________________  
JSONlab: a toolbox to encode/decode JSON files in MATLAB/Octave
JSONlab is an opensource JSON/UBJSON encoder and decoder for MATLAB and Octave.


__________________________________________________________________________  
nasa/TMATS
Simulink Toolbox for the Modeling and Analysis of Thermodynamic Systems, such as gas turbines


__________________________________________________________________________  
Structure display
simple recursive display of a structure content in Matlab


__________________________________________________________________________  
cachedcall
Cache the results of slow function calls


__________________________________________________________________________  
EXPAND
Replicate and tile each element of an array.


__________________________________________________________________________  
deploypcode(source_dir, target_dir, varargin)
DEPLOYPCODE recursively searches a directory for .m files, creating encrypted .p files with .m help


__________________________________________________________________________  
plot_subfun
plots the subroutines in a function, and their dependencies on each other


__________________________________________________________________________  
ForEach
Tools for simplifying forloops. Customizable loop iteration.


__________________________________________________________________________  
Decimate Polygon
Simplify a 2D closed, piecewise linear contour by specifying boundary offset tolerance.


__________________________________________________________________________  
Rolling Ball on Plane
Model of a rolling ball on plane using SimMechancs.


__________________________________________________________________________  
CAD APPS
Computer Aided Design (CAD) and Exploration Applications (APPS)


__________________________________________________________________________  
FAST, PROGRAMMATIC string searching in directories of MATLAB code files
VERY FAST CommandLine searching for text contained in MATLAB code files.


__________________________________________________________________________  
Genetic Packman
A simple demonstration of Genetic Algorithm using all times favorite game.


__________________________________________________________________________  
Number to Words
Convert a number to a string giving the English name of the number value (GB/US).

Published with MATLAB® R2016a
]]>Jiro's pick this week is polyfix by Are Mjaavatten.Have you ever wanted to fit a polynomial to your data and have the line go through some specified points? What about specifying the slope at a certain point? Let's take a look at some options, including Are's entry.ContentsPolynomial fittingConstrain to go... read more >>
]]>Jiro's pick this week is polyfix by Are Mjaavatten.
Have you ever wanted to fit a polynomial to your data and have the line go through some specified points? What about specifying the slope at a certain point? Let's take a look at some options, including Are's entry.
The function polyfit lets you fit a polynomial to your data. We'll first create some data.
t = linspace(0,2,31)';
y = sin(pi*t)+ 0.1*randn(size(t));
plot(t,y,'o')
We'll fit a 3rd order polynomial to the data.
$$ y \approx x_1t^3 + x_2t^2 + x_3t + x_4$$
x_polyfit = polyfit(t,y,3) y1 = polyval(x_polyfit,t); plot(t,y,'o',t,y1) legend('data','polyfit')
x_polyfit = 2.8843 8.6941 6.0419 0.2050
What if you want this polynomial to go through certain points. Perhaps, you want the curve to cross (0, 0) and (2, 0). This is where Are's entry comes into play. But first, let me talk about a different method. I found this question on MATLAB Answers. There are several ways to deal with this, and one of them is to use a function like lsqlin from Optimization Toolbox. lsqlin solves the following leastsquares curve fitting problem.
$$\min_{x}\frac{1}{2}C\cdot x  d_2^2 \quad \rm {such \; that} \quad \Bigg \{ \begin{array}{l} A \cdot x \leq b, \\ Aeq \cdot x = beq, \\ lb \leq x \leq ub \end{array} $$
For a 3rd order polynomial, $C$ and $d$ are defined as the following.
$$C = \left[ t^3 \quad t^2 \quad t \quad 1 \right],\quad d = y$$
$x$ represents the coefficients for the polynomial terms.
$$x : \left[ \begin{array}{c} x_1 \\ x_2 \\ x_3 \\ x_4 \end{array} \right]$$
C = [t.^3 t.^2 t ones(size(t))]; d = y;
There are no inequality constraints, so we set $A$ and $b$ to empty.
A = []; % No inequality constraint b = []; % No inequality constraint
For the equality constraints, we need to set the $y$ values at $t$ = 0 and $t$ = 2 to zero. This means
$$\begin{array}{rccccc} x_1(0)^3 + x_2(0)^2 + x_3(0) + x_4 = 0 & \Rightarrow & [0\quad0\quad0\quad1] & \cdot & x = & 0 \\ x_1(2)^3 + x_2(2)^2 + x_3(2) + x_4 = 0 & \Rightarrow & \underbrace{[2^3\quad2^2\quad2\quad1]}_{Aeq} & \cdot & x = & \underbrace{0}_{beq} \end{array}$$
Putting these into $Aeq$ and $beq$, we get the following.
Aeq = [0 0 0 1 ; % t = 0 2^3 2^2 2 1]; % t = 2 beq = [0 ; % y = 0 (when t = 0) 0]; % y = 0 (when t = 2)
We then call lsqlin to solve for the polynomial coefficients.
x_lsqlin1 = lsqlin(C,d,A,b,Aeq,beq)
Warning: The trustregionreflective algorithm can handle bound constraints only; using activeset algorithm instead. Optimization terminated. x_lsqlin1 = 2.5524 7.6807 5.1518 0
plot(t,y,'o',t,C*x_lsqlin1) legend('data','lsqlin') grid on
Let's add more constraint for the curve to go through (0.5,1) and (1.5,1). Also, we want the derivatives at those points to be zero. That's additional 4 constraints. With so many constraints, we won't be able to satisfy them with a 3rd order polynomial. Let's try a 7th order.
$$ y \approx x_1t^7 + x_2t^6 + x_3t^5 + x_4t^4 + x_5t^3 + x_6t^2 + x_7t + x_8$$
C = [t.^7 t.^6 t.^5 t.^4 t.^3 t.^2 t ones(size(t))];
The derivative for the 7th order polynomial is defined as
$$\frac{dy}{dt} \approx 7x_1t^6 + 6x_2t^5 + 5x_3t^4 + 4x_4t^3 + 3x_5t^2 + 2x_6t + x_7$$
For example, the constraint "the derivative at $t$ = 0.5 is zero" can be represented as
$$ \begin{array}{c} { 7x_1(0.5)^6 + 6x_2(0.5)^5 + 5x_3(0.5)^4 + 4x_4(0.5)^3 + 3x_5(0.5)^2 + 2x_6(0.5) + x_7 = 0 } \\ \\ { \Downarrow } \\ \\ { \underbrace{\left[ 7(0.5)^6\quad6(0.5)^5\quad5(0.5)^4\quad4(0.5)^3\quad3(0.5)^2\quad2(0.5)\quad1\quad0\right]}_{Aeq}\cdot x = \underbrace{0}_{beq} } \end{array}$$
Aeq = [0 0 0 0 0 0 0 1 ; % t = 0 2^7 2^6 2^5 2^4 2^3 2^2 2 1 ; % t = 2 0.5^7 0.5^6 0.5^5 0.5^4 0.5^3 0.5^2 0.5 1 ; % t = 0.5 1.5^7 1.5^6 1.5^5 1.5^4 1.5^3 1.5^2 1.5 1 ; % t = 1.5 7*0.5^6 6*0.5^5 5*0.5^4 4*0.5^3 3*0.5^2 2*0.5 1 0 ; % t = 0.5 (for dy/dt) 7*1.5^6 6*1.5^5 5*1.5^4 4*1.5^3 3*1.5^2 2*1.5 1 0]; % t = 1.5 (for dy/dt) beq = [ 0 ; % y = 0 (when t = 0) 0 ; % y = 0 (when t = 2) 1 ; % y = 1 (when t = 0.5) 1 ; % y = 1 (when t = 1.5) 0 ; % dy/dt = 0 (when t = 0.5) 0]; % dy/dt = 0 (when t = 1.5)
Let's fit and see if we've accomplished our goal.
x_lsqlin2 = lsqlin(C,d,A,b,Aeq,beq) plot(t,y,'o',t,C*x_lsqlin2) legend('data','lsqlin (with derivative constraint)') grid on set(gca,'XTick',0:0.5:2) % Adjust tick marks to show points of interest
Warning: The trustregionreflective algorithm can handle bound constraints only; using activeset algorithm instead. Optimization terminated. x_lsqlin2 = 0.2925 2.1030 7.8142 17.6810 19.6794 5.7234 2.2753 0.0000
In the MATLAB Answers post I mentioned above, Are actually posted a response mentioning polyfix. This entry achieves the goal of performing a polynomial fit with constraints to pass through specific points with specific derivatives. Let's solve the same problem using polyfix, 7th order polynomial to fit through (0,0), (2,0), (0.5,1), (1.5,1) and derivative of zero at $t$ = 0.5 and $t$ = 1.5.
x_polyfix = polyfix(t,y,7,[0 2 0.5 1.5],[0 0 1 1],[0.5 1.5],[0 0]) plot(t,y,'o',t,polyval(x_polyfix,t)) legend('data','polyfix') grid on set(gca,'XTick',0:0.5:2) % Adjust tick marks to show points of interest
x_polyfix = Columns 1 through 7 0.2925 2.1030 7.8142 17.6810 19.6794 5.7234 2.2753 Column 8 0
If we compare this result with that from lsqlin, we see that it's essentially identical.
norm(x_lsqlin2x_polyfix')
ans = 2.1194e10
Are's polyfit is great for performing polynomial fits with constraints around passing points. If you need other sophisticated constraints, you would want to check out Optimization Toolbox.
Give this a try and let us know what you think here or leave a comment for Are.
Get
the MATLAB code
Published with MATLAB® R2015b
ContentsTimeBased Frame Readsimshow and cdata instead of imageSo...And finally:Comments?Brett's Pick this week is Video Processing Tutorial, by prolific File Exchange author Image Analyst.For various reasons, I've been spending a lot of time working with videos in MATLAB latelywhether helping a customer work through some challenges, or developing new tools for... read more >>
]]>Brett's Pick this week is Video Processing Tutorial, by prolific File Exchange author Image Analyst.
For various reasons, I've been spending a lot of time working with videos in MATLAB latelywhether helping a customer work through some challenges, or developing new tools for detecting, tracking, and labeling regions of interest in individual frames. Getting started with video analysis can be a bit dauntingthere are several options to confound the newer user, and it's easy to take missteps en route.
I particularly like Image Analyst's tutorial precisely because (as one recent commenter put it), it's: "a nice starting place for video processing. Shows how easy it is for beginners to get into. Great job!"
The tutorial is at just the right level to show video playback, and to demonstrate how to incorporate a simple framewise processing algorithm. Using a demo video ('rhinos.avi') that ships with the Image Processing Toolbox, Image Analyst shows how to:
folder = fileparts(which('rhinos.avi'));
movieFullFileName = fullfile(folder, 'rhinos.avi');
videoObject = VideoReader(movieFullFileName)
fontSize = 12; numberOfFrames = videoObject.NumberOfFrames; for frame = 1 : numberOfFrames thisFrame = read(videoObject, frame); image(thisFrame); caption = sprintf('Frame %4d of %d.', frame, numberOfFrames); title(caption, 'FontSize', fontSize); end
There's much more.... Image Analyst shows the user the how to calculate and plot live statistics for the frame, and to perform some basic image analyses during the read/display process, and to visualize the results while the video plays:
Optionally, you are prompted to write individual frames as images to a directory, and to recall them for subsequent playback. Very useful stuff!
I have a few suggestions for consideration:
Image Analyst's video player uses "framebased" reading. In R2014b, we introduced "timebased" frame reading that can be more efficient. To modify the code to use timebased reading, consider commenting out the call to videoObject.NumberOfFrames. (That triggers framebased reading, and causes an error if you subsequently try to read using timebased modalities.) Instead, you can calculate the number of frames using numberOfFrames = round(videoObject.FrameRate * videoObject.Duration);, if you need to.
Then, instead of
for frame = 1:numberOfFrames
you can use a while loop:
while hasFrame(videoObject)
and a new readFrame command.
Also, I really like imshow for displaying images. It recognizes that the input matrix is an image, and maintains the aspect ratio. (imagedisplayed images can be stretched.) It also suppresses axes tick marks automatically, and has some other nice behaviors. Moreover, once you've created an "image object," you can reuse it quite easily by modifying the "CData" of the object. There's no need to create a new image with each frame read:
videoObject = VideoReader(movieFullFileName); frame = readFrame(videoObject); img = imshow(frame); while hasFrame(videoObject) thisFrame = readFrame(videoObject); img.CData = thisFrame; caption = sprintf('Frame %4d of %d.', ... round(videoObject.CurrentTime*videoObject.FrameRate), numberOfFrames); title(caption, 'FontSize', fontSize); end
Image Analyst uses a struct to store the frame information. The new "image datastore" functionality (introduced in R2015b) facilitates easy reference to, and visualization of, individual images. (Image Analyst shows how to create a new video from the extracted frames, but you can alternatively just display them in a loop, using the readimage method of the datastore object. (I'll leave it to you to peruse the documentation for those new capabilities.)
Comments and feedback are always welcome! Let us know what you think.
Get
the MATLAB code
Published with MATLAB® R2015b