|
|
- Let's jump right into the fun and start making pixel art with Open CV.
- Before you read this article, consider checkout out these articles:
-
- - [Shallow Dive into Open CV](https://jrtechs.net/open-source/shallow-dive-into-open-cv)
- - [Image Clustering with K-means](https://jrtechs.net/data-science/image-clustering-with-k-means)
-
-
- Like most CV projects, we need to start by importing some libraries and loading an image.
-
- ```python
- # Open cv library
- import cv2
-
- # matplotlib for displaying the images
- from matplotlib import pyplot as plt
-
- img = cv2.imread('dolphin.jpg')
- ```
-
- I like to define scripts to print images nicely in a Jupyter notebook.
-
- ```python
- def printI(img):
- rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
- plt.imshow(rgb)
-
- def printI2(i1, i2):
- fig = plt.figure()
- ax1 = fig.add_subplot(1,2,1)
- ax1.imshow(cv2.cvtColor(i1, cv2.COLOR_BGR2RGB))
- ax2 = fig.add_subplot(1,2,2)
- ax2.imshow(cv2.cvtColor(i2, cv2.COLOR_BGR2RGB))
-
- printI(img)
- ```
-
- ![original image](media/pixel/output_2_0.png)
-
-
- To pixelate an image, we can use the open cv resize function.
- To make the image viewable, after we shrink the picture, we resize it again to be the size of the original image.
-
- ```python
- def pixelate(img, w, h):
- height, width = img.shape[:2]
-
- # Resize input to "pixelated" size
- temp = cv2.resize(img, (w, h), interpolation=cv2.INTER_LINEAR)
-
- # Initialize output image
- return cv2.resize(temp, (width, height), interpolation=cv2.INTER_NEAREST)
-
- img16 = pixelate(img, 16, 16)
-
- printI2(img, img16)
- ```
-
-
- ![pixelated 16x16](media/pixel/output_3_0.png)
-
- We can try a few different shrinkage sizes.
- 32x32 seems to work the best.
-
- ```python
- img32 = pixelate(img, 32, 32)
- img64 = pixelate(img, 64, 64)
-
- printI2(img32, img64)
- ```
-
-
- ![pixelated 32x42, 64x64](media/pixel/output_4_0.png)
-
-
-
- ```python
- img8 = pixelate(img, 8, 8)
- printI(img8)
- ```
-
-
- ![original image 8x8 pixelated](media/pixel/output_5_0.png)
-
-
- Despite the images being pixelated, they have imperfections that normal pixel art wouldn't have.
- To remove the noise and make it look smoother, we will do k-means clustering on the pixelated images.
- K-means will reduce the number of colors in the image and eliminate any noise.
- Most of the clustering code is from my blog post: [Image Clustering with K-means](https://jrtechs.net/data-science/image-clustering-with-k-means)
-
- ```python
- import skimage
- from sklearn.cluster import KMeans
- from numpy import linalg as LA
- import numpy as np
-
- def colorClustering(idx, img, k):
- clusterValues = []
- for _ in range(0, k):
- clusterValues.append([])
-
- for r in range(0, idx.shape[0]):
- for c in range(0, idx.shape[1]):
- clusterValues[idx[r][c]].append(img[r][c])
-
- imgC = np.copy(img)
-
- clusterAverages = []
- for i in range(0, k):
- clusterAverages.append(np.average(clusterValues[i], axis=0))
-
- for r in range(0, idx.shape[0]):
- for c in range(0, idx.shape[1]):
- imgC[r][c] = clusterAverages[idx[r][c]]
-
- return imgC
- ```
-
-
- ```python
- def segmentImgClrRGB(img, k):
-
- imgC = np.copy(img)
-
- h = img.shape[0]
- w = img.shape[1]
-
- imgC.shape = (img.shape[0] * img.shape[1], 3)
-
- #5. Run k-means on the vectorized responses X to get a vector of labels (the clusters);
- #
- kmeans = KMeans(n_clusters=k, random_state=0).fit(imgC).labels_
-
- #6. Reshape the label results of k-means so that it has the same size as the input image
- # Return the label image which we call idx
- kmeans.shape = (h, w)
-
- return kmeans
- ```
-
-
-
- ```python
- def kMeansImage(image, k):
- idx = segmentImgClrRGB(image, k)
- return colorClustering(idx, image, k)
-
- printI(kMeansImage(img, 5))
- ```
-
-
- ![original image with k means of 5](media/pixel/output_9_0.png)
-
-
- Running the k-means algorithm on the 32x32 bit image produces a cool look.
-
- ```python
- printI(kMeansImage(img32, 3))
- ```
-
- ![32 bit k-means of 3 clusters](media/pixel/output_10_0.png)
-
- We can compare the original, pixelated, and clustered images side by side.
-
-
- ```python
- def printI3(i1, i2, i3):
- fig = plt.figure(figsize=(18,6))
- ax1 = fig.add_subplot(1,3,1)
- ax1.imshow(cv2.cvtColor(i1, cv2.COLOR_BGR2RGB))
- ax2 = fig.add_subplot(1,3,2)
- ax2.imshow(cv2.cvtColor(i2, cv2.COLOR_BGR2RGB))
- ax3 = fig.add_subplot(1,3,3)
- ax3.imshow(cv2.cvtColor(i3, cv2.COLOR_BGR2RGB))
- plt.savefig('trifecta.png')
- printI3(img, img32, kMeansImage(img32, 3))
- ```
-
- ![original, pixelated, k-means](media/pixel/output_11_0.png)
|