This is an individual lab -- each student should submit their own lab.
When using MATLAB off-campus, you will need to use the VPN GlobalProtect. GlobalProtect can be a bit finnicky -- you may want to ask me about this if you plan to use GlobalProtect off campus. All the labs were developed off-campus, so it DOES work.
Overview
- Manipulate an image as an array of numbers
- Blur an image using Gaussian filtering
- Explain why a filter's values should generally sum to 1 if it only has positive values.
Prelab
Install Matlab 2016a on your computer. It is available through MSOE's network install. (Control Panel->Programs->Get Programs)
Deliverables
- A single Matlab file divided into cells (groups beginning with a two-percent %% comment), following this template.
- The image you worked with, saved as a "png" file. (You can save an image using
imwrite(I,'input.png')
.) - (optional) Results images that you created with your program.
Useful Matlab commands for this lab
- clear
- Delete all variables
- close all
- Close all windows
- clc
- Clear the command window (but not history)
- commandhistory
- Opens the command history window. You can then "dock" it so it is available every time you start Matlab
- imread
- Read a Matlab image. e.g.
I = imread('filename.png');
- imshow
- Show an image; open a new figure to hold the image if needed. e.g.
imshow(I)
- shg
- "Show graph"; Bring the current figure window to the front. e.g.
shg
- size
- Find the size of a Matlab array. e.g.
sz = size(I);
- zeros
- Make an array of zeros with a specified size. e.g.
black = zeros(sz);
- ones
- Make an array of ones with a specified size. e.g.
white = 255*ones(sz);
- ginput
- Allow user to click points on a graph.
e.g. [j,i] = ginput(1);
will allow you to click on one (1) point on the graph. If you do not supply an argument,ginput
will keep collecting points until you press the enter key. - imfilter
- Filter an image using correlation. e.g.
I2 = imfilter(I2, [-1 0 1]);
is a simple derivative filter in the j direction. - normpdf
- Create a Gaussian filter (or Probability Distribution Function -- PDF). e.g.
blurFilter = normpdf(x,mu,sigma)
- double
- Convert an image to the double type. e.g.
I = double(I)/255;
- class
- Find the type of an array. e.g.
cls = class(I);
- plot
- Plot 2-d data. e.g.
plot(x,y,'ro-')
. If you usedoc
for help, be sure to check out the LineSpec link.
If you would like more information about any of these functions, use help functionname
to get the command-line help. doc functioname
brings up the full Matlab help browser for that function.
You may have noticed in the examples above, some commands end with a semi-colon, while others do not. This is because the semicolon is not required on statement endings. Matlab uses one line for each statement. (If you want to continue a statement over multiple lines, use ...
at the end of each line except the last one.) The semi-colon is used for hiding the result of a statement. So if you want to hide the results of a Matlab statement (which you generally do if it is a HUGE image), put a semicolon at the end of the line. If you want to see the results printed to standard-out, leave the semicolon off. (In the examples above, the commands without semicolons don't have any output at all.)
This Matlab Tutorial from Brown University is very good. Everything discussed in the tutorial is essential to programming in Matlab1. Although I try not to assume familiarity with Matlab in this lab, if this is your first time using Matlab, I encourage you to work through the tutorial in depth.
In particular, the tutorial has a section on working with images. Search for %(8) Working with (gray level) images
. It's at the end.
1. Opening and displaying an image.
(The numbers of the sections correspond to the code cells in the required lab template)
Select any image file on your computer. The .jpg, .bmp, or .png formats work fine. Open the file with imread
and display it with imshow
. shg
may also be helpful here.
As you work through this lab, you may want to just "try things" at the Matlab command prompt and then paste what works into your .m file. Do run clear; close all
to clear all your variables and close all your figure windows, then re-run everything from your file to make sure it is complete!
2. Look at an interesting point on your image.
2.a. ginput
Use ginput
to select an interesting point on your image. Try to choose a point with high contrast (both dark and bright values), perhaps a sharp corner or an edge. [j,i] = ginput(1);
will assign values to variables j and i (in that order).
2.b. Create a chunk of the image
Manually create code that assigns the same values, e.g.i = 148; j = 236;
(You may be wondering why I am encouraging you to hard-code a value. The scripting techniques we use in this lab are for creating "scratch code" in matlab. Creating scratch code is an effective way of interactively creating short snippets of code, which you can then refactor into proper Matlab methods/functions.)
This makes it easy to go back to the point you selected earlier.
Select a portion of the image near that point. Your chunk should be about 10 pixels wide, 10 pixels tall, and have all three image channels. It should be an array of size roughly [10 10 3]. To select a sub-array, it is helpful to play with Matlab's range options. Consider these examples to get started:
x = [1 2 3 4; 5 6 7 8 9 10 11 12]; x(1,1) % this prints 1, not 6. Matlab is 1-based, not 0-based! y = x(:,3); % Ask yourself: What does this do? y = x(2,2:3); % Ditto. % Can you combine these techniques to take a chunk out of % a three-dimensional image array?
If you would like more than these enigmatic hints, try the Matlab Tutorial from Brown University.
Some useful things to know about images in Matlab:
- The first index is for the row of the pixel
- The second index is for the column of the pixel
- The third index is for the color channel within the pixel, in the order red, green, blue (RGB)
For example, value = I(1,5,3);
will give you the blue brightness of the pixel in row 1, column 5. It will give you the blue component because 3 indicates the third channel of RGB.
It is OK if your selection is hard-coded to this particular image. In future labs, you will do this sort of thing programmatically.
Display your small image chunk. Does it look like the point you clicked?
Print your small image chunk to standard out and include it in a comment, like this: (You can comment a block of text by pressing Ctl-R, you can uncomment with Ctl-T.)
% Ismall(:,:,1) = % % 221 222 215 218 216 218 221 217 226 215 218 % 221 222 218 218 210 212 219 222 234 218 214 % 217 219 226 221 219 213 217 216 223 219 214 % 219 219 220 222 229 224 221 221 221 218 214 % 217 215 197 210 220 223 216 214 225 211 216 % 217 221 217 227 197 199 197 185 207 214 218 % 214 217 217 213 194 196 195 174 155 217 222 % 216 217 215 230 202 195 222 221 184 202 220 % 213 215 221 198 176 173 192 186 170 204 217 % 215 215 202 191 204 188 164 122 156 223 215 % 214 212 207 181 185 190 186 172 180 212 215 % % % Ismall(:,:,2) = % % 221 222 221 227 222 223 226 222 220 224 222 % 219 220 218 223 220 219 219 217 219 221 225 % 221 219 221 218 226 224 223 221 215 224 223 % 219 219 218 213 220 222 222 225 218 219 224 % 217 218 217 228 222 217 214 212 225 224 218 % 217 217 217 211 130 104 101 91 158 233 219 % 216 217 222 198 89 72 78 60 107 225 220 % 214 216 225 218 134 95 124 111 125 215 224 % 213 214 201 149 104 81 92 75 107 219 222 % 211 220 117 73 100 95 84 54 97 218 220 % 213 221 133 71 90 88 90 82 90 195 223 % % % Ismall(:,:,3) = % % 219 220 217 222 220 219 220 215 222 223 221 % 220 221 216 226 229 227 221 213 222 214 219 % 220 217 215 209 218 218 221 214 213 220 218 % 217 217 221 218 225 225 226 234 227 213 216 % 217 211 224 230 219 201 201 200 223 217 217 % 215 216 209 196 88 60 63 57 151 231 214 % 211 215 225 191 31 12 24 0 93 228 223 % 217 214 227 220 87 43 61 22 91 223 223 % 213 220 174 117 46 34 56 29 89 226 215 % 210 223 76 25 49 52 51 9 79 222 213 % 208 216 94 22 36 40 48 30 53 188 208
Can you see the shape that you selected in the values in the image? Write a comment about what you learned from looking at these raw numbers below the numbers.
Displaying a single-color chanel
To display a single color channel of an image, you can extract that color channel using Matalb's indexing, for example, to display the red channel, you could use imshow(I(:,:,1));
. However, this image will appear gray. To create an image that looks red for a red channel, you can create a full-color image that only has zeros for the second and third "image planes."
Here are two ways to do this:
% Clear the blue and green channels Ired = I; Ired(:,:,2:3) = 0; imshow(Ired) shg % Create a new image and copy over the red channel Ired = zeros(size(I)); Ired(:,:,1) = I(:,:,1); imshow(Ired/255)
Notice that the first image is shown with imshow(Ired)
, while the second uses imshow(Ired/255)
. This is because in the first image, Ired has the type uint8, and in the second image, Ired has the type double. imshow
interprets the image as being in the range 0-255 for uint8, and in the range 0-1 for doubles.
Matlab uses the type double by default, and it is fine if you do that throughout these labs. If you want to convert an image to the double type, use I = double(I)/255;
. You can use class(I)
to find the class of an image.
Another option that could be handy is the imagesc(I)
, which is like imshow(I)
, except it automatically re-scales the intensities in the image to go from full black to full white before displaying it. It seems to throw errors on me a lot, though, so I just use mx = max(I(:)); imshow(I/max)
instead.
You do not need to report anything for this section. It is preparation for the next section.
3. Creating a gray-scale image
Keeping track of the three color channels can be a challenge. So we often make a gray-scale version of an image.
In this section, you will create a gray-scale version of an image, by averaging the color channels for each pixel in the image
For each pixel in row i, column j, you can compute a simple gray-scale image as grayi = 1/3 (ri,j + gi,j + bi,j). However, you do not need to create any loops to create this gray-scale image. If you add two arrays in Matlab, it will automatically perform the operation for each element. e.g. [1 2] + [30 40]
will yield [31 42]
.
It might help to convert the image to the double type, otherwise you can have issues with rounding error.
4. Blurring an image
To blur an image, use some of the commands from the top of the screen. imfilter
is one of them. As long as the image "looks" blurred, you have succeeded - there are many ways you could do this.
Fun Ideas
- You can downsample an image by selecting every other pixel along the rows and columns. Can you do a simple downsampling using Matlab's range operators? If you want to store your downsampled images in a single variable, a cell array might be useful. (Not to be confused with cells in a .m file, which are completely different.) Cell arrays are like matrices, except that they can hold any matlab object in each position. Try
stack{1} = I;
,imshow(stack{1});
, etc. - Can you create your own image by alternating black and white images between rows? (You can use the Matlab range operators and indexing for this, too.)
- Logical indexing is a powerfull alternative to range indexing. In a logical index, the index is an array the same size as the image (or as one dimension of the indexing). You can create a logical mask with an expresssion like
mask = I > 0.5;
, and then only edit the selected pixels with an expression likeI(mask) = 0
. What creative images can you come up with using masking? (If you want to use a mask on a binary image, you will need to duplicate it for each channel, e.g.[mask(:);mask(:);mask(:)]
) - You can also create fun images using alpha-compositing. This is where you combine images together, but multiply them by an "alpha" mask first. What fun images can you come up with using an alpha mask? (How might you compute the mask automatically from the image? Or from some simple user input?)
- The gray-scale method we use in this class works well, but other weightings of the channels can give more pleasing results. Look up in the text the section on color, and try converting your image to gray-scale (or a different full 3-d color space like YCrCb). Does this make your grayscale image look better? Do you think using a color space closer to human perception would increase the performance of your computer vision algorithms? (You may want to revisit this question later in the quarter.)
- What would you like to do automatically from images? Give it a try!
The fine print
1 Except you should use (1:10) instead of [1:10]. As the squiggly orange mlint line will tell you, brackets are unnecessary around a range. They imply a call to the concatenation function, so using parenthesis will save you a few clock cycles.