-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 25fdd03
Showing
26 changed files
with
304 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"cells": [], | ||
"metadata": {}, | ||
"nbformat": 4, | ||
"nbformat_minor": 4 | ||
} |
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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%; | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
|