Академический Документы
Профессиональный Документы
Культура Документы
Recitation 12
Image Processing
Plan: Image Processing with numpy
Binary segmentation
Image gradient
Image brightening
Morphological operators
Erosion
Dilation
Smoothing
Denoising
Ternary segmentation
2
A 2D table of values
(pixels), each in
Grayscale Image 0..255:
• 0 = Black
• 255 = White
105 114 116 116 160 121 97 90 124 119 188 144 112 116 78 32 19 61 40
3
Image processing – basic functions
Reading an image from disk:
from scipy import misc
im = misc.imread('C:/Koala.jpg')
Creating an “empty” image matrix:
im = numpy.zeros( (height,width), dtype=numpy.uint8 )
5
Image processing – more functions
We will need the following numpy function later:
numpy.concatenate( (A,B), axis=0)
array([[1, 2, 3],
>>> A = numpy.array([[1,2,3],[4,5,6]]) [4, 5, 6]])
6
Binary Segmentation
Goal: grayscale image black and white image
pixel > threshold change to white (255)
pixel <= threshold change to black (0)
7
Binary Segmentation: Code
>>> import matplotlib.pyplot as plt
>>> threshold = 128
>>> from scipy import misc
>>> binIm = (im > threshold) * 255
>>> im = misc.imread('C:/Koala.jpg')
>>> plt.figure()
>>> type(im)
>>> plt.imshow(im, cmap=plt.cm.gray)
<type 'numpy.ndarray'>
>>> plt.figure()
>>> im.shape, im.dtype
>>> plt.imshow(binIm, cmap=plt.cm.gray)
((598, 848), dtype('uint8'))
>>> plt.show()
>>> np.min(im), np.max(im)
(0, 255)
8
Image gradient
Given an image we may want to locate points of major change in
intensity.
In the gradient image, every pixel is the difference between the
corresponding pixel in the original image and a neighboring pixel.
We can compute the gradient wrt each of the image dimensions.
9
Image vertical gradient: Code
The idea: shift up and subtract images
10
Brightening an image
We can hardly see the gradient image.
o Solution: let’s brighten it.
11
Image processing
Many more operations can be performed on images, in particular:
o Geometric transformations: shifting, rotation, flipping
o Filtering: replace a pixel by a function of the neighboring pixels
The neighborhood can be defined by a structuring element, e.g. square
12
Morph by Neighbors
All the operators we’ll see have the same basic idea:
Change a pixel according to its
neighborhood
The ‘neighborhood’ of a pixel in
the input image
Morphological Operators
Morphology is a technique for the analysis and processing
of geometrical structures
Erosion:
Take binary image ; produce more black, less white.
Edges of white areas (“foreground”) erode away.
So black areas (“background”) grow.
14
Morphological Operators
Dilation – inverse of erosion.
Boundaries of black areas erode away.
So white areas grow.
15
Morph – Common Code
The specific
Framework: morph. operator
Default Neighborhood
17
Erosion and dilation using morph
def erosion(im, nx=5, ny=5):
return morphological(im, np.min, nx, ny)
18
Morphological Operators - Run
erosion
dilation
19
Detect Edges with Dilation
Idea:
Thicken white edges a bit, using dilation
Compute difference from original image
im1 = misc.imread('square1.bmp')
im2 = dilation(im1, 1, 1)
imDiff = im2 – im1
20
Denoising
We want to “clean” these pictures from noise
Suggestions?
21
Denoising - Mean
Take 1: Smoothing
Use the morphological framework with mean (average):
def denoise_mean(im, nx=5, ny=5):
return morphological(im, np.mean, nx, ny)
22
Denoising - Median
Take 2: Median
def denoise_median(im, nx=5, ny=5):
return morphological(im, np.median, nx, ny)
23
Denoising - Median
Can we do better?
We did not exploit what we know about the ‘noise’
The ‘noise’ can only be
Almost white
Almost black
25
Denoising – Bounded Median
def my_median(nbrs, min_val=0, max_val=255): def fix_white(nbrs, W=200):
goodNbrs = \ center = (nbrs.shape[0]/2, nbrs.shape[1]/2)
nbrs[(nbrs >= min_val) & (nbrs <= max_val)] if nbrs[center] > W: # too bright
if goodNbrs.shape[0] > 0: return my_median(nbrs, max_val=W)
return np.median(goodNbrs) else:
else: return nbrs[center]
center = (nbrs.shape[0]/2, nbrs.shape[1]/2)
return nbrs[center]
def fix_black(nbrs, B=50):
center = (nbrs.shape[0]/2, nbrs.shape[1]/2)
if nbrs[center] < B: # too dark
return my_median(nbrs, min_val=B)
else:
return nbrs[center]
26
Denoising – Bounded Median
def denoise_bounded_median(im, nx=3, ny=3):
num_repeat = 3
for i in range(num_repeat):
im = morphological(im, fix_white, nx, ny)
im = morphological(im, fix_black, nx, ny)
return im
27
Denoising – Bounded Median
Iteration
number
1 2
3 4
28
Ternary segmentation
29
Example
Before After
30
Ternary segmentation
Example: If the values of the image pixels are 1 to 90 then:
first threshold = 30; second threshold = 60
Possible algorithm:
Sort all n*m pixel values in the image into sorted_pxls
(one-dimensional list)
Set first threshold = sorted_pxls[n*m/3]
Set second threshold = sorted_pxls[2*n*m/3]
Complexity: O(nm*log(nm))
31
Ternary segmentation
We will break the problem into smaller problems:
1. Create a histogram.
2. Create a cumulative histogram.
3. Find 2 thresholds from cumulative histogram.
4. Transform the image using the thresholds.
Step by step…
Modularize the solution
32
Image histogram
pic.png contains a 20x20 pixels image
Each pixel is a gray level in 0..255
34
Cumulative histogram
Q2: Implement the function cum_sum(lst):
Input: list of numbers
Output: list of the cumulative sums of lst
12 43 17 22
12 55 72 94
35
Cumulative sum – Code
def cum_sum(numbers):
res = []
for i in range(len(numbers)):
prevSum = res[i-1] if i > 0 else 0
res.append(prevSum + numbers[i])
return res
36
Ternary segmentation
Q3: Given an image, find two thresholds th1, th2 such that:
37
Finding the thresholds
def find_thrds(im):
hist = build_hist(im)
c_lst = cum_sum(hist)
i=0
while float(c_lst[i]) / im.size < 1./3:
i += 1
th1 = i
while float(c_lst[i]) / im.size < 2./3:
i += 1
th2 = i
return (th1, th2)
38
Ternary segmentation
Q4: Implement the ternary segmentation function itself:
o Input: a grayscale image
o Output: a new image where every pixel has one of 3 gray levels:
0, 128 or 255
def ternary_sementation(im):
th1, th2 = find_thrds(im)
newIm = np.zeros(im.shape)
newIm = newIm + ((im > th1) & (im <= th2)) * 128
newIm = newIm + (im > th2) * 255
return newIm
39