Background
- find, any and all, GOBG Ch. 3
- plot and set, GOBG Ch. 3
- Octave reference on image processing
Thresholding: overexposure detection
- Time
- 25 minutes
- Activity
- Individual
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 L22 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.
Thresholding gradient
- Time
- 15 minutes
- Activity
- Individual
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.
Convolution and smoothing I
- Time
- 10 minutes
- Activity
- Demo
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
Convolution and Smoothing II
- Time
- 25 minutes
- Activity
- individual
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);
Smoothing and gradient via convolution
- Time
- 25 minutes
- Activity
- Individual
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.
soebel.jpg