I have published more than 560 blog posts here since 2006, and I estimate that about 98% of them started out as MATLAB scripts.Recently, I've started writing my blog posts as live scripts. Live... read more >>

]]>I have published more than 560 blog posts here since 2006, and I estimate that about 98% of them started out as MATLAB scripts.Recently, I've started writing my blog posts as live scripts. Live scripts contain not only MATLAB code, but also code output, graphics output, and formatted text, including equations. It's a really nice way to share a technical story.Now, thanks to my friends on the MATLAB Central development team, I can write a blog post as a live script -- and then you can run the code yourself in your web browser!Let me show you how it works. Here is my blog post from last week:Now scroll all the down to the bottom of the post (above the comments):Click on the "Run in your browser" button, and you'll get your own MATLAB Online session in your browser, with the contents of the live script preloaded for

...read more >>

]]>Today's blog post comes from planning one topic, but then taking a sharp left turn and doing something else completely. I was thinking about writing something related to meshgrid, and so I was... read more >>

]]>Today's blog post comes from planning one topic, but then taking a sharp left turn and doing something else completely. I was thinking about writing something related to meshgrid, and so I was looking at some old blog posts in which meshgrid was used. For example, meshgrid was used in this 30-Dec-2010 post about the a* and b* component in the Lab color space.In reading over that old post, however, I realized that I made a rather egregious conceptual error in it. I plotted colors over the domain $ -100 \leq a^* \leq 100 $, $ -100 \leq b^* \leq 100 $, using $ L^* = 90 $, without realizing or explaining that most of those $ (L^*,a^*,b^*) $ combinations are far out of the sRGB gamut. In other words, they are not really displayable (even on a wide-gamut monitor). Also, the functions I used back then have since been superseded by new functions that are not only easier to use, but are also more helpful at looking at

...read more >>

]]>A MATLAB user recently contacted MathWorks tech support to ask why the output of fft did not meet their expectations, and tech support asked the MATLAB Math Team for assistance. Fellow Georgia Tech... read more >>

]]>A MATLAB user recently contacted MathWorks tech support to ask why the output of fft did not meet their expectations, and tech support asked the MATLAB Math Team for assistance. Fellow Georgia Tech graduate Chris Turnes wrote a detailed response that I enjoyed reading. I thought it would be worth adapting the case for a blog post. Although the case is about the 1-D FFT, the underlying issues show up in image processing, too, and I have written about them in the past. (See my Fourier transform category.)Let's set up the case by starting with a sine wave at 50 Hz, sampled at 1 kHz, with 4080 samples.Fs = 1000;N = 4080;t = (0:(N-1))/Fs;y = sin(2*pi*50*t);plot(t,y)axis([0 0.1 -1.2 1.2])xlabel('t (sec)')ylabel('y(t)')grid ontitle('The first 0.1 seconds of y(t)')Next, let's compute and display the FFT, scaling the frequency axis so that it is in Hz, and scaling the magnitude by the square root of the FFT length.Y

...read more >>

]]>In this post, I'll explore how imshowpair and imfuse work.Reason: I was curious.Last month, I wrote about registering several hand-held photographs together. In that post, I used imshowpair several... read more >>

]]>In this post, I'll explore how imshowpair and imfuse work.Reason: I was curious.Last month, I wrote about registering several hand-held photographs together. In that post, I used imshowpair several times.Here are two of the images:A = imread('A.jpg');imshow('A.jpg')B = imread('B.jpg');imshow(B)And here is imshowpair in use:imshowpair(A,B)I wanted to know how this function works. Today, I thought I would share with you what I found and how I found it.Many functions in Image Processing Toolbox ship as MATLAB source code. When this is the case, I always start my code exploration by using the Debugger to follow the code as it executes, a step at a time. Here is the beginning of my code dive:The first thing I notice is that the parsed input arguments are all passed along immediately to imfuse. A few lines later, the results from imfuse are displayed using imshow.Aha! The function imfuse must be really how this is all computed. So, I continue to follow execution in the Debugger by stepping

...read more >>

]]>The typical modern French* horn, pictured below, has about 23 total feet of tubing. At the beginning and the end, the tubing is conical. In the middle, the tubing is cylindrical.Depending on which... read more >>

]]>The typical modern French* horn, pictured below, has about 23 total feet of tubing. At the beginning and the end, the tubing is conical. In the middle, the tubing is cylindrical.Depending on which valve levers are pressed, a player might be buzzing into single tube that is anywhere from 9 feet to 17 feet long (approximately). For a personal project, I wanted to create a visual illustration of these various lengths. I used an extension pole and got some help in taking several pictures. My helper used a handheld phone.A = imread('A.jpg');B = imread('B.jpg');C = imread('C.jpg');tiledlayout(2,2)nexttileimshow(A,'Interpolation','bilinear')title('Image A (length of F horn, 12 feet)')nexttileimshow(B,'Interpolation','bilinear')title('Image B (length of B-flat horn, 9 feet)')nexttileimshow(C,'Interpolation','bilinear')title('Image C (length of B horn, 17 feet)')I wanted to use these pictures to make a composite that lets you visually compare the three pole lengths. The problem is that these

...read more >>

]]>A question on MATLAB Answers caught my eye earlier today. Borys has this pseudocolor image of a weighted adjacency matrix: And he has this image of the color scale: Borys wants to know how to compute... read more >>

]]>A question on MATLAB Answers caught my eye earlier today. Borys has this pseudocolor image of a weighted adjacency matrix:

And he has this image of the color scale:

Borys wants to know how to compute the real adjacency matrix from this image, knowing that the color scale represents the range [0,5].

The problem looked interesting to me, and I wanted to give it a try.

image_url = "https://www.mathworks.com/matlabcentral/answers/uploaded_files/410520/image.png"; scale_url = "https://www.mathworks.com/matlabcentral/answers/uploaded_files/410525/image.png"; A = imread(image_url);Here is my planned approach:

1. Use the white squares to determine the grid of coordinates for the cells of the adjacency matrix.

2. Extract the

...read more >>

]]>I wrote previously about the new colorChecker, which can detect X-Rite test charts in the R2020b release. Another area of new color-related functionality is computing perceptual color differences.... read more >>

]]>I wrote previously about the new colorChecker, which can detect X-Rite test charts in the R2020b release. Another area of new color-related functionality is computing perceptual color differences. There is the new function deltaE, which computes color differences based on the L*a*b* color space and the CIE76 standard. There is also the imcolordiff function, which can compute color differences based either on the CIE94 or the CIEDE2000 standard.

I recently mentioned to someone on the Image Processing Toolbox team that I was planning to write a blog post about these functions, and he posed the following question: which two colors are the furthest apart, perceptually speaking? I decided to give that a try using $\Delta_E$. I'll formulate the problem this way: which two sRGB colors have the largest $\Delta_E$ between them?

In a related post back in 2015, I demonstrated how

...read more >>

]]>Lately, I've been spending more time on MATLAB Central, and I'd like to encourage you to try out some of the resources there, if you haven't already.

Have you heard of Cody? It is an addictive MATLAB puzzle-solving activity. You can learn a lot about MATLAB and algorithm coding approaches by trying the problems there, and especially by looking at other people's solutions. There's a competitive aspect as well, as your puzzle solutions get scored and ranked against other solutions. (In the Cody world, smaller programs get the better scores.)

This morning, for example, this Cody problem attracted my attention:

Problem 340. Find the last non-zero in a given dimension

You are given a logical matrix BW of any dimension, and a dimension dim . You need to find the locations of the last

...read more >>

]]>When I saw this picture, I was really tempted to take it into the local garden nursery and ask them how to keep color checker charts out of my rhododendrons. No, no, this post is not really about... read more >>

]]>When I saw this picture, I was really tempted to take it into the local garden nursery and ask them how to keep color checker charts out of my rhododendrons.

No, no, this post is not really about protecting gardens against unusual invaders. I was looking over the just-released R2020b Image Processing Toolbox, and I noticed that a number of color science related features made it into the release. Since I was posting about color a couple of months ago, I thought I would highlight some of these new features here. Today, I'll start with a function that can detect the location of an X-Rite® ColorChecker® chart into the workspace.

First, let's read our test image. This file contains the image shown above.

A = imread('colorCheckerTestImage-with-credit.jpg');Next, create a colorChecker object from the image.

chart = colorChecker(A) chart = colorChecker with properties: Image: [1024×1541×3 uint8]...read more >>

]]>Recently, I've been explaining how I made this plot, which is from DIPUM3E (Digital Image Processing Using MATLAB, 3rd ed.): In my July 20 post, I showed one way to compute the spectral colors to... read more >>

]]>Recently, I've been explaining how I made this plot, which is from DIPUM3E (Digital Image Processing Using MATLAB, 3rd ed.):

In my July 20 post, I showed one way to compute the spectral colors to display below the x-axis. Today I'll finish up by explaining the use of the colorbar function. These techniques are used in the DIPUM3E functions spectrumBar and spectrumColors, which are available to you in MATLAB Color Tools on the File Exchange and on GitHub. The entire set of DIPUM3E

...read more >>

]]>