MH0386’s Jupyter Notebooks
  • Home
  1. Notebooks
  2. Machine Learning
  3. Using Chain Code
  • Notebooks
    • Deep Learning
      • Create Autoencoder Model
      • Inception Network
      • Word2vec
    • Fine Tuning
      • Data
      • Data
    • Machine Learning
      • Iris Classification from Scratch
      • Using Chain Code
      • Loading Data
      • Imports
      • Model
      • Naive Bayes from Built-in
    • Pre Processing
      • Text Processing
    • Rag
      • Try Docling

On this page

  • Using Centroid
  • Edit this page
  • View source
  • Report an issue
  1. Notebooks
  2. Machine Learning
  3. Using Chain Code

Using Chain Code

  • Show All Code
  • Hide All Code
Code
import sys
import cv2
import numpy as np
from keras.datasets import mnist
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix, ConfusionMatrixDisplay
from sklearn.preprocessing import OneHotEncoder
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
Code
NUM_BLOCKS = 9
block_size = int(27 / np.sqrt(NUM_BLOCKS))
Code
def calculate_centroid(block):
    """Calculate the centroid of a 2D matrix"""
    rows, cols = block.shape
    x_centroid = 0.0
    y_centroid = 0.0
    for i in range(rows):
        for j in range(cols):
            x_centroid += i * block[i, j]
            y_centroid += j * block[i, j]
    total = np.sum(block)
    x_centroid = x_centroid / total
    y_centroid = y_centroid / total
    return x_centroid, y_centroid
Code
def generate_chain_code(image):
    image = np.dstack([image, image, image])
    img = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    _, img_bin = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)
    row, col = img_bin.shape
    if np.all(img_bin == 0):
        img_bin[np.random.randint(0, row, 2), np.random.randint(0, col, 2)] = 255
    contours, _ = cv2.findContours(img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    chain_code = []
    point = contours[0][0][0]
    for i in range(1, len(contours[0])):
        next_point = contours[0][i][0]
        diff = next_point - point
        if diff[0] == 0 and diff[1] == 1:
            chain_code.append(6)
        elif diff[0] == -1 and diff[1] == 1:
            chain_code.append(5)
        elif diff[0] == -1 and diff[1] == 0:
            chain_code.append(4)
        elif diff[0] == -1 and diff[1] == -1:
            chain_code.append(3)
        elif diff[0] == 0 and diff[1] == -1:
            chain_code.append(2)
        elif diff[0] == 1 and diff[1] == -1:
            chain_code.append(1)
        elif diff[0] == 1 and diff[1] == 0:
            chain_code.append(0)
        elif diff[0] == 1 and diff[1] == 1:
            chain_code.append(7)
        point = next_point
    return chain_code
Code
def extract_features_with_chain_code(image):
    features = np.zeros((block_size, block_size, 50))
    for i in range(0, 27, block_size):
        for j in range(0, 27, block_size):
            block = image[i : i + block_size, j : j + block_size]
            chain_code = generate_chain_code(block)
            # print("chain len", len(chain_code))
            if len(chain_code) < 50:
                chain_code += [0] * (50 - len(chain_code))
            # print("chain", chain_code)
            features[i // block_size, j // block_size] = chain_code
    return features
Code
def extract_features_with_centroid(image):
    features = np.zeros((block_size, block_size, 2))
    for i in range(0, 28, block_size):
        for j in range(0, 28, block_size):
            block = image[i : i + block_size, j : j + block_size]
            x_centroid, y_centroid = calculate_centroid(block)
            features[int(i / block_size), int(j / block_size), 0] = x_centroid
            features[int(i / block_size), int(j / block_size), 1] = y_centroid
    return features
Code
def k_means(X, k=10, max_iters=sys.maxsize):
    centroids = X[np.random.choice(range(X.shape[0]), size=k, replace=False)]
    for _ in range(max_iters):
        labels = np.argmin(
            np.linalg.norm(X[:, np.newaxis] - centroids, axis=-1), axis=-1
        )
        new_centroids = np.array([X[labels == i].mean(axis=0) for i in range(k)])
        if np.all(centroids == new_centroids):
            break
        centroids = new_centroids
    return centroids, labels
Code
(x_train, y_train), (x_test, y_test) = mnist.load_data()
Code
x_train = x_train[:, 1:28, 1:28]
x_test = x_test[:, 1:28, 1:28]
y_train = y_train.astype(np.int64)
y_test = y_test.astype(np.int64)
Code
encoder = OneHotEncoder()
Code
x_train.shape, y_train.shape
Code
x_train, x_val, y_train, y_val = train_test_split(
    x_train, y_train, test_size=0.2, random_state=42, shuffle=True
)
Code
x_train.shape, y_train.shape
Code
train_features_with_chain_code = np.nan_to_num(
    np.array([extract_features_with_chain_code(image) for image in x_train])
)
Code
train_features_with_chain_code.shape
Code
train_features_with_chain_code = train_features_with_chain_code.reshape(
    train_features_with_chain_code.shape[0], -1
)
Code
train_features_with_chain_code.shape
Code
centroids, labels = k_means(train_features_with_chain_code)
Code
centroids.shape, labels.shape
Code
labels = encoder.fit_transform(labels.reshape(-1, 1)).toarray()
y_train = encoder.fit_transform(y_train.reshape(-1, 1)).toarray()
Code
accuracy_score(y_train, labels)
Code
best = KMeans(n_clusters=10)
accuracies = np.array([])
max_acc = 0
for _ in range(10):
    kmeans = KMeans(n_clusters=10)
    kmeans.fit(train_features_with_chain_code)
    labels = kmeans.predict(train_features_with_chain_code)
    labels = encoder.fit_transform(labels.reshape(-1, 1)).toarray()
    acc = accuracy_score(y_train, labels)
    print("Accuracy: ", acc)
    accuracies = np.append(accuracies, acc)
    if max_acc < accuracies.max():
        max_acc = accuracies.max()
        best = kmeans
print("max acc: ", max_acc)
Code
y_train = np.argmax(y_train, axis=1)
labels = np.argmax(labels, axis=1)
Code
y_train.shape, labels.shape
Code
cm = ConfusionMatrixDisplay(confusion_matrix=confusion_matrix(y_train, labels))
cm.plot()
plt.show()

Using Centroid

Code
train_features_with_centroid = np.nan_to_num(
    np.array([extract_features_with_centroid(image) for image in x_train])
)
Code
train_features_with_centroid.shape
Code
train_features_with_centroid = train_features_with_centroid.reshape(
    train_features_with_centroid.shape[0], -1
)
Code
train_features_with_centroid.shape
Code
centroids, labels = k_means(train_features_with_centroid)
Code
centroids.shape, labels.shape
Code
labels = encoder.fit_transform(labels.reshape(-1, 1)).toarray()
y_train = encoder.fit_transform(y_train.reshape(-1, 1)).toarray()
Code
accuracy_score(y_train, labels)
Code
best = KMeans(n_clusters=10)
accuracies = np.array([])
max_acc = 0
for _ in range(10):
    kmeans = KMeans(n_clusters=10)
    kmeans.fit(train_features_with_centroid)
    labels = kmeans.predict(train_features_with_centroid)
    labels = encoder.fit_transform(labels.reshape(-1, 1)).toarray()
    acc = accuracy_score(y_train, labels)
    print("Accuracy: ", acc)
    accuracies = np.append(accuracies, acc)
    if max_acc < accuracies.max():
        max_acc = accuracies.max()
        best = kmeans
print("max acc: ", max_acc)
Code
y_train = np.argmax(y_train, axis=1)
labels = np.argmax(labels, axis=1)
Code
y_train.shape, labels.shape
Code
cm = ConfusionMatrixDisplay(confusion_matrix=confusion_matrix(y_train, labels))
cm.plot()
plt.show()
Back to top
Iris Classification from Scratch
Loading Data

Mohamed Hisham Abdelzaher

 
  • Edit this page
  • View source
  • Report an issue