IR
|
@ -21,7 +21,7 @@ def kmeans(points = [0,0], K = 1):
|
||||||
Pc_index.append(np.random.randint(0,N))
|
Pc_index.append(np.random.randint(0,N))
|
||||||
Pc = points[Pc_index,:]
|
Pc = points[Pc_index,:]
|
||||||
|
|
||||||
while (np.mean(distance(Pc,Pc_save)) > eps and iter < 3):
|
while (np.mean(distance(Pc,Pc_save)) > eps and iter < 10):
|
||||||
iter += 1
|
iter += 1
|
||||||
Pc_save = Pc
|
Pc_save = Pc
|
||||||
# print(Pc)
|
# print(Pc)
|
||||||
|
@ -74,9 +74,10 @@ def kmeans_image(path_image, K):
|
||||||
# imgplot = plt.imshow(img_seg)
|
# imgplot = plt.imshow(img_seg)
|
||||||
return Pc, index, img_seg
|
return Pc, index, img_seg
|
||||||
|
|
||||||
path_image = "fruits.jpg"
|
path_image = "images/fruits.jpg"
|
||||||
|
|
||||||
start_time = time.time()
|
for K in range(1,21):
|
||||||
Pc, index, img_seg = kmeans_image(path_image=path_image, K=2)
|
start_time = time.time()
|
||||||
end_time = time.time()
|
Pc, index, img_seg = kmeans_image(path_image=path_image, K=K)
|
||||||
print(f"It took {end_time-start_time:.2f} seconds to compute")
|
end_time = time.time()
|
||||||
|
print(f"It took {end_time-start_time:.2f} seconds to compute for K =", K)
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
import numpy as np
|
|
||||||
import pycuda.autoinit
|
|
||||||
import pycuda.driver as cuda
|
|
||||||
from pycuda.compiler import SourceModule
|
|
||||||
import time
|
|
||||||
|
|
||||||
# Load the image and convert it to a NumPy array
|
|
||||||
from PIL import Image
|
|
||||||
im = Image.open('fruits.jpg')
|
|
||||||
im_data = np.array(im)
|
|
||||||
|
|
||||||
# Convert the image data to float32 and normalize it
|
|
||||||
im_data = im_data.astype(np.float32) / 255
|
|
||||||
|
|
||||||
# Create a CUDA kernel to perform K-means clustering
|
|
||||||
kernel = """
|
|
||||||
__global__ void kmeans(float *data, int *labels, float *centroids, int n, int k, int dim)
|
|
||||||
{
|
|
||||||
int tid = blockIdx.x * blockDim.x + threadIdx.x;
|
|
||||||
if (tid >= n)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float min_dist = 10000;
|
|
||||||
int min_centroid = -1;
|
|
||||||
for (int i = 0; i < k; i++)
|
|
||||||
{
|
|
||||||
float dist = 0.0;
|
|
||||||
for (int j = 0; j < dim; j++)
|
|
||||||
{
|
|
||||||
float diff = data[tid * dim + j] - centroids[i * dim + j];
|
|
||||||
dist += diff * diff;
|
|
||||||
}
|
|
||||||
if (dist < min_dist)
|
|
||||||
{
|
|
||||||
min_dist = dist;
|
|
||||||
min_centroid = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
labels[tid] = min_centroid;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
mod = SourceModule(kernel)
|
|
||||||
kmeans = mod.get_function("kmeans")
|
|
||||||
|
|
||||||
# Set the number of clusters and the number of iterations
|
|
||||||
k = 2
|
|
||||||
n_iter = 5
|
|
||||||
|
|
||||||
# Initialize the centroids and labels
|
|
||||||
centroids = np.random.rand(k, im_data.shape[-1]).astype(np.float32)
|
|
||||||
labels = np.zeros(im_data.shape[:2], dtype=np.int32)
|
|
||||||
|
|
||||||
def replace_with_nearest_centroid(centroids, colors):
|
|
||||||
# Compute the distance between each color and each centroid
|
|
||||||
distances = np.sqrt(np.sum((colors[:, :] - centroids) ** 2, axis=2))
|
|
||||||
|
|
||||||
# Find the index of the centroid that is nearest to each color
|
|
||||||
nearest_centroids = np.argmin(distances, axis=1)
|
|
||||||
|
|
||||||
# Replace each color with the nearest centroid
|
|
||||||
colors[:] = centroids[nearest_centroids]
|
|
||||||
|
|
||||||
|
|
||||||
start_time = time.time()
|
|
||||||
|
|
||||||
# Run the K-means algorithm
|
|
||||||
for _ in range(n_iter):
|
|
||||||
kmeans(cuda.In(im_data), cuda.Out(labels), cuda.In(centroids), np.int32(im_data.shape[0] * im_data.shape[1]), np.int32(k), np.int32(im_data.shape[-1]), block=(1024,1,1), grid=(im_data.shape[0] * im_data.shape[1] // 1024 + 1, 1))
|
|
||||||
|
|
||||||
# Update the centroids
|
|
||||||
for i in range(k):
|
|
||||||
centroids[i] = np.mean(im_data[labels == i], axis=0)
|
|
||||||
|
|
||||||
replace_with_nearest_centroid(centroids=centroids, colors=im_data)
|
|
||||||
# Convert the labels back to the original image format
|
|
||||||
labels = labels
|
|
||||||
|
|
||||||
end_time = time.time()
|
|
||||||
print(f"It took {end_time-start_time:.2f} seconds to compute")
|
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,41 @@
|
||||||
import numpy as np
|
|
||||||
import cv2
|
|
||||||
import cupy as cp
|
import cupy as cp
|
||||||
|
import numpy as np
|
||||||
|
from sklearn.cluster import KMeans
|
||||||
|
from skimage import io
|
||||||
|
import time
|
||||||
|
|
||||||
# Load the image and convert it to a NumPy array
|
# Load the image using skimage
|
||||||
image = cv2.imread("fruits.jpg")
|
image = io.imread('fruits.jpg')
|
||||||
image = image.astype(np.float32)
|
|
||||||
|
|
||||||
# Use cupy to transfer the image to the GPU
|
# Convert the image to a CuPy array
|
||||||
image_gpu = cp.asarray(image)
|
image_cp = cp.asarray(image)
|
||||||
|
|
||||||
# Perform k-means clustering on the GPU
|
# Flatten the image into a 2D array of pixels
|
||||||
cluster_centers_gpu, labels_gpu, _ = cp.cluster.kmeans(image_gpu.reshape(-1, 3), k=8)
|
image_flat = image_cp.get().reshape(image_cp.shape[0] * image_cp.shape[1], image_cp.shape[2])
|
||||||
|
|
||||||
# Transfer the cluster centers and labels back to the CPU
|
def Kmeans_cuda(K=1):
|
||||||
cluster_centers = cp.asnumpy(cluster_centers_gpu)
|
# Use KMeans to cluster the pixels into a specified number of clusters
|
||||||
labels = cp.asnumpy(labels_gpu)
|
kmeans = KMeans(n_clusters=K, random_state=0).fit(image_flat)
|
||||||
|
|
||||||
# Convert the image pixels to the closest cluster
|
# Predict the cluster for each pixel
|
||||||
clustered_image = cluster_centers[labels].reshape(image.shape)
|
clusters = kmeans.predict(image_flat)
|
||||||
|
|
||||||
# Save the clustered image as a PNG file
|
# Create a new CuPy array to hold the modified image
|
||||||
cv2.imwrite("clustered_image.png", clustered_image)
|
new_image_cp = cp.empty_like(image_cp)
|
||||||
|
|
||||||
|
# Iterate over each pixel and assign its value to the corresponding cluster center
|
||||||
|
for i, cluster in enumerate(clusters):
|
||||||
|
new_image_cp[i // image_cp.shape[1], i % image_cp.shape[1]] = cp.asarray(kmeans.cluster_centers_[cluster])
|
||||||
|
|
||||||
|
# Convert the CuPy array back to a NumPy array
|
||||||
|
new_image = cp.asnumpy(new_image_cp)
|
||||||
|
|
||||||
|
# Save the modified image using skimage
|
||||||
|
io.imsave("fruits" + "_%d" % K + "_cuda.jpg", new_image)
|
||||||
|
|
||||||
|
|
||||||
|
for K in range(1,256):
|
||||||
|
start_time = time.time()
|
||||||
|
Kmeans_cuda(K=K)
|
||||||
|
end_time = time.time()
|
||||||
|
print(f"It took {end_time-start_time:.2f} seconds to compute for K =",K)
|
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 21 KiB |
|
@ -1,237 +0,0 @@
|
||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 2,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"import matplotlib.pyplot as plt\n",
|
|
||||||
"import numpy as np\n",
|
|
||||||
"import scipy.spatial"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 3,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"clusters = 3\n",
|
|
||||||
"mean = np.random.randint(5, size=clusters)\n",
|
|
||||||
"sd = [0.25, 0.25, 0.3]\n",
|
|
||||||
"dim = 2\n",
|
|
||||||
"nb = 50\n",
|
|
||||||
"K= clusters"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 4,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"def gen_points(mean=1,sd=0.5, nb=100, dim=2, clusters=2):\n",
|
|
||||||
" size = []\n",
|
|
||||||
" # for i in range(0,dim):\n",
|
|
||||||
" size.append(nb)\n",
|
|
||||||
" size.append(dim)\n",
|
|
||||||
" points = np.random.normal(mean[0],sd[0],size=size)\n",
|
|
||||||
" for i in range(1,clusters):\n",
|
|
||||||
" points = np.concatenate((points,np.random.normal(mean[i],sd[i],size=size)),axis=0)\n",
|
|
||||||
" \n",
|
|
||||||
" return points"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 5,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"def distance(points,Pc): \n",
|
|
||||||
" return scipy.spatial.distance.cdist(points[:,:], Pc[:,:])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 6,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"def kmeans(points = [0,0], K = 1, nb=1, dim=2):\n",
|
|
||||||
" # Initialisation K prototypes\n",
|
|
||||||
" Pc_index = []\n",
|
|
||||||
" Pc_save = np.zeros([K,dim])\n",
|
|
||||||
" clusters = []\n",
|
|
||||||
" iter = 0\n",
|
|
||||||
" eps = 0.1\n",
|
|
||||||
"\n",
|
|
||||||
" for i in range(0,K):\n",
|
|
||||||
" Pc_index.append(np.random.randint(0,nb))\n",
|
|
||||||
" Pc = points[Pc_index,:]\n",
|
|
||||||
"\n",
|
|
||||||
" # print(Pc.shape)\n",
|
|
||||||
" # print(points.shape)\n",
|
|
||||||
"\n",
|
|
||||||
" while (np.mean(distance(Pc,Pc_save)) > eps and iter < 10):\n",
|
|
||||||
" iter += 1\n",
|
|
||||||
" Pc_save = Pc\n",
|
|
||||||
" # print(Pc.shape[1])\n",
|
|
||||||
" # toto = points[:,:Pc.shape[0]]\n",
|
|
||||||
" # print(toto.shape)\n",
|
|
||||||
" dist = distance(points=points[:,:Pc.shape[1]],Pc=Pc)\n",
|
|
||||||
" clust = np.argmin(dist, axis=1)\n",
|
|
||||||
" clust = np.expand_dims(clust, axis=0)\n",
|
|
||||||
" points = np.append(points[:,:Pc.shape[1]], clust.T, axis=1)\n",
|
|
||||||
" # print(points)\n",
|
|
||||||
" Pc = np.zeros([K,dim])\n",
|
|
||||||
" index = np.array([])\n",
|
|
||||||
"\n",
|
|
||||||
" for n in range(0,2*nb):\n",
|
|
||||||
" for k in range(0,K):\n",
|
|
||||||
" index = np.append(index, (clust==k).sum())\n",
|
|
||||||
" if points[n,-1] == k:\n",
|
|
||||||
" # print(points)\n",
|
|
||||||
" # print(Pc)\n",
|
|
||||||
" Pc[k,:] = np.add(Pc[k,:], points[n,:-1])\n",
|
|
||||||
"\n",
|
|
||||||
" for k in range(0,K):\n",
|
|
||||||
" Pc[k,:] = np.divide(Pc[k,:],index[k])\n",
|
|
||||||
"\n",
|
|
||||||
" # print(Pc)\n",
|
|
||||||
" return Pc, points\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 7,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"points = gen_points(mean,sd,nb,dim,clusters)\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 8,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"Pc, clusters = kmeans(points,K=K,nb=nb,dim=dim)\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 9,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"def img_2_mat(my_img):\n",
|
|
||||||
" mat = my_img.reshape(my_img.shape[0]*my_img.shape[1],my_img.shape[2])\n",
|
|
||||||
" return mat\n",
|
|
||||||
"\n",
|
|
||||||
"def mat_2_img(mat,my_img):\n",
|
|
||||||
" img_seg = mat.reshape(my_img.shape[0], my_img.shape[1], my_img.shape[2])\n",
|
|
||||||
" return img_seg\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 10,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"(103230, 3)\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"from skimage import io\n",
|
|
||||||
"\n",
|
|
||||||
"path_image = \"fruits.jpg\"\n",
|
|
||||||
"my_img = io.imread(path_image)\n",
|
|
||||||
"Mat = img_2_mat(my_img)\n",
|
|
||||||
"print(Mat.shape)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 11,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"[[[0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]]\n",
|
|
||||||
"\n",
|
|
||||||
" [[0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]]]\n",
|
|
||||||
"[[0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]]\n",
|
|
||||||
"[[[0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]]\n",
|
|
||||||
"\n",
|
|
||||||
" [[0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]\n",
|
|
||||||
" [0. 1. 2.]]]\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"A = np.zeros((2,3,3))\n",
|
|
||||||
"for i in range(3):\n",
|
|
||||||
" A[:,:,i] = i\n",
|
|
||||||
"\n",
|
|
||||||
"print(A)\n",
|
|
||||||
"\n",
|
|
||||||
"B = img_2_mat(A)\n",
|
|
||||||
"\n",
|
|
||||||
"print(B)\n",
|
|
||||||
"B[0,:] = np.array([0,0,0])\n",
|
|
||||||
"A = mat_2_img(B,A)\n",
|
|
||||||
"\n",
|
|
||||||
"print(A)"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python 3.9.4 64-bit",
|
|
||||||
"language": "python",
|
|
||||||
"name": "python3"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.9.4"
|
|
||||||
},
|
|
||||||
"orig_nbformat": 4,
|
|
||||||
"vscode": {
|
|
||||||
"interpreter": {
|
|
||||||
"hash": "2ef431f6525756fa8a44688585fa332ef3b2e5fcfe8fe75df35bbf7028a8b511"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 2
|
|
||||||
}
|
|
|
@ -1851,7 +1851,7 @@
|
||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.9.4"
|
"version": "3.9.4 (tags/v3.9.4:1f2e308, Apr 6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)]"
|
||||||
},
|
},
|
||||||
"orig_nbformat": 4,
|
"orig_nbformat": 4,
|
||||||
"vscode": {
|
"vscode": {
|
||||||
|
|