Before the lab
Read
One common feature of photo editing software (or camera firmware) is to highlight overexposed or underexposed pixels. In this exercise we will use our solutions for scale layers and monochrome from L21 in order to mark the pixels above a certain level.
Download the following image (make sure you download the actual full
resolution image) and save it as ~/cs2613/labs/L22/leaf.jpg
.
Use the builtin function find to complete the threshold
function
to find all pixel positions with value higher than a given threshold.
Note that this use of find depends on broadcasting. In all
of the calls to plot in this lab, you may want to adjust
markersize to better see the selected pixels (it depends a bit on
screen resolution and image size).
function [rows, cols] = threshold(in, lower=100)
[rows,cols] =
endfunction
%!test
%! A=[1,2,3; 4,5,6];
%! [rows,cols]=threshold(A,4);
%! assert(rows==[2;2]);
%! assert(cols==[2;3]);
%!demo
%! leaf=imread("leaf.jpg");
%! monoleaf=monochrome(leaf);
%! [rows, cols] = threshold(monoleaf,200);
%! clf
%! hold on;
%! imshow(leaf);
%! plot(cols,rows,".","markersize",1);
The output of demo threshold
should be something like the following.
In order to extract a description of a scene from an image, an early step is to detect the boundaries between various objects in the scene via edge detection. There are many different methods, but one approach is to find pixels where the gradient is particularly high. Use the monochrome and normgrad functions from L22 to complete the following script.
leaf=imread("leaf.jpg");
monoleaf=
ng =
[rows, cols] = threshold(ng, 8 );
clf
hold on;
imshow(leaf);
plot(cols,rows,".","markersize",1);
The output of this script should be something like the following; it's interesting as far as detecting texture, but not very helpful for dividing the scene into objects. There's also a fair amount of isolated "edge" pixels in the background. Both of these problems can be addressed via smoothing in the next section.
In order to smooth out some of the noise (or just isolated bright
pixels), we can replace the value of each pixel with a weighted
average of it's neighbourhood. The simplest approach is the so called
box blur, where each pixel in the neighbourhood is added up, and the
result divided by the number of pixels. The Octave function
conv2(A,B)
provides an easy way to apply a convolution or
kernel to a
matrix. This just means that B
specifies the weights in averaging
the neighbourhood.
Fill in the appropriate matrix (formula) B
to make the following
smoothing demo work.
A = [0,0,0,0,0,1;
0,1,1,1,0,0;
0,1,1,1,0,1;
0,1,1,1,1,0;
0,1,1,1,1,0;
0,0,0,0,0,0];
for j=2:12
B=
AB = conv2(A,B);
imshow(AB,[]);
pause(1);
endfor
Generalized the demo above to make a smoothing function. For variety we're going to use the Paris image image from last lab for the demo.
function S=smooth(in, side=3)
S =
endfunction
%!test
%! A = [0,0,0,1;
%! 1,1,0,0;
%! 1,1,0,1;
%! 1,1,1,0];
%! B= [0.50, 0.25, 0.25, 0.25;
%! 1.00, 0.50, 0.25, 0.25;
%! 1.00, 0.75, 0.50, 0.25;
%! 0.50, 0.50, 0.25, 0.00];
%! assert(smooth(A,2),B,eps);
%!demo
%! paris=imread("paris.jpg");
%! monoparis=monochrome(paris,[1/3,1/3,1/3]);
%! imshow(monoparis,[])
%! pause(1);
%! imshow(smooth(monoparis),[])
%! pause(1);
%! imshow(smooth(monoparis,10),[])
%! pause(1);
%! imshow(smooth(monoparis,20),[])
Use your new function to complete the following script. Adjust the smoothing and threshold parameters to approximate the image below.
leaf=imread("leaf.jpg");
monoleaf=monochrome(leaf);
smoothed=
ng = normgrad(smoothed)
[rows, cols] =
clf
hold on;
imshow(leaf,[]);
plot(cols,rows,".","markersize",1);
As you probably saw, the second argument to conv2 can be much more general than just uniform weights. In particular some of the weights can be negative, e.g. to approximate a gradient calculation.
One example is the Soebel Operator which combines gradiant and smoothing operations.
Refering to the Wikipedia page, complete the function to calculuate
the Soebel operator. You will also need to define function norm2
,
which can be copied from the definition of normgrad (without the
gradient part).
function [Gx,Gy]=soebel(in)
Gx =
Gy =
endfunction
%!demo
%! leaf=imread("leaf.jpg");
%! monoleaf=monochrome(leaf);
%! [Dx, Dy] = soebel(monoleaf);
%! ns = norm2(Dx,Dy);
%! [rows,cols] = threshold(ns,150);
%! clf
%! hold on
%! imshow(leaf);
%! plot(cols,rows,".","markersize",10);
In the resulting figure the size of the detected pixels is exaggerated to make them easier to spot.