| import os
|
| import numpy as np
|
| from PIL import Image
|
| from sklearn.neighbors import KNeighborsClassifier
|
| from sklearn.preprocessing import LabelEncoder
|
| from sklearn.model_selection import train_test_split
|
| from sklearn.metrics import classification_report
|
| import joblib
|
| from sklearn.utils.multiclass import unique_labels
|
|
|
|
|
| def getListOfFiles(dirName):
|
| listOfFile = os.listdir(dirName)
|
| allFiles = []
|
| for entry in listOfFile:
|
| fullPath = os.path.join(dirName, entry)
|
| if os.path.isdir(fullPath):
|
| allFiles += getListOfFiles(fullPath)
|
| else:
|
| allFiles.append(fullPath)
|
| return allFiles
|
|
|
|
|
| DATASET_PATH = "./knn_number_dataset/"
|
| imagePaths = getListOfFiles(DATASET_PATH)
|
|
|
|
|
| data = []
|
| labels = []
|
| for i, imagePath in enumerate(imagePaths):
|
| label = os.path.basename(os.path.dirname(imagePath))
|
|
|
| try:
|
|
|
| with Image.open(imagePath) as img:
|
| img = img.convert("RGB")
|
| img = img.resize((32, 32))
|
| image = np.array(img)
|
| except Exception as e:
|
| print(f"β οΈ Skipping unreadable image: {imagePath} | Error: {e}")
|
| continue
|
|
|
| data.append(image)
|
| labels.append(label)
|
|
|
| if i % 100 == 0:
|
| print(f"π₯ Processed {i} images...")
|
|
|
|
|
| data = np.array(data)
|
| labels = np.array(labels)
|
|
|
|
|
| le = LabelEncoder()
|
| labels = le.fit_transform(labels)
|
|
|
|
|
| dataset_size = data.shape[0]
|
| data = data.reshape(dataset_size, -1)
|
|
|
| print(f"β
Data shape: {data.shape}")
|
| print(f"β
Labels shape: {labels.shape}")
|
| print(f"β
Unique classes: {set(labels)}")
|
|
|
|
|
| (trainX, testX, trainY, testY) = train_test_split(
|
| data, labels, test_size=0.25, random_state=42, stratify=labels
|
| )
|
|
|
|
|
| model = KNeighborsClassifier(n_neighbors=3, n_jobs=-1)
|
| model.fit(trainX, trainY)
|
|
|
|
|
| print("\nπ Classification Report:")
|
| predictions = model.predict(testX)
|
| present_labels = unique_labels(testY, predictions)
|
|
|
| print(classification_report(
|
| testY,
|
| predictions,
|
| labels=present_labels,
|
| target_names=le.inverse_transform(present_labels)
|
| ))
|
|
|
|
|
| os.makedirs("Models", exist_ok=True)
|
| joblib.dump(model, os.path.join("Models", "knn_model.pkl"))
|
| np.save(os.path.join("Models", "label_classes.npy"), le.classes_)
|
|
|
| print("β
Model saved to: Models/knn_model.pkl")
|
| print("β
Label classes saved to: Models/label_classes.npy")
|
|
|