File Exchange Pick of the Week

November 6th, 2009

Segmenting Coins…a Tutorial on Blob Analysis

Many of us who have used or participated in comp.soft-sys.matlab over the years--particularly those of us who have had occasion to solve image processing problems--have come to appreciate Image Analyst's thoughts on relevant matters.

Recently, Image Analyst had occasion to share his first file through the File Exchange--a demo tutorial on blob analysis. In a nice, well-documented bit of code, IA steps us through an approach to segmenting, and determining the properties of, some objects in an image. In this case, the image is a sample ('coins.png') that ships with the Image Processing Toolbox.

IA's code shows how one might segment objects of interest (coins) from the background, then use regionprops (my favorite IPT function!) to differentiate nickels from dimes, and dull dimes from shiny ones:

This is a nice demo--very informative, and certainly worth a read. Two thoughts: 1) IA's code uses bwlabel to calculate a connected components matrix of the image as a precursor to calling regionprops. As of R2009a, the new IPT function bwconncomp replaces bwlabel as the preferred approach; it uses significantly less memory, and can be markedly faster! Also, 2) IA shows how one can extract the specific pixels (PixelIdxList) associated with each object of interest, then calculate statistics on those pixel intensities to differentiate shiny from dull objects. Note that the fourth syntax of regionprops in the documentation enables one to avoid this step, and instead to operate directly on the original intensity image. Using this syntax, one can calculate directly the MIN, MAX, or MEAN intensitities--or even the weighted centroids-- of each blob in the image.

Nice work, Image Analyst!

Comments?


Get the MATLAB code

Published with MATLAB® 7.9

October 30th, 2009

allstats

Bob's pick this week is Allstats by Francisco de Castro.

The file is simple enough. Given a data set,

x = randn(1000,1);
hist(x,100)

allstats returns a list of statistical values.

myStats = allstats(x)
myStats = 
      min: -3.1289
      max: 2.9371
     mean: -0.06815
      std: 1.0019
     mode: -3.1289
     q2p5: -1.9519
       q5: -1.7128
      q25: -0.73464
      q50: -0.072006
      q75: 0.55077
      q95: 1.6351
    q97p5: 1.8844

The mean should be close to zero,

myStats.mean
ans =
     -0.06815

and the standard deviation should be close to one.

myStats.std
ans =
       1.0019

How convenient.

As it turns out, this month the File Exchange recently celebrated a major milestone. Allstats has the honor of being the official 10,000-th submission. Congratulations to Francisco and every contributor who made this possible! Growth of the File Exchange has been absolutely amazing.

If only my retirement account was that impressive! (sigh)

Comments?


Get the MATLAB code

Published with MATLAB® 7.9

October 23rd, 2009

Object Oriented Programming (MATLAB vs others)

Jiro's pick this week is "Comparison of object oriented code" by our very own Stuart McGarrity.

To some of you, this may be old news, but I know that not everyone is up to date on newer features. The new Object Oriented Programming capability that was introduced in R2008a has been highlighted several times by Loren, Doug, and Steve.

This entry by Stuart provides a nice syntax comparisons between MATLAB and a few of the common object oriented languages (C++, Java, Python, Ruby). Take a look at the published HTML to read about it and get a quick side-by-side comparison of these languages.

Note: as Stuart mentions in the comments, this is a syntax comparison, and it is not meant for showcasing best practices. The documentation is a good place to get such info.

Comments?


Get the MATLAB code

Published with MATLAB® 7.9

October 16th, 2009

Circular Statistics Toolbox (Directional Statistics)

Bob's pick this week is Circular Statistics Toolbox (Directional Statistics) by Philipp Berens.

I remember lots of A-ha moments in college when I realized the significance of yet another application for Fourier transforms. For example, calculation of power spectral density in signal processing. The central limit theorem was another pleasant surprise. This submission stirred those memories: not unlike bumping into an old friend you haven't seen for a long time. Now all I need is a compelling problem that requires circular or directional statistics so I can truly internalize the value of these tools for myself.

Philipp first submitted this file in January 2007. There have been a number of review comments over the years. It is currently rated 4.4 (on the 5 point scale).

Downloads have averaged almost 9 per day over the past month as well. So others clearly appreciate it. I also appreciate that Philipp recently updated the submission in response to feedback from others. In addition, follow the Acknowledgements trail to see that Circular Statistics Toolbox (Directional Statistics) was inspired by Circular Cross Correlation which also inspired Fast Circular (Periodic) Cross Correlation. That's social computing. Keep up the great work, everyone.

Comments?


Get the MATLAB code

Published with MATLAB® 7.9

October 9th, 2009

Colored Area on a Curved Surface

Bob's pick this week is Colored Area on a Curved Surface by Michael Wunder.

This is a nice example of quantitative image analysis. Given a heat map and region of interest based on elevation,

compute the surface area.

See Michael's published example for the step by step details.

Comments?


Get the MATLAB code

Published with MATLAB® 7.10

October 2nd, 2009

Integrating the File Exchange with the MATLAB Desktop

This week's Pick of the Week takes a turn "out of the box"; rather than select a file, I'd like to highlight new functionality in MATLAB that allows one to interface with the MATLAB Central File Exchange directly from one's MATLAB Desktop.

As of the current release of MATLAB (R2009b), the Desktop includes a new tool called, appropriately, the File Exchange Desktop Tool. To access the tool, simply browse from the MATLAB 'Start' button to 'Desktop Tools,' and then to 'File Exchange':

From there, you'll be presented with a standard MATLAB window that will allow you to find and grab files from the Exchange.

Also, be sure to check out this mini video tutorial demonstrating these new capabilities. And be sure to tell us what you think!


Get the MATLAB code

Published with MATLAB® 7.9

September 25th, 2009

lasso.m

Bob's pick this week is lasso.m by Thomas Rutten.

Suppose you have a set of XY points. You plot them to see how they spread out. You decide a certain clump of points is special. How do you get MATLAB to know which points you care about? With lasso you can select them with your mouse!

To demonstrate I will use the sunspot example data that ships with MATLAB.

load sunspot.dat
[x,y,i] = lasso(sunspot(:,1),sunspot(:,2))
press a KEY to start selection by mouse, LEFT mouse button for selection, RIGHT button closes loop
x =
        1836
        1837
        1848
        1870
y =
        121.5
        138.3
        124.7
          139
i =
   137
   138
   149
   171
centroid = [mean(x) mean(y)]
centroid =
       1847.8       130.88

The program prompted me how to start and stop the selection. I left off the semicolon to show the values returned for further analysis (ie, centroid calculation). The first plot shows the polygon region I selected. The second plot shows the selected points with a free legend and point counter. Nice!

Note: if you like graphically interacting with your XY points be sure to check out Data Brushing introduced with R2008a.

Comments?


Get the MATLAB code

Published with MATLAB® 7.9

September 18th, 2009

Easier (and less error-prone) creation of Zip files

Brett's Pick this week is exportToZip, by fellow MathWorker Malcolm Wood.

I recently received an email from a File Exchange user informing me that a GUI I had shared for morphologically processing images (i.e., morphTool) didn't work. As it turns out, I had neglected to include in the Zip file that I uploaded a couple of functions that were called internally by morphTool.

I've made the same mistake before, and I've also downloaded File Exchange files that were missing some key functionality.

This email exchange had me thinking about writing a bit of code to automatically create my Zip files, making sure to include all necessary supporting function files. MATLAB has a depfun command that will thoroughly analyze a function and determine its dependencies, including, by default, functions in MATLAB Toolboxes. It can take a little while to generate a report, though, and does a lot more work than is necessary just to create a comprehensive Zip file. Alternatively, one can easily create a dependency report for the current file active in the MATLAB editor by using "Save and Show Dependency Report" from the Tools menu. That approach is much faster than using depfun (with its default options), but leaves you then to manually evaluate one-by-one each function that your top-level function calls. As you might guess, it's easy to miss a necessary file when you create your Zip.

Before I started coding, I thought I'd check the File Exchange (wouldn't you?), and I quickly found Malcolm's exportToZip. Malcolm's file uses his own version of depfun (called mydepfun), that smartly uses non-default behavior of depfun to automatically skip files in MATLAB Toolboxes; mydepfun returns the paths to just those files needed for the target Zip file, which is then automatically created.

I tried exportToZip on morphTool; it worked flawlessly--and quickly! And syntactically, it couldn't be easier to use:

zipfilename = exportToZip(funcname,zipfilename)

Oh, and incidentally, a new version of morphTool will go live soon. Thanks, Malcolm--you saved me a lot of time and effort!

You gotta love the File Exchange!

Comments?


Get the MATLAB code

Published with MATLAB® 7.8

September 11th, 2009

Tables made easy

Jiro's pick this week is DataTable by Paul.

MATLAB stands for MATrix LABoratory. So it's no surprise that we work with a lot of matrices. From time to time, I've wanted to embed a matrix in a Wiki page or an HTML document. The problem is that it's a tedious process to create the appropriate markup, and it doesn't scale well for large matrices.

Paul's DataTable class makes this extremely simple. Just create your matrix like a cell array, and convert it to the appropriate markup with a single command. In addition, he uses the new MATLAB Classes (introduced in R2008a) to implement his class.

Let's take a look at an example. Oh, and here is some personal info about us.

table         = DataTable();
table{2:4, 1} = {'Bob'; 'Brett'; 'Jiro'};
table{1, 2:5} = {'Occupation', ...
  'MathWorker since...', ...
  'FEX submissions', ...
  'POTW posts'};
table{2, 2:5} = {'Quality Engineer', 'July 2001', 24, 25};
table{3, 2:5} = {'Application Engineer', 'Dec 2005', 47, 27};
table{4, 2:5} = {'Application Engineer', 'May 2006', 32, 23};

% Center-align the text
table.setColumnTextAlignment(1:5, 'c')

table.toText();
|       |      Occupation      | MathWorker since... | FEX submissions | POTW posts |
|  Bob  |   Quality Engineer   |      July 2001      |       24        |     25     |
| Brett | Application Engineer |      Dec 2005       |       47        |     27     |
| Jiro  | Application Engineer |      May 2006       |       32        |     23     |

For HTML printing, simply call the toHTML method. You can even add table attributes!

table.toHTML('tableattributes', 'bgcolor="#ffcc00"');
<table bgcolor="#ffcc00">
<tr>
  <td align="center"></td>
  <td align="center">Occupation</td>
  <td align="center">MathWorker since...</td>
  <td align="center">FEX submissions</td>
  <td align="center">POTW posts</td>
</tr>
<tr>
  <td align="center">Bob</td>
  <td align="center">Quality Engineer</td>
  <td align="center">July 2001</td>
  <td align="center">24</td>
  <td align="center">25</td>
</tr>
<tr>
  <td align="center">Brett</td>
  <td align="center">Application Engineer</td>
  <td align="center">Dec 2005</td>
  <td align="center">47</td>
  <td align="center">27</td>
</tr>
<tr>
  <td align="center">Jiro</td>
  <td align="center">Application Engineer</td>
  <td align="center">May 2006</td>
  <td align="center">32</td>
  <td align="center">23</td>
</tr>
</table>

The above HTML markup renders to the following table:

Occupation MathWorker since... FEX submissions POTW posts
Bob Quality Engineer July 2001 24 25
Brett Application Engineer Dec 2005 47 27
Jiro Application Engineer May 2006 32 23

Thanks for this very useful and well-written entry, Paul!

Comments?


Get the MATLAB code

Published with MATLAB® 7.9

September 4th, 2009

Concatenate vectors of unequal lengths

Brett's Pick this week is padcat, by Jos--one of the File Exchange's most popular contributors.

MATLAB has a few containers that are useful for storing heterogeneous data. In particular, one can store just about any combination of variables or data types in cell arrays, structures, or (if you have the always useful Statistics Toolbox) dataset arrays. Sometimes you want something lighter-weight, and easy to manipulate. If you just wanted to combine several row or column vectors into a matrix, the function cat makes short work of it, if the vectors are the same length and orientation (all row vectors or all column vectors). If, on the other hand, they had the same orientation but different lengths, cat wouldn't know what to do with them.

With padcat, you could automatically combine them, padding shorter vectors with NaNs as necessary.

Say, for example, that you had four row vectors of different length:

a = 1:5 ; b = 1:3 ; c = [] ; d = 1:4 ;

and you wanted to create from them a single matrix. Try padcat:

M = padcat(a,b,c,d) % all are row vectors
M =
     1     2     3     4     5
     1     2     3   NaN   NaN
   NaN   NaN   NaN   NaN   NaN
     1     2     3     4   NaN

As an added bonus, Jos's function can generate a second output that contains a binary mask showing true (or 1) where elements of M originated from an input vector, and false (or 0) where they were padded. This can be useful if any of the component vectors themselves contain NaNs. For instance:

a = [1:3]' ; b = [] ; c = [1;NaN] ;
[M,tf] = padcat(a,b,c) % all are column vectors
M =
     1   NaN     1
     2   NaN   NaN
     3   NaN   NaN
tf =
     1     0     1
     1     0     1
     1     0     0

(Note that the second element in the third column of tf [i.e., row 2, column 3] is 1, indicating that the NaN in that position of M originated in vector c.)

Just a nice utility function to have around. Thanks, Jos!

Comments?


Get the MATLAB code

Published with MATLAB® 7.8


Bob, Brett & Jiro share their favorite user-contributed submissions from the File Exchange.

  • Daniel: Hi Doug Thanks for these videos, they have really helped me alot. I am currently looking to create a surface...
  • Jon: This is a useful tool - but in fairness I have to point out that it is remarkably similar to a routine of the...
  • oleg: The author has implemented skewness, kurtosis and checks answering appropriately to the critic.
  • Ashok: how to store 10 or more random number in a loop a loop for i = 1:n mean(i) = input(’enter the mean value...
  • Ben: Doug, Thanks for the very helpful videos! Uitables seem like a convenient way to make a customized property...
  • oleg: Allstats has no checks, no comments and could also be improved (talking about prctile implementatio). Not to...
  • Todd: Additional information and a link to download free MATLAB and Simulink LEGO MINDSTORMS NXT code can be found at...
  • Doug: @Leo, Here is the “English version” of that code. “vec = []” makes an empty variable...
  • leo: Dear Doug I have a question in your code ‘October 9th, 2009 at 13:53′ vec = []; vec = [vec val]; I...
  • Shanker Keshavdas: You sir, are a gentleman and a scholar… No really, helped me out a lot. As to what is...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.