6/24/2020 Lab04-Object Segmentation
LAB04 - Image Segmentation
Dr. Tran Anh Tuan,
Faculty of Mathematics and Computer Science,
University of Science, HCMC
In [1]: import numpy as np
import cv2
from matplotlib import pyplot as plt
from skimage.color import rgb2gray
from skimage.filters import threshold_otsu
from skimage.measure import label, regionprops
from skimage.segmentation import mark_boundaries
from scipy import ndimage as ndi
import pandas as pd
import json
import os
import timeit
import random
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 1/29
6/24/2020 Lab04-Object Segmentation
In [2]: def ShowImage(ImageList, nRows = 1, nCols = 2, WidthSpace = 0.00, HeightSpace = 0.00):
from matplotlib import pyplot as plt
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(nRows, nCols)
gs.update(wspace=WidthSpace, hspace=HeightSpace) # set the spacing between axes.
plt.figure(figsize=(20,20))
for i in range(len(ImageList)):
ax1 = plt.subplot(gs[i])
ax1.set_xticklabels([])
ax1.set_yticklabels([])
ax1.set_aspect('equal')
plt.subplot(nRows, nCols,i+1)
image = ImageList[i].copy()
if (len(image.shape) < 3):
plt.imshow(image, plt.cm.gray)
else:
plt.imshow(image)
plt.title("Image " + str(i))
plt.axis('off')
plt.show()
In [3]: def FillHoles(Mask):
Result = ndi.binary_fill_holes(Mask)
return Result
def morphology(Mask, Size):
from skimage.morphology import erosion, dilation, opening, closing, white_tophat
from skimage.morphology import disk
selem = disk(abs(Size))
if(Size > 0):
result = dilation(Mask, selem)
else:
result = erosion(Mask, selem)
return result
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 2/29
6/24/2020 Lab04-Object Segmentation
In [4]: import os
import pandas as pd
def get_subfiles(dir):
"Get a list of immediate subfiles"
return next(os.walk(dir))[2]
In [5]: def SegmentColorImageByMask(IM, Mask):
Mask = Mask.astype(np.uint8)
result = cv2.bitwise_and(IM, IM, mask = Mask)
return result
In [6]: def SegmentationByOtsu(image, mask):
image_process = image.copy()
image_mask = mask.copy()
image_process[image_mask == 0] = 0
ListPixel = image_process.ravel()
ListPixel = ListPixel[ListPixel > 0]
from skimage.filters import threshold_otsu
otsu_thresh = threshold_otsu(ListPixel)
return otsu_thresh
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 3/29
6/24/2020 Lab04-Object Segmentation
In [7]: def ResizeImage(IM, DesiredWidth, DesiredHeight):
from skimage.transform import rescale, resize
OrigWidth = float(IM.shape[1])
OrigHeight = float(IM.shape[0])
Width = DesiredWidth
Height = DesiredHeight
if((Width == 0) & (Height == 0)):
return IM
if(Width == 0):
Width = int((OrigWidth * Height)/OrigHeight)
if(Height == 0):
Height = int((OrigHeight * Width)/OrigWidth)
dim = (Width, Height)
# print(dim)
resizedIM = cv2.resize(IM, dim, interpolation = cv2.INTER_NEAREST)
# imshows([IM, resizedIM], ["Image", "resizedIM"],1,2)
return resizedIM
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 4/29
6/24/2020 Lab04-Object Segmentation
In [8]: def SegmentByKmeans(image_orig, nClusters = 3):
img = image_orig.copy()
Z = img.reshape((-1,3))
# convert to np.float32
Z = np.float32(Z)
# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 1.0)
K = nClusters
ret,labellist,center=cv2.kmeans(Z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
# Now convert back into uint8, and make original image
center = np.uint8(center)
res = center[labellist.flatten()]
res2 = res.reshape((img.shape))
label2 = labellist.reshape((img.shape[:2]))
image_index = label2
image_kmeans = res2
# Sort to make sure the index is stable
AreaList = []
for idx in range(image_index.max() + 1):
mask = image_index == idx
AreaList.append(mask.sum().sum())
sort_index = np.argsort(AreaList)[::-1]
index = 0
image_index1 = image_index * 0
for idx in sort_index:
image_index1[image_index == idx] = index
index = index + 1
image_index = image_index1.copy()
return image_index, image_kmeans
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 5/29
6/24/2020 Lab04-Object Segmentation
In [9]: def LabelObjectByMask(image_input, image_mask, type = "BBox", color = (0,255,0), thick = 2):
# image_input = image_orig.copy()
image_output = image_input.copy()
label_img = label(image_mask)
regions = regionprops(label_img)
for props in regions:
minr, minc, maxr, maxc = props.bbox
left_top = (minc, minr)
right_bottom = (maxc, maxr)
at_row, at_col = props.centroid
if(type == "Center"):
cv2.drawMarker(image_output, (int(at_col), int(at_row)),color, markerType=cv2.MARKER_STAR, marker
Size=15, thickness= 1, line_type=cv2.LINE_AA)
if(type == "BBox"):
cv2.rectangle(image_output,left_top, right_bottom, color ,thick)
if(type == "Boundary"):
color = [(number / 255) for number in color]
image_mask = morphology(image_mask, 1)
image_output = mark_boundaries(image_output, image_mask, color = color, mode='thick')
if(type == "Fill"):
image_output[image_mask > 0] = color
return image_output
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 6/29
6/24/2020 Lab04-Object Segmentation
In [10]: def SelectMaskByThreshArea(Mask, minArea = 300, maxArea = 100000):
import pandas as pd
from skimage.measure import label, regionprops
mask = Mask.copy()
mask_output = mask * 0
bboxList = []
label_img = label(mask)
regions = regionprops(label_img)
for props in regions:
area = props.area
label = props.label
if((area > minArea) and (area < maxArea)):
mask_output = mask_output + (label_img == label).astype(int)
return mask_output
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 7/29
6/24/2020 Lab04-Object Segmentation
In [11]: def EdgeDetection(image):
import numpy as np
import matplotlib.pyplot as plt
#define the vertical filter
vertical_filter = [[-1,-2,-1], [0,0,0], [1,2,1]]
#define the horizontal filter
horizontal_filter = [[-1,0,1], [-2,0,2], [-1,0,1]]
#read in the pinwheel image
img = image_orig
#get the dimensions of the image
n,m,d = img.shape
#initialize the edges image
edges_img = img.copy()
#loop over all pixels in the image
for row in range(3, n-2):
for col in range(3, m-2):
#create little local 3x3 box
local_pixels = img[row-1:row+2, col-1:col+2, 0]
#apply the vertical filter
vertical_transformed_pixels = vertical_filter*local_pixels
#remap the vertical score
vertical_score = vertical_transformed_pixels.sum()/4
#apply the horizontal filter
horizontal_transformed_pixels = horizontal_filter*local_pixels
#remap the horizontal score
horizontal_score = horizontal_transformed_pixels.sum()/4
#combine the horizontal and vertical scores into a total edge score
edge_score = (vertical_score**2 + horizontal_score**2)**.5
#insert this edge score into the edges image
edges_img[row, col] = [edge_score]*3
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 8/29
6/24/2020 Lab04-Object Segmentation
#remap the values in the 0-1 range in case they went out of bounds
edges_img = edges_img/edges_img.max()
edges_img = (edges_img[:,:,0]*255).astype(int)
return edges_img
In [12]: DataPath = "D:\\MSI DATA (Previous Computer)\\Teaching And Training\\Image Segmentation\\Image Segmentation D
ataSet1\\"
path = DataPath
all_names = get_subfiles(path)
print("Number of Images:", len(all_names))
IMG = []
for i in range(len(all_names)):
tmp = cv2.imread(path + all_names[i])
IMG.append(tmp)
SegDataIMG = IMG.copy()
SegDataName = all_names
Number of Images: 45
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 9/29
6/24/2020 Lab04-Object Segmentation
In [13]: FileName = 'Bill 04.jpg'
idx = SegDataName.index(FileName)
print("Selected Image : ", "\nIndex ", idx, "\nName ", SegDataName[idx])
image = SegDataIMG[idx]
image = ResizeImage(image, DesiredWidth = 300, DesiredHeight = 0)
image_orig = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
image_ycbcr = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB)
ShowImage([image_orig, image_gray, image_hsv, image_ycbcr], 1, 4)
Selected Image :
Index 3
Name Bill 04.jpg
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 10/29
6/24/2020 Lab04-Object Segmentation
In [14]: image_edge = EdgeDetection(image_orig)
image_mask_edge = image_edge > 20
image_mask_fill = FillHoles(image_mask_edge)
s = image_hsv[:,:,1]
image_mask_object = image_mask_fill.copy()
image_mask_object[s > 50] = 0
image_mask_object = FillHoles(image_mask_object)
image_result = LabelObjectByMask(image_orig, image_mask_object, type = "Boundary", color = (0,255,0), thick =
3)
ShowImage([image_orig, image_edge, image_mask_edge, image_mask_fill], 1, 4)
ShowImage([s, image_mask_object, image_result], 1, 4)
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 11/29
6/24/2020 Lab04-Object Segmentation
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 12/29
6/24/2020 Lab04-Object Segmentation
In [15]: FileName = 'Cross 01.jpg'
idx = SegDataName.index(FileName)
print("Selected Image : ", "\nIndex ", idx, "\nName ", SegDataName[idx])
image = SegDataIMG[idx]
image = ResizeImage(image, DesiredWidth = 300, DesiredHeight = 0)
image_orig = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
image_ycbcr = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB)
ShowImage([image_orig, image_gray, image_hsv, image_ycbcr], 1, 4)
Selected Image :
Index 15
Name Cross 01.jpg
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 13/29
6/24/2020 Lab04-Object Segmentation
In [16]: image_edge = EdgeDetection(image_orig)
image_mask_edge = image_edge > 50
image_mask_edge = SelectMaskByThreshArea(image_mask_edge, minArea = 200, maxArea = 300)
image_mask_edge = morphology(image_mask_edge, 1)
image_mask_edge = FillHoles(image_mask_edge)
image_result = LabelObjectByMask(image_orig, image_mask_edge, type = "Boundary", color = (0,255,0), thick = 3
)
ShowImage([image_orig, image_edge, image_mask_edge], 1, 3)
ShowImage([image_result], 1, 2)
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 14/29
6/24/2020 Lab04-Object Segmentation
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 15/29
6/24/2020 Lab04-Object Segmentation
In [23]: FileName = 'TrafficSign 02.jpg'
idx = SegDataName.index(FileName)
print("Selected Image : ", "\nIndex ", idx, "\nName ", SegDataName[idx])
image = SegDataIMG[idx]
image = ResizeImage(image, DesiredWidth = 300, DesiredHeight = 0)
image_orig = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
image_ycbcr = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB)
ShowImage([image_orig, image_gray, image_hsv, image_ycbcr], 1, 4)
Selected Image :
Index 41
Name TrafficSign 02.jpg
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 16/29
6/24/2020 Lab04-Object Segmentation
In [24]: import matplotlib.pyplot as plt
import numpy as np
from skimage.data import astronaut
from skimage.color import rgb2gray
from skimage.filters import sobel
from skimage.segmentation import felzenszwalb, slic, quickshift, watershed
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float
img = image_orig.copy()
segments_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
segments_slic = slic(img, n_segments=250, compactness=10, sigma=1)
segments_quick = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)
gradient = sobel(rgb2gray(img))
segments_watershed = watershed(gradient, markers=250, compactness=0.001)
print(f"Felzenszwalb number of segments: {len(np.unique(segments_fz))}")
print(f"SLIC number of segments: {len(np.unique(segments_slic))}")
print(f"Quickshift number of segments: {len(np.unique(segments_quick))}")
fig, ax = plt.subplots(2, 2, figsize=(10, 10), sharex=True, sharey=True)
ax[0, 0].imshow(mark_boundaries(img, segments_fz))
ax[0, 0].set_title("Felzenszwalbs's method")
ax[0, 1].imshow(mark_boundaries(img, segments_slic))
ax[0, 1].set_title('SLIC')
ax[1, 0].imshow(mark_boundaries(img, segments_quick))
ax[1, 0].set_title('Quickshift')
ax[1, 1].imshow(mark_boundaries(img, segments_watershed))
ax[1, 1].set_title('Compact watershed')
for a in ax.ravel():
a.set_axis_off()
plt.tight_layout()
plt.show()
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 17/29
6/24/2020 Lab04-Object Segmentation
Felzenszwalb number of segments: 173
SLIC number of segments: 177
Quickshift number of segments: 743
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 18/29
6/24/2020 Lab04-Object Segmentation
In [55]: h = image_hsv[:,:,0]
s = image_hsv[:,:,1]
v = image_hsv[:,:,2]
y = image_ycbcr[:,:,0]
cb = image_ycbcr[:,:,1]
cr = image_ycbcr[:,:,2]
ShowImage([h, s, v], 1, 3)
ShowImage([y, cb, cr], 1, 3)
ShowImage([h < 10, (cb > 200)], 1, 2)
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 19/29
6/24/2020 Lab04-Object Segmentation
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 20/29
6/24/2020 Lab04-Object Segmentation
In [60]: image_index = segments_fz.copy()
max_index = image_index.max()
image_mask = image_index * 0
h = image_hsv[:,:,0]
s = image_hsv[:,:,1]
v = image_hsv[:,:,2]
y = image_ycbcr[:,:,0]
cb = image_ycbcr[:,:,1]
cr = image_ycbcr[:,:,2]
for idx in range(max_index):
mask = (image_index == idx)
HValueList = h[mask == 1]
CbValueList = cb[mask == 1]
if((HValueList.mean() < 20) or (CbValueList.mean() > 200)):
image_mask = image_mask + mask
image_result1 = LabelObjectByMask(image_orig, image_mask, type = "Boundary", color = (0,255,0), thick = 3)
image_result2 = LabelObjectByMask(image_orig, image_mask, type = "BBox", color = (0,255,0), thick = 3)
ShowImage([image_index, image_mask], 1, 2)
ShowImage([image_result1, image_result2], 1, 2)
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 21/29
6/24/2020 Lab04-Object Segmentation
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 22/29
6/24/2020 Lab04-Object Segmentation
In [61]: FileName = 'KFC 01.jpg'
idx = SegDataName.index(FileName)
print("Selected Image : ", "\nIndex ", idx, "\nName ", SegDataName[idx])
image = SegDataIMG[idx]
image = ResizeImage(image, DesiredWidth = 300, DesiredHeight = 0)
image_orig = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
image_ycbcr = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB)
ShowImage([image_orig, image_gray, image_hsv, image_ycbcr], 1, 4)
Selected Image :
Index 20
Name KFC 01.jpg
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 23/29
6/24/2020 Lab04-Object Segmentation
In [62]: import matplotlib.pyplot as plt
import numpy as np
from skimage.data import astronaut
from skimage.color import rgb2gray
from skimage.filters import sobel
from skimage.segmentation import felzenszwalb, slic, quickshift, watershed
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float
img = image_orig.copy()
segments_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
segments_slic = slic(img, n_segments=250, compactness=10, sigma=1)
segments_quick = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)
gradient = sobel(rgb2gray(img))
segments_watershed = watershed(gradient, markers=250, compactness=0.001)
print(f"Felzenszwalb number of segments: {len(np.unique(segments_fz))}")
print(f"SLIC number of segments: {len(np.unique(segments_slic))}")
print(f"Quickshift number of segments: {len(np.unique(segments_quick))}")
fig, ax = plt.subplots(2, 2, figsize=(10, 10), sharex=True, sharey=True)
ax[0, 0].imshow(mark_boundaries(img, segments_fz))
ax[0, 0].set_title("Felzenszwalbs's method")
ax[0, 1].imshow(mark_boundaries(img, segments_slic))
ax[0, 1].set_title('SLIC')
ax[1, 0].imshow(mark_boundaries(img, segments_quick))
ax[1, 0].set_title('Quickshift')
ax[1, 1].imshow(mark_boundaries(img, segments_watershed))
ax[1, 1].set_title('Compact watershed')
for a in ax.ravel():
a.set_axis_off()
plt.tight_layout()
plt.show()
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 24/29
6/24/2020 Lab04-Object Segmentation
Felzenszwalb number of segments: 208
SLIC number of segments: 206
Quickshift number of segments: 1098
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 25/29
6/24/2020 Lab04-Object Segmentation
In [73]: h = image_hsv[:,:,0]
s = image_hsv[:,:,1]
v = image_hsv[:,:,2]
y = image_ycbcr[:,:,0]
cb = image_ycbcr[:,:,1]
cr = image_ycbcr[:,:,2]
ShowImage([h, s, v], 1, 3)
ShowImage([y, cb, cr], 1, 3)
ShowImage([s > 150, (cr < 100) & (cr > 50)], 1, 2)
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 26/29
6/24/2020 Lab04-Object Segmentation
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 27/29
6/24/2020 Lab04-Object Segmentation
In [77]: image_index = segments_watershed.copy()
max_index = image_index.max()
image_mask = image_index * 0
h = image_hsv[:,:,0]
s = image_hsv[:,:,1]
v = image_hsv[:,:,2]
y = image_ycbcr[:,:,0]
cb = image_ycbcr[:,:,1]
cr = image_ycbcr[:,:,2]
for idx in range(max_index):
mask = (image_index == idx)
SValueList = s[mask == 1]
CrValueList = cr[mask == 1]
Condition1 = SValueList.mean() > 150
Condition2 = (CrValueList.mean() < 100) & (CrValueList.mean() > 50)
if(Condition1 & Condition2):
image_mask = image_mask + mask
image_mask = SelectMaskByThreshArea(image_mask, minArea = 500, maxArea = 100000)
image_result1 = LabelObjectByMask(image_orig, image_mask, type = "Boundary", color = (0,255,0), thick = 3)
image_result2 = LabelObjectByMask(image_orig, image_mask, type = "BBox", color = (0,255,0), thick = 3)
ShowImage([image_index, image_mask], 1, 2)
ShowImage([image_result1, image_result2], 1, 2)
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 28/29
6/24/2020 Lab04-Object Segmentation
C:\Users\tuant\Anaconda3\lib\site-packages\ipykernel_launcher.py:18: RuntimeWarning: Mean of empty slice.
C:\Users\tuant\Anaconda3\lib\site-packages\ipykernel_launcher.py:19: RuntimeWarning: Mean of empty slice.
file:///D:/MSI DATA (Previous Computer)/Teaching And Training/Image Segmentation/Lab04-Object Segmentation.html 29/29