Skip to content

Commit

Permalink
Finished k-Means Algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
allengu01 committed Sep 26, 2020
0 parents commit 25fdd03
Show file tree
Hide file tree
Showing 26 changed files with 304 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .ipynb_checkpoints/kmeans_colors-checkpoint.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 4
}
Binary file added __pycache__/kmeans.cpython-38.pyc
Binary file not shown.
Empty file added about.html
Empty file.
141 changes: 141 additions & 0 deletions css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
* {
box-sizing: border-box;
}

body {
margin: 0;
font-size: 24px;
font-family: 'Montserrat', sans-serif;
color: #111d5e;
}

/** HEADER NAV BAR **/
header {
width: 100%;
font-family: 'Montserrat', sans-serif;
height: auto;
position: relative;
color: #111d5e;
font-size: 24px;
box-shadow: 2px 2px 8px #111d5e;
}

.nav-bar {
display: flex;
width: 100%;
margin-bottom: 15px;
flex-direction: column;
}

.nav-brand {
font-size: 1.33em;
width: 100%;
margin-top: auto;
}

.nav-name {
text-decoration: none !important;
color: #111d5e;
font-style: italic;
font-weight: 500;
padding-left: 2.5em;
}

.nav-categories {
display: flex;
line-height: 1.33em;
font-weight: 500;
height: 100%;
flex: 1;
margin-bottom: auto;
padding: 0;
}

.nav-item {
list-style-type: none;
flex-wrap: wrap;
flex: 1;
text-align: center;
height: 100%;
}

.nav-item a {
text-decoration: none !important;
color: #111d5e;
}

.nav-item a.active, .nav-item a:hover {
color: #6a0d83 !important;
cursor: pointer;
}
header hr {
margin-top: 0;
border-bottom: 2px solid #111d5e;
margin-bottom: 8px;
}
.col-sm-3, .col-sm-6, .col-sm-9, .col-sm-12, .col-md-3, .col-md-6, .col-md-9, .col-md-12 {
position: relative;
float: left;
min-height: 1px;
padding-left: 25px;
padding-right: 25px;
}

/** MEDIA QUERIES **/
@media (max-width: 991px) {
.nav-brand {
padding-bottom: 15px;
border-bottom: 1px dotted #111d5e;
text-align: center;
}
.nav-logo {
position: relative;
top: 12px;
left: -5px;
}
.nav-name {
padding-left: 0;
}
.nav-categories {
flex-direction: column;
margin: 0;
}
.nav-item {
padding-top: 15px;
}
.col-sm-3 {
width: 25%;
}
.col-sm-6 {
width: 50%;
}
.col-sm-9 {
width: 75%;
}
.col-sm-12 {
width: 100%;
}
}
@media (min-width: 992px) {
.nav-brand {
width: 600px !important;
}
.nav-bar {
flex-direction: row;
}
.nav-item:nth-child(1) {
border-left: 1px solid #111d5e;
}
.col-md-3 {
width: 25%;
}
.col-md-6 {
width: 50%;
}
.col-md-9 {
width: 75%;
}
.col-md-12 {
width: 100%;
}
}
Binary file added figs/final.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration14.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figs/iteration9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/minimalist_landscape.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/minimalist_landscape2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/minimalist_landscape3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/tsunami.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content=""> <!-- fill out later -->

<title>k-means Visualizer</title>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<header>
<nav class="nav-bar">
<div class="nav-brand">
<a class="nav-name" href="#">k-Means Visualizer</a>
</div>
<ul class="nav-categories">
<li class="nav-item visible-md">
<a class="nav-link">Tutorial</a>
</li>
<li class="nav-item visible-md">
<a class="nav-link" href="about.html">About</a>
</li>
</ul>
</nav>
<hr>
</header>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
</body>
</html>
95 changes: 95 additions & 0 deletions kmeans.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import cv2

# READ IMAGE
img = cv2.imread('images/minimalist_landscape3.jpg')
resized_img = cv2.resize(img, (30, 30))

def split_rgb(image):
b, g, r = cv2.split(image)
return r, g, b

def flatten(arr):
n = arr.size
return arr.reshape([n,])

img_r, img_g, img_b = split_rgb(resized_img)
flatten_img_r, flatten_img_g, flatten_img_b = list(map(flatten, [img_r, img_g, img_b]))
pixels = np.stack([flatten_img_r, flatten_img_g, flatten_img_b], axis=1)

def distance(p1, p2):
"""
Returns the Euclidean distance
"""
return np.sqrt(np.sum((p2 - p1) * (p2 - p1), axis=1))

def range_of(data):
return {"min" : np.array([np.min(data, axis=0)]), "max" : np.array([np.max(data, axis=0)])}

def random_in_range(data):
data_range = range_of(data)
data_min, data_max = data_range["min"], data_range["max"]
data_diff = data_max - data_min
return data_min + np.array([np.random.rand(data.shape[1])]) * data_diff

def initialize_random_centroids(data, k):
centroids = np.empty((0, data.shape[1]))
for _ in range(k):
centroids = np.concatenate([centroids, random_in_range(data)])
return centroids

def cluster_data(data, centroids):
clusters = {}
for i in range(1, len(centroids) + 1):
clusters[i] = np.empty((0, data.shape[1]))
for point in data:
nearest_centroid = int(np.argmin(distance(np.array([point]), centroids))) + 1
clusters[nearest_centroid] = np.concatenate([clusters[nearest_centroid], np.array([point])])
return clusters

def update_centroids(data, centroids, clusters):
change = False
for centroid_num in clusters:
if clusters[centroid_num].shape[0] == 0:
pass
else:
points_in_cluster = clusters[centroid_num]
new_centroid = np.sum(points_in_cluster, axis=0) / points_in_cluster.shape[0]
if not np.array_equal(centroids[centroid_num - 1], new_centroid):
change = True
centroids[centroid_num - 1] = new_centroid
return centroids, change

def k_means(data, k, directory_name):
centroids = initialize_random_centroids(data, k)
clusters = cluster_data(data, centroids)

centroids_changed = True
i = 1
while centroids_changed:
print("Iteration:", i)
plot_rgb(data, centroids, directory_name + 'iteration' + str(i))
clusters = cluster_data(data, centroids)
centroids, centroids_changed = update_centroids(data, centroids, clusters)
i += 1
return centroids

def plot_rgb(data, centroids, file_path):
fig = plt.figure(figsize = (8, 6))
ax = plt.axes(projection='3d')

for r, g, b in data:
ax.scatter3D(r, g, b, facecolor='white', edgecolor=(r / 255, g / 255, b / 255))

for r, g, b in centroids:
print(r, g, b)
ax.scatter3D(r, g, b, s=200, color=(r / 255, g / 255, b / 255))

plt.savefig(file_path, dpi=300)

centroids_result = k_means(pixels, 4, 'figs/')
plot_rgb(pixels, centroids_result, 'figs/final')
29 changes: 29 additions & 0 deletions plots.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import cv2

img = cv2.imread('images/minimalist_landscape.jpg')
resized_img = cv2.resize(img, (20, 20))

fig = plt.figure(figsize = (8, 6))
ax = plt.axes(projection='3d')

def split_rgb(image):
b, g, r = cv2.split(image)
return r, g, b

def flatten(arr):
n = arr.size
return arr.reshape([n,])

img_r, img_g, img_b = split_rgb(resized_img)
flatten_img_r, flatten_img_g, flatten_img_b = list(map(flatten, [img_r, img_g, img_b]))
pixels = np.stack([flatten_img_r, flatten_img_g, flatten_img_b], axis=1)
print(pixels.shape)

for r, g, b in pixels:
ax.scatter3D(r, g, b, color = (r / 255, g / 255, b / 255))

plt.show()

0 comments on commit 25fdd03

Please sign in to comment.