CS 332
Assignment 1 Due: Thursday, September 19 |
The aim of this assignment is to help you learn some of the basics of MATLAB programming and begin thinking of 2D matrices as representations of images, with the value at each location representing the light intensity at a corresponding position in a 2D image. Problem 1 also offers an opportunity for a little creative image-making.
For this assignment, create a folder named assign1
and store all
of your code files in this folder. While your work is in progress, store your
assign1
folder in your personal directory on the CS file server. Details on
submitting your final assignment work are given at the end of this assignment.
In MATLAB, it's easy to create an image with rectangular blocks of constant intensity. The following code creates an 8-bit gray-level image that has a background intensity of 0 and two overlapping blocks with intensities of 100 and 200:
% create an 8-bit image of size 200x200
image = uint8(zeros(200,200));
% add two rectangular blocks of constant intensity
image(40:80,30:120) = 100;
image(60:150,100:180) = 200;
This code is contained in the makeBlocks.m
script file in the lab2
folder that we explored in lab. You can run this script and view the image by executing the
following commands in MATLAB's Command Window:
>> makeBlocks;
>> imtool(image);
(1,1)
(200,1) | |
(1,200)
(200,200) |
The coordinates shown at the four corners of the above image are the pixel coordinates
(X,Y)
printed
in the bottom left corner of the Image Tool display window. In pixel coordinates, the
location of the upper left corner of the darker gray block is (X,Y) = (30,40)
. In
the matrix indices, the order of the two dimensions is reversed, so the matrix location of
this upper left corner is image(40,30)
(i.e. row 40, column 30, of the
image
matrix). Carefully examine the relationship between the ranges of
coordinates in the above script and the position and size of the two blocks.
Part a (15 points): Making circles
Your first task is to write a MATLAB function named addCircle
that adds a
circular patch of constant intensity to an input matrix. The function should have inputs and
outputs as shown in the following header:
function newImage = addCircle(image, xcenter, ycenter, radius, intensity)
Assume that the input image
is a 2D matrix of uint8
values
that already exists. The circular
patch of intensity should be centered at pixel location
(X,Y) = (xcenter,ycenter)
and should have the specified input radius
and intensity
.
Your function can first alter the contents of the input image
matrix to add
the new circle, and then copy the new contents of the image
matrix into
newImage
at the end of the function definition, using a single assignment statement:
newImage = image;
Alternatively, you can copy the original contents of the input image
matrix into
newImage
at the beginning of your function definition and then modify the contents
of newImage
to add the circular patch.
When constructing the nested for
loops to step
through the region of the matrix where the circle is added, think about how the range of values
for the control variables in the for
statements can be specified in a way that
avoids unnecessary computations. You can assume that this function will be called with
appropriate input values, so that the circular patch fits within the bounds of the matrix.
Store your new function in a file named addCircle.m
in your assign1
folder. Be sure to place a semi-colon at the end of each statement that generates a value,
to avoid unnecessary printout during execution of the function. The following example
illustrates the application of this function:
image = uint8(zeros(200,200));
image = addCircle(image,80,50,30,100);
image = addCircle(image,150,100,20,200);
The first, larger circle is centered at pixel coordinates (X,Y) = (80,50)
and
the second, smaller circle is centered at pixel coordinates (X,Y) = (150,100)
.
Part b (15 points): Creating color images
Color images can be stored in 3D matrices, where the third dimension stores the amount of
red, green and blue that combine to form a particular color. For example, load the
"peppers" image into MATLAB and view it with imtool
:
peppers = imread('peppers.png');
imtool(peppers);
If you enter the whos
command, you'll see that peppers
is a
384x512x3
matrix of uint8
values.
The "Pixel info:
" printed in the bottom left corner of the Image Tool window now displays
three intensity values corresponding to red, green and blue, e.g. [218 190 152]
.
You can use the Pixel Region Tool to examine the RGB values in image regions of different color.
A colorful RGB image of rectangular patches can be created by placing intensity values in
a 3D matrix, where the third dimension specifies color. The following code shows how
this idea extends to three dimensions (this code is also contained in the
makeBlocks.m
script):
% create an 8-bit image of size 200x200x3
colorImage = uint8(zeros(200,200,3)); % 3D matrix
colorImage(40:80,30:120,1) = 200; % patch of red
colorImage(40:80,30:120,3) = 200; % mixed with blue
colorImage(60:150,100:180,2) = 255; % patch of green
Matrix location colorImage(y,x,1)
specifies
the amount of red that is displayed at pixel location (x,y)
, while
colorImage(y,x,2)
specifies the amount of green and
colorImage(y,x,3)
specifies the amount of blue displayed at pixel location
(x,y)
. In this example,
the upper left rectangle has red, green and blue values of 200, 0 and 200, respectively.
The mixture of red and blue creates the color magenta. The lower right triangle has red,
green and blue values of 0, 255 and 0, respectively, corresponding to pure green.
The overlapping region has a combination of all three colors, creating a whitish color.
Create a modified version of the addCircle
function named
addColorCircle
that adds a circular patch of constant color to an RGB image:
function newImage = addColorCircle(image, xcenter, ycenter, radius, r, g, b)
This function should assume that the input image
is an existing 3D matrix of
uint8
values representing an RGB image. The circular patch of color should
be centered at pixel location (X,Y) = (xcenter,ycenter)
and should have the
specified radius
. The input RGB values should be placed in the third dimension
of the matrix. Note that addColorCircle
can be very similar to
addCircle
! As a starting point, you can copy-and-paste your
addCircle
function into a new M-File window in the MATLAB editor, save it in
the file addColorCircle.m
and then modify the code as needed.
Part c (10 points): Create images of blocks and circles
To demonstrate your new addCircle
and addColorCircle
functions,
write a script
that creates two images, one gray-level image and one RGB image. In
these images, place blocks and circles of constant gray-level intensities or colors. Experiment
with different colors, sizes and positions of the figures, and think about trying to design
a particular scene, such as a bunch of balloons. Keep in mind the relationship between matrix
indices and pixel coordinates. Have fun with this part! Note that you now have the tools to
create images for some visual illusions, such as some of the static "Luminance & Contrast"
illusions at Michael Bach's illusions website:
http://www.michaelbach.de/ot/
One way to blur an image is to calculate the average intensity within a neighborhood of each
location. Write a function named blurImage
that creates a blurred version of an
image using this technique. This function should have two inputs that represent the input
image and the size of the neighborhood, and a single output that is the new, blurred version
of the image. Assume that the input image is a 2D matrix of gray-level intensities ranging
from 0 to 255 (i.e. of type uint8
). The output matrix should be the same size as
the input matrix, and can be created initially using the uint8
and
zeros
functions. Suppose we let
nsize
denote the input neighborhood size. Then the value stored in location
(x,y)
of the output matrix should be the average of the intensities in the input
matrix calculated over a square region from (x-nsize,y-nsize)
to
(x+nsize,y+nsize)
. This average can be converted to an integer using the
round
function. You do not need to calculate average values for the region
of width nsize
around the outer border of the image (these values can remain zero).
Think about how the built-in sum
function combined with colon notation
can be used to add the intensity values within a square neighborhood around each location
— you do not need to create an additional pair of nested for
loops to
perform this step. Test your function by creating blurry versions of simple images that you
create.
The images that you created in Problem 1 consist of patches of uniform intensity with sharp
intensity changes at their borders. The simplest way to find the edges in such images is to
scan each row of the image from left to right and look for a change of intensity between
adjacent pixels in the horizontal or vertical direction. Write a new function named
findEdges
that has a single input that is a 2D gray-level image. This function
should return a 2D matrix of 8-bit values (i.e. with numbers of type uint8
) of the same
size as the input image, which has the value 255 at the locations of edges in the input
image, and the value 0 elsewhere. To find the edges, the intensity at location
(x,y)
can be compared to the intensities at locations (x-1,y)
and
(x,y-1)
. If there is a difference of intensity in either direction, then 255
should be placed in the output matrix at location (x,y)
. You do not need to
detect edges along row 1 and column 1 of the input image. Test your function with simple
images that you create.
Some applications of computer vision systems involve counting objects of a particular type in an image, and possibly computing the size or shape of these objects. An early medical application of this sort involved counting and analyzing the shapes of different types of cells in cell cultures. I once attended a conference on computer vision applications with a session organized by the food industry, which was primarily interested in automated quality control. Researchers presented vision systems that counted the number of pepperoni slices on frozen pepperoni pizzas, counted the raisins in a sample of raisin-bran cereal, and assessed the randomness of the distribution of holes inside Thomas' english muffins!
Consider the type of images that you created in Problem 1, which consist of rectangular or circular patches of uniform intensity. In this problem, I'd like you to think about possible strategies that could be used to count the number of rectangles and circles that appear in the image, and determine the size of these objects. You do not need to do any computer work for this problem, just describe the strategies in words. It's OK to discuss possible strategies with your classmates!
Part a (10 points): Isolated objects
First assume that the shapes are isolated, with no overlapping areas, as shown in the sample image below on the left. The goal is to compute information about the sizes of the rectangles and circles contained in the image. For the example below, this information would include three rectangles of size 80x20, 70x30, and 15x140 pixels, and four circles of radius 10, 20, 25, and 30 pixels. You do not need to compute the position and intensity of the objects. Outline at least two strategies for computing this information. One strategy should derive this information directly from the original image and the second should derive this information from an image of edge contours, as shown in the figure on the right. In the case of the original image, you can assume that the background is a constant value that is known, and that the shapes are perfect circles, or perfect rectangles that are oriented in the horizontal or vertical direction.
Part b (10 points): Overlapping objects
Suppose that the object shapes could overlap and that overlapping objects could have the same intensity. The images below show an example of such an image and its edges:
Would the strategies that you outlined in Part a work for images with overlapping objects? Explain why or why not. If not, try to suggest possible modifications to your strategies that could improve their performance in this more challenging context.
Submission details: Hand in a hardcopy of the files addCircle.m,
addColorCircle.m, blurImage.m, findEdges.m
, the script file that you used to create
the images for Problem 1c, and your answers to Problem 4. (To conserve paper, you can
copy-and-paste the individual code files into one extended M-File that you submit.)
At the
beginning or end of your hardcopy material, please add a note indicating (roughly) how much
time you spent on this assignment outside of lab time. Please separate the amount of time
spent on background reading and amount of time spent working on the problems. Please
also submit an electronic copy of your code files by logging into the CS file server,
cs.wellesley.edu
,
connecting to your assign1
folder and executing the following command:
submit cs332 assign1 *.*
A separate handout will be provided on "Submitting your assignment work electronically," with more details. Please ask if you need help with this last step.