程序代写代做代考 python Background subtraction¶

Background subtraction¶
In [1]:
%matplotlib notebook
# loading standard modules
import numpy as np
import math
import matplotlib.pyplot as plt
from skimage import img_as_ubyte
from skimage.color import rgb2grey

Load Image Sequence¶
In [2]:
imgs = []

for i in range(1, 10):
imgs.append(plt.imread(‘images/%d.png’ %i))

Show Image Sequence¶
In [3]:
for i in range(len(imgs)):
plt.figure()
plt.title(“image ” + str(i+1))
plt.imshow(imgs[i])

Compute The Median Image of the image sequence¶
In [4]:
# every pixel value of the median image is the median of all image pixel value at this position
images = np.zeros(shape=imgs[0].shape + (len(imgs),))

for i in range(len(imgs)):

images[:,:,:,i] = imgs[i]

imgMedian = np.median(images, axis=3)
plt.figure()
plt.imshow(imgMedian)
plt.title(“median image”)


Out[4]:

Compute the Difference Image¶
In [5]:
differenceImages = [0]*len(imgs)
for i in range(len(imgs)):
differenceImages[i] = imgs[i] – imgMedian

Segment object from background using Kmeans¶
In [6]:
from sklearn.cluster import KMeans
kmeansModels = []
kmeansPreds = []
for i in range(len(differenceImages)):
diffImag = differenceImages[i]
# kmeans on difference image
kmeans = KMeans(n_clusters=2, random_state=0).fit(diffImag.reshape((-1, 4)))
kmeansModels.append(kmeans)
pred = kmeans.labels_.reshape(diffImag.shape[:-1])

# show the segmentation mask
plt.figure()
plt.title(“kmeans segmentation mask for image ” + str(i+1))
if(pred[0, 0] == 1):
pred = 1 – pred
kmeansPreds.append(pred)
plt.imshow(pred, cmap=”gray”)

Graph Cuts class adapted from HW1¶
In [7]:
import maxflow
class MyGraphCuts:

bgr_value = 0
obj_value = 1
none_value = 2

def __init__(self, img, isFourNeighbor=True, sigma=0.1, inf=1000):

self.num_rows = img.shape[0]
self.num_cols = img.shape[1]

self.img = np.mean(img, -1)

if isFourNeighbor:
self.d = [(0, 1), (1, 0)]
else:
self.d = [(-1, 1), (0, 1), (1, 1), (1, 0)]

self.sigma = sigma

self.inf = inf

def compute_labels(self, seed_mask):
num_rows = self.num_rows
num_cols = self.num_cols

label_mask = np.full((num_rows, num_cols), self.none_value, dtype=’uint8′)

g = maxflow.GraphFloat()

arr = g.add_nodes(self.num_rows * self.num_cols)

arr = arr.reshape(self.num_rows, self.num_cols)

sigma2 = self.sigma ** 2

for i in range(self.num_rows):
for j in range(self.num_cols):

if seed_mask[i, j] == self.bgr_value:
g.add_tedge(arr[i, j], self.inf, 0)

if seed_mask[i, j] == self.obj_value:
g.add_tedge(arr[i, j], 0, self.inf)

for d in self.d:
ni = i + d[0]
nj = j + d[1]

if ni in range(self.num_rows) and nj in range(self.num_cols):
w = np.exp(- ((self.img[i, j] – self.img[ni, nj]) ** 2) / (2 * sigma2))

g.add_edge(arr[i, j], arr[ni, nj], w, w)

g.maxflow()
segments = g.get_grid_segments(arr)

label_mask[segments == True] = self.obj_value

label_mask[segments == False] = self.bgr_value

return label_mask
In [8]:
def computeCenter(b):
“””
compute the forground center of the mask b
“””
r = 0.0
c = 0.0

count = 0
for i in range(b.shape[0]):
for j in range(b.shape[1]):

if b[i, j] == 1:
count += 1
r += i
c += j

r /= count
c /= count

return (r,c)

Segment object from background using graph cuts¶
I get background and foreground seed from the segmentation computed by kmeans, and then using the seeds and difference image as input to segment using graph cuts.
In [9]:
def getSeed(b, center, rr, cr, rb, cb):
“””
Get background, foreground seed from mask b which is computed by kmeans.
“””
res= np.zeros(b.shape, dtype = ‘int’) + 2

for i in range(b.shape[0]):
for j in range(b.shape[1]):
if b[i, j] == 1:

if np.abs(i – center[0]) < rr and np.abs(j - center[1]) < cr: ## it is within sensible range, set as foreground seed res[i, j] = 1 else: if np.abs(i - center[0]) > rb or np.abs(j – center[1]) > cb:
## it is outside sensible range, set as background seed
res[i, j] = 0

return res

graphCutsPreds = []
# for i in range(len(differenceImages)):

for i in range(9):
diffImag = differenceImages[i]

graphcuts = MyGraphCuts(diffImag, isFourNeighbor=True, sigma=0.01)
## using graph cuts with seeds computed from segmentation by kmeans
pred = graphcuts.compute_labels(getSeed(kmeansPreds[i], computeCenter(kmeansPreds[i]), 250, 100, 200, 50))

if(pred[0, 0] == 1):
pred = 1 – pred
graphCutsPreds.append(pred)
plt.figure()
plt.imshow(pred, cmap=”gray”)
plt.title(“graph cuts segmentation mask for image ” + str(i+1))

/Users/vagrant/anaconda42/anaconda/lib/python2.7/site-packages/matplotlib/pyplot.py:524: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
max_open_warning, RuntimeWarning)

Summary¶
In this project, I first estimate the background by computing the median image of the image sequence, and then compute the difference image by subtracting each image with median image. Then I use kmeans to segment on the difference image. Finally, I use graph cuts with seeds computed from segmentation mask got from kmeans. From the shown figure above, we can see that the segmentation of kmeans is good, and with graph cuts, the segmented foreground is more connected.
In [ ]: