Skip to content

Instantly share code, notes, and snippets.

@quocdat32461997
Last active February 1, 2020 21:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quocdat32461997/f5f1be1c6b8e55b7b79c8e06cb497c01 to your computer and use it in GitHub Desktop.
Save quocdat32461997/f5f1be1c6b8e55b7b79c8e06cb497c01 to your computer and use it in GitHub Desktop.
#segmentation.py
"""
In Computer Vision, segmentation objects and background could be done by different methods:
Intensity-based Segmentation: Thresholding - Based on the intensity of colors in histogram
Edge-based Segmentation - Based on edges
Region-based Segmentation
"""
#import dependencies
from . import histogram
import numpy as np
__all__ = ['optimal_thresholding']
"""
optimal_thresholding - function to segment objects and background using Quantization
Parameters:
image I/P image
"""
def optimal_thresholding(image):
#calculate histogram
hist = histogram.histogram(image)
#thresholding by quantization
optimal_thd = _quantization(hist)
#segment image based on optimal_threshold
front = np.array([[0] * image.shape[1]] * image.shape[0])
back = np.array([[255] * image.shape[1]] * image.shape[0])
for row in range(image.shape[0]):
for col in range(image.shape[1]):
if image[row, col] > optimal_thd:
front[row, col] = image[row, col]
else:
back[row, col] = image[row, col]
#reconstruct
return front, back
#################### helper functions ###########################
"""
_quantization - private function to perform quanization (color compression) to find the optimal threshold within the image histogram
Parameters:
hist I/P image histogram
optimal_thd O/P optimal_threshold
"""
def _quantization(hist):
#by default, histogram has 0-255 brightness levels
min_error = -1
optimal_threshold = -1
#Calculate q1 and q2 by calculating means of two classes of threshold
q2_num = sum([k * hist[k] for k in range(len(hist))]) #total of #_pixels * color
q2_denom = sum(hist) #total of #_pixels
q1_num = 0
q1_denom = 0
#Quantization, assume all brightness levels as possible thresholds
for t in range(len(hist)) :
q1 = 0
q2 = 0
#calculate q1
if q1_denom == 0:
q1 = 0
else:
q1 = np.floor(q1_num / q1_denom)
#calculate q2
if q2_denom == 0:
q2 = 0
else:
q2 = np.floor(q2_num / q2_denom)
#update numerator and denominator
q1_num += t * hist[t]
q2_num -= t * hist[t]
q1_denom += hist[t]
q2_denom -= hist[t]
#calculate threshold by calculating total varaince two classes
threshold = int(np.mean([q1, q2]))
temp_error = _calculate_error(q1, q2, threshold, hist)
if optimal_threshold < 0: #if optimal_threshold not initialized
min_error = temp_error
optimal_threshold = threshold
elif temp_error < min_error: #check the next min error to find the optimal threshold
min_error = temp_error
optimal_threshold = threshold
return optimal_threshold
"""
_calculate_error - function to calculate sum of variance of two classes for error at a threshold
Parameters:
q1 I/P class 1
q2 I/P class 2
threshold I/P threshold
hist I/P histogram
error O/P total error: q1_variance + q2_variance
"""
def _calculate_error(q1, q2, threshold, hist):
#calclulate sum of variance of class 1
q1_variance = 0
for color in range(threshold):
q1_variance += hist[color] * ((color - q1) ** 2)
#calculate sum of variance of class 2
q2_variance = 0
for color in range(threshold, 256):
q2_variance += hist[color] * ((color - q2) ** 2)
return q1_variance + q2_variance
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment