Skip to content

Instantly share code, notes, and snippets.

@CedricVanhaverbeke
Created May 9, 2019 12:06
Show Gist options
  • Save CedricVanhaverbeke/b8a45814783f83eab90512a7d8e3948d to your computer and use it in GitHub Desktop.
Save CedricVanhaverbeke/b8a45814783f83eab90512a7d8e3948d to your computer and use it in GitHub Desktop.
# Based on https://www.mathworks.com/help/images/ref/imsegkmeans.html
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn import preprocessing
# Building some gabor kernels to filter image
orientations = np.arange(0, np.pi, np.pi / 4)
wavelengths = []
lmbda = 1
while lmbda <= 32:
wavelengths.append(lmbda)
lmbda *= 2
def build_gabor_kernels():
filters = []
ksize = 45
for rotation in orientations:
for wavelength in wavelengths:
kernel = cv.getGaborKernel(
(ksize, ksize), 1, rotation, wavelength, 0.5, 0, ktype=cv.CV_32F)
filters.append(kernel)
return filters
image = cv.imread('./mona.jpg')
rows, cols, channels = image.shape
# Resizing the image.
# Full image is taking to much time to process
image = cv.resize(image, (int(cols * 0.5), int(rows * 0.5)))
rows, cols, channels = image.shape
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
gaborKernels = build_gabor_kernels()
gaborFilters = []
for (i, kernel) in enumerate(gaborKernels):
filteredImage = cv.filter2D(gray, cv.CV_8UC1, kernel)
# Blurring the image
sigma = int(3*0.5*wavelengths[i % len(wavelengths)])
# Sigma needs to be odd
if sigma % 2 == 0:
sigma = sigma + 1
blurredImage = cv.GaussianBlur(filteredImage, (int(sigma), int(sigma)), 0)
gaborFilters.append(blurredImage)
# numberOfFeatures = 1 (gray color) + number of gabor filters + 2 (x and y)
numberOfFeatures = 1 + len(gaborKernels) + 2
# Empty array that will contain all feature vectors
featureVectors = []
for i in range(0, rows, 1):
for j in range(0, cols, 1):
vector = [gray[i][j]]
for k in range(0, len(gaborKernels)):
vector.append(gaborFilters[k][i][j])
vector.extend([i+1, j+1])
featureVectors.append(vector)
# Some example results:
# featureVectors[0] = [164, 3, 10, 255, 249, 253, 249, 2, 43, 255, 249, 253, 249, 3, 10, 255, 249, 253, 249, 2, 43, 255, 249, 253, 249, 1, 1]
# featureVectors[1] = [163, 3, 17, 255, 249, 253, 249, 2, 43, 255, 249, 253, 249, 3, 17, 255, 249, 253, 249, 2, 43, 255, 249, 253, 249, 1, 2]
# Normalizing the feature vectors
scaler = preprocessing.StandardScaler()
scaler.fit(featureVectors)
featureVectors = scaler.transform(featureVectors)
kmeans = KMeans(n_clusters=2, random_state=170)
kmeans.fit(featureVectors)
centers = kmeans.cluster_centers_
labels = kmeans.labels_
result = centers[labels]
# Only keep first 3 columns to make it easy to plot as an RGB image
result = np.delete(result, range(3, numberOfFeatures), 1)
plt.figure(figsize=(15, 8))
plt.imsave('test.jpg', result.reshape(rows, cols, 3) * 100)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment