Sunday 11 December 2011

Changing the bit depth of images using ImageMagick

Today I wanted to create a simple black-and-white version of a grayscale image that I have. This is pretty easily done in Matlab (you can scale the image to values between 0 and 1 and use round()), but I was guessing there was probably already some simple way to do it in ImageMagick - and there is!

This is the original version of the image (from the great graphical novel series "Bone"):


To convert it to a 3-bit image (8 levels), I used the -depth switch with the convert command:

convert bone.jpg -colorspace gray -depth 3 bone3bit.jpg


And similarly, for black-and-white (1 bit image):

convert bone.jpg -colorspace gray -depth 1 bone1bit.jpg






Friday 11 November 2011

Setting up Matlab mex compilation in Ubuntu


NOTE: This post was updated on January 16, 2012.

Recently I have been trying to compile some Matlab mex-files from the excellent Machine Vision Toolbox by Peter Corke. When I first tried to compile, I got the following warning:

Warning: You are using gcc version "4.6.1-9ubuntu3)".  The version
         currently supported with MEX is "4.3.4".

I tried several ways of "downgrading" gcc, but as it turns out, the newer version of gcc on Ubuntu 11.10 is backwards compatible and works fine. The message above is simply a warning, not an error, and there is no need to change gcc to an older version. However, my real problem was this: I got errors of the type

error: expected expression before ‘/’ token

I had no idea why this error was popping up, until I read a post on similar issues on xcorr. It turns out that C++ style "//" comments are not allowed in the standard mex configuration that is set when you run "mex -setup". To avoid the error, open the mexopts.sh file (mine is located in ~/.matlab/R2011b/mexopts.sh), and replace all occurences of "-ansi" with "-std=c99".

Thursday 3 November 2011

Batch renaming files in Ubuntu Linux

I often deal with a large number of data files, for example files containing ultrasound data from experiments. Recently I had to rename about 200 files which were named something like this,

oldName001.mat, oldName002.mat, ..., oldName200.mat

to something like this:

newName001.mat, newName002.mat, ..., newName200.mat

Basically, I wanted to keep the numbering but change the base of the name. I found out that on Ubuntu 11.10, which I'm currently using, there are two different flavors of the "rename" command. One is a Perl script, and using this, the syntax for doing the above operation is

rename "s/oldName/newName/" *mat

To test without actually renaming, use the "-n" switch. Type "man rename" or have a look at these Webmaster Tips for several more examples of this usage. However, there is also a rename command as part of the linux-util package. To distinguish this from the above command in Ubuntu, call the command as rename.ul:

rename.ul oldName newName *mat

Notice that the syntax is simpler and easier to remember for this version. Type "man rename.ul" or have a look at this NixCraft post for more examples. 

Finally I found out that it is also possible to batch rename files using Thunar, which is the default file manager in Ubuntu 11.10. Mark all the files, right-click and choose "rename", and use the "Search and replace" option.

Wednesday 26 October 2011

Installing Matlab with standalone user on Ubuntu Linux

OK, after doing this in an awkward manner a couple of times, here is how I install Matlab on Ubuntu with a standalone license:

  • Download the files from Mathworks
  • Run the install script with sudo (as root), but DO NOT activate the license yet. Choose custom install, use default install location, tick the box for creating symbolic links.
  • After installing, try to run Matlab (not as root). The activation procedure will start automatically. Register your own user name for the standalone license.
  • Matlab (with GUI) can now be run by calling the command "matlab -desktop". To create a application launcher for it, use the "Main Menu" program (also called Alacarte, can be installed with the Ubuntu Software Center). Get a logo for the launcher here, or put it right where it belongs by using this command:
sudo wget http://upload.wikimedia.org/wikipedia/commons/2/21/Matlab_Logo.png -O /usr/share/icons/matlab.png

I also recommend having a look at the Ubuntu Documentation for Matlab installation. It might not always be completely up to date, but the procedure doesn't change much between releases.

Monday 10 October 2011

Merging images into movie using FFmpeg

Let's say that you have a number of images, named image001.jpeg, image002.jpeg, image003.jpeg etc., and you want to merge them into a single movie, for example to create a time-lapse video. FFmpeg is a great commend-line tool for doing this kind of stuff. To use FFmpeg to create the movie "outmovie.mp4", with 25 frames per second and reasonable quality, enter

ffmpeg -i image%03d.jpeg -sameq -r 25 outmovie.mp4

Note the format image%03d.jpeg, indicating that the numbering of the files has three digits with (possible) leading zeros. To set the output bitrate explicitly to for example 64 kbits/s, use the switch "-b 64k" rather than "-sameq". See the FFmpeg documentation for lots of other possibilities.

Wednesday 5 October 2011

Converting images from PDF to PNG using ImageMagick

I usually prefer vector formats like PDF for my figures, but some times I need to make a PNG version. ImageMagick is my tool of choice to do this, since it can be called from the command line. My initial try was something like this:

convert figure.pdf figure.png

which indeed converts the figure from PDF to PNG, but with a much too low resolution in the PNG image. After reading up on the subject on the Magick-users mailing list and the ImageMagick documentation, I found out that the default resolution at which the PDF file is read is 72 DPI. To read with a higher resolution, for example 600 DPI, use the -density option:

convert -density 600 figure.pdf figure.png

As a little side comment, I could mention that I first tried to do this because when I saved a figure from Inkscape as PNG, the resolution was very poor. The workaround was then to save as PDF and convert to PNG. However, afterwards I remembered that Inkscape also has a "export bitmap" option, which will allow you to set the density before saving to PNG. Oh well, the ImageMagick conversion may still come in useful some day...

Thursday 29 September 2011

Matlab and version control with Subversion

At my company, we use Subversion for version control of our software. I currently use RabbitVCS as a file explorer front-end for Subversion (in Ubuntu Linux), but I've been looking for a way to use Subversion directly from Matlab.

I haven't found any solution that fully integrates with the file explorer in Matlab yet, although there are some useful tools available. However, it wasn't until today that I realized (the bleeding obvious fact) that the Subversion command line interface can be used directly from the command line. Simply put an exclamation mark in front and call the svn commands as usual, for example:

!svn help
!svn status
!svn add file1.m
!svn commit -m "This is a log message"

The command line version of Subversion is both simple and reliable, so until the Mathworks makes an official Subversion plugin, I guess I'm sticking to this approach.

Thursday 15 September 2011

Using ImageMagick to convert images to grayscale

Although color images are nice, I try to avoid using them in articles, as that always costs extra. Sometimes I also prefer grayscale images for presentations, since the colors of the projector can often be quite different from what I see on my screen.

Anyway, here is a simple way to convert an image from color to grayscale using the command line tool ImageMagick:

convert inputFile -colorspace Gray outputFile

Monday 12 September 2011

Plotting polar images in Matlab

I'm currently working with ultrasound images acquired on a polar grid, with equispaced range and angle values. Such images cannot be plotted directly using the image or imagesc command in Matlab, since it requires a x-y grid of coordinates. At first I tried resampling the polar image to a rectangular grid using a 2D interpolator (TriScatteredInterp), which works but takes quite a lot of time. However, at a conference I attended recently I got a very useful tip from Marcelo Matuda from the University of São Paulo: 

Convert the polar coordinates to rectangular coordinates, and plot the image as a surface, seen directly from above. Simple! And fast.

Here is a little example code that illustrates this approach:

%% ---------------------------- %%
close all
clear all

%% Create an example image using peaks function
im = peaks(512);

%% Specify axes for the image (chosen arbitrarily)
[nZ,nX] = size(im); 
theta = ((0:(nX-1))-nX/2)*(0.1*(pi/180)) - pi/2;
rr = (0:(nZ-1))*0.1e-3 + 0.05;

%% Plot image in rectangular coordinates
figure
imagesc(theta*(180/pi), rr*1e3, im)
xlabel('theta [deg]')
ylabel('r [mm]')

%% Create grids and convert polar coordinates to rectangular
[THETA,RR] = meshgrid(theta,rr);
[XX,YY] = pol2cart(THETA,RR);

%% Plot as surface, viewed from above
figure
surf(XX*1e3,YY*1e3,im,'edgecolor','none')
view(0,90)
xlabel('x [mm]')
ylabel('y [mm]')
%% ---------------------------- %%

The code outputs two images, one of the polar plot made using the imagesc command:


... and one with the "proper" polar plot using surf: 


Sunday 4 September 2011

Fixing SD card error on HTC desire

I recently started getting problems with the SD card on my HTC Desire phone. A notifier saying that "The SD card has an unexpected problem ..." would pop up, and if I tried using the camera, an error message would display, saying that the the SD card was mounted as read-only.

After some googling I found that several others had a similar problem. After reading this post I tested running mounting the card in a card reader and running the dosfsck command, with syntax

dosfcsk -va /dev/sdb1

This executed without error, but after putting the card back in the phone, I found that the same error messages were still popping up. After reading this forum thread, I finally decided to back up the contents of the card, and reformat it to FAT32 it using GParted. Even if this is possibly a suboptimal solution, it fixed the problem, and I once again have a functioning phone.

Thursday 1 September 2011

Cropping an image from the command line (/Matlab)

I recently had to crop some figures which had a lot of unnecessary white space on the sides. The figures were made in Matlab, and I wanted to find some way to do the cropping from the command line, to avoid manually editing each image.

As always when it comes to image editing, ImageMagick provides a solution, as explained here. The "convert" command is used to crop images with the following syntax:

convert -crop (width)x(height)+(horzOffset)+(vertOffset) infile outfile

where (horzOffset) and (vertOffset) denote the pixel coordinates of the upper left corner of the cropping window (sideways, down). The parentheses are not included in the syntax. Example:

convert -crop 1800x1597+700+0 im1.png imCropped.png

crops im1.png to size 1800x1597, with 700 horizontal offset and 0 pixels vertical offset. To do the same from Matlab, simply use the "system" command:

> system('convert -crop 1800x1597+700+0 im1.png imCropped.png')

Wednesday 6 July 2011

Setting up dual displays in Ubuntu (VGA & DVI)

For a time, I've been wondering how to set up dual displays in Ubuntu. I have two screens connected, one via DVI and one via VGA. Whenever I tried using both, the VGA screen would always be placed to the left, whatever setup I made in the display settings. Finally, I found the solution in Mark's blog post.

The key is the xrandr command line function. I first enabled both displays under the display settings, and then used the command

xrandr --output VGA1 --right-of DVI1

Note that you may have to call the xrandr function without any arguments first, to find the name for each screen.


Wednesday 18 May 2011

Removing N first characters from each line in a file

I recently had to remove the 5 first characters from each line in a text file; it was a source code file copied from the internet with the line numbers included. I found a nice way to do this in a forum post:

sed -i 's/\(.\{5\}\)//' file.m

Here, the "sed" function of the Linux command line is used with the -i (for "in place") switch to remove the 5 first characters from each line in the file "file.m". It looks a bit messy, but it works.

Wednesday 4 May 2011

Using LaTeX in Inkscape Drawings

I use Inkscape to draw all my vector graphics. I often use these graphics in combination with PdfLaTeX to write papers and Beamer presentations. However, one of the things I have been struggling with is how to include greek letters and mathematical formulas in the graphics. One simple solution for displaying Greek letters is to use the corresponding unicode. For example, to display the letter gamma, create a text box, press Ctrl+U, and enter <03B3>. However, the character will (usually) not be available in the same font as the LaTeX document, and it is also hard to write anything more complex than single characters.

It was not until today that I found out that Inkscape actually has a export option that solves this problem quite nicely. This is documented very nicely here. To create a drawing with LaTeX elements, simply enter the LaTeX code in a text box, export as PDF, and cross the box in the PDF export options. This will export the graphics to a PDF file and the text to a separate .tex file, which can then be included in the LaTeX document using this syntax (or similar):

\begin{figure}
\centering
\def\svgwidth{\columnwidth}
\includesvg{image}
\end{figure}

where the file name of the exported graphic is "image". Note that no additional packages are needed. Consult the documentation for more details.

Tuesday 3 May 2011

Spell checking LaTeX documents

Spell checking a LaTeX document is different from spell checking a plain text document, since the LaTeX document contains commands that should be ignored by the spell checker. For example, consider this command for including a figure with a caption:

\begin{figure}
\centering
\includegraphics[width = 7cm]{image1}
\caption{Focused image of piont scatterer.}
\end{figure}

Here, a spell checker should not suggest changing "\includegraphics" to "include graphics", but it should suggest changing the misspelled "piont" in the caption to "point". Luckily, there are spell checkers that interpret LaTeX commands, and I am currently using one of them, Aspell. In Linux, Aspell is easily installed by the following commands:

apt-get install aspell
apt-get install aspell-en

which installs both the program and the english dictionary. To spell check a LaTeX file called paper.tex on the command line, type

aspell -c paper.tex

Note that Aspell (and its relative Ispell) can also be used at runtime by text processing programs like Kile.

Thursday 28 April 2011

Concatenating binary raw data files

At my company, Breivoll Inspection Technologies, we perform inline ultrasound scans of water pipelines, and the resulting raw data is stored in a number of binary files for postprocessing. I was looking for a simple way to combine these files, and found out that the familiar cat command (on Linux) does the trick:

cat *.dat > mergedFile.dat

This concatenates all the .dat files in the current directory and outputs them into mergedFile.dat. Note that although cat is often used for text files, it works just as well for binary files.

Another note: In some cases, a raw data file may contain headers or footers that should not be included when the files are concatenated. I found a simple solution in this forum post. For binary files, a number of bytes can easily be stripped away from the beginning and the end of the file by using the dd command, for example:

dd if=input.dat of=output.dat bs=1 skip=X count=Y

This skips the X first bytes of the input file, and writes the following Y bytes to the output file. See the help section on the dd command for more options.

Sunday 3 April 2011

The Acoustic Ghost in the Machine

I came across this awesome article when doing research on another topic. Haunting "supernatural" events can be explained by simple acoustics - infrasonic waves are the Ghost In The Machine! :D

Abstract: In this paper we outline an as yet undocumented natural cause for some cases of ostensible haunting. Using the first author’s own experience as an example, we show how a 19hz standing air wave may under certain conditions create sensory phenomena suggestive of a ghost. The mechanics and physiology of this "ghost in the machine" effect is outlined. Spontaneous case researchers are encouraged to rule out this potential natural explanation for paranormal experience in future cases of the haunting or poltergeistic type.

Wednesday 19 January 2011

Inline comments in LaTeX

I recently got some feedback on an article that I've submitted, and when I started including the reviewer's comments in the revised version, I started wondering if there is a way to make an "in-line" comment in LaTeX documents. I often use the percent sign, %, to comment out everything after a line, like this:

... and thus we see that these methods are equvivalent. % Or are they?

After some searching I found an interesting post on Eric Rasmussen's blog, and it seems that the easiest way to do this is to define a "macro" that doesn't do anything, in the document preamble:

\newcommand{\comment}[1]{}

and then I can make an inline comment using the \comment{} command, like this:

... these methods are equvalent. \comment{Or are they?} Luckily, it doesn't matter...

Thursday 13 January 2011

Compressing Matlab AVI videos in Linux

Recently I've started making a few movies in Matlab. This is actually quite easy - for an example see this description from the Matlab documentation. Unfortunately, the movie2avi() function does not apply any compression when writing the movie to file (not in Linux, anyway), and this results in very large movies (on the order of 100 MB for a few seconds).

However, I found a solution. I originally posted it as a reply in the MATLAB Newsreader, but I thought I'd share it here as well:

You can transcode Matlabs AVI movies using FFmpeg (www.ffmpeg.org). If you don't have the package, you can install it using the terminal:

sudo apt-get install ffmpeg

If you have only one file, let's call it inputFile, you can transcode it using something like this:

ffmpeg -i inputFile.avi -sameq outputFile.avi

The "-sameq" option is used to preserve video quality. I tested this on a 80 MB file produced by Matlab, and got a 5 MB file without any visible loss in quality. If you want to do it within your matlab script, use the system() command:

system('ffmpeg -i file1.avi -sameq outputFile.avi')

If you have a problem with the Matlab AVI file growing too big, you can split it into several smaller files and compress them as you go, and finally combine them after your iteration has finished. A way of doing this is described here in the FFmpeg FAQ. Note that you will have to transcode your intermediate files to MPEG format. .