Keras

language:

  • en library_name: keras pipeline_tag: image-classification tags:
  • tensorflow
  • keras
  • cnn
  • computer-vision
  • image-classification
  • digit-recognition
  • sudoku
  • sudoku-solver
  • opencv datasets:
  • hidemyas/sudoku-digit

Sudoku Digit Recognition

This repository contains a TensorFlow/Keras convolutional neural network developed to recognize digits extracted from Sudoku puzzle cells.

The model is designed as the digit-recognition component of the Sudoku Solver project. In the complete application, OpenCV is used to detect the Sudoku board, extract individual cells, preprocess the cell images, recognize the digits, and solve the puzzle using a backtracking algorithm.

Model Details

  • Developed by: hidemyas
  • Model type: Convolutional Neural Network
  • Framework: TensorFlow / Keras
  • Task: Image classification
  • Input format: Grayscale digit image
  • Input size: 28 Γ— 28 Γ— 1
  • Output: Predicted Sudoku digit class
  • Supported digit classes: 1–9
  • Primary use case: Recognition of printed digits extracted from Sudoku grids

Model Architecture

The model uses the following architecture:

Input: 28 Γ— 28 Γ— 1
β”‚
β”œβ”€β”€ Rescaling: 1 / 255
β”œβ”€β”€ Data augmentation
β”‚   β”œβ”€β”€ Random rotation
β”‚   β”œβ”€β”€ Random translation
β”‚   └── Random zoom
β”‚
β”œβ”€β”€ Conv2D: 32 filters, 3 Γ— 3, ReLU
β”œβ”€β”€ Batch normalization
β”œβ”€β”€ Conv2D: 32 filters, 3 Γ— 3, ReLU
β”œβ”€β”€ Max pooling
β”‚
β”œβ”€β”€ Conv2D: 64 filters, 3 Γ— 3, ReLU
β”œβ”€β”€ Batch normalization
β”œβ”€β”€ Conv2D: 64 filters, 3 Γ— 3, ReLU
β”œβ”€β”€ Max pooling
β”‚
β”œβ”€β”€ Conv2D: 128 filters, 3 Γ— 3, ReLU
β”œβ”€β”€ Flatten
β”œβ”€β”€ Dense: 128 units, ReLU
β”œβ”€β”€ Dropout: 0.35
└── Dense: 9 classes, Softmax

The model was compiled with:

  • Optimizer: Adam
  • Learning rate: 0.0003
  • Loss function: Sparse categorical cross-entropy
  • Metric: Accuracy

Training Data

The model was trained using the hidemyas/sudoku-digit dataset.

The expected dataset directory structure is:

dataset/
└── data/
    β”œβ”€β”€ 1/
    β”‚   β”œβ”€β”€ image_1.png
    β”‚   └── ...
    β”œβ”€β”€ 2/
    β”‚   β”œβ”€β”€ image_1.png
    β”‚   └── ...
    β”œβ”€β”€ 3/
    β”œβ”€β”€ 4/
    β”œβ”€β”€ 5/
    β”œβ”€β”€ 6/
    β”œβ”€β”€ 7/
    β”œβ”€β”€ 8/
    └── 9/

The parent directory name of each image is used as its class label.

All images are:

  • Loaded in grayscale
  • Resized to 28 Γ— 28
  • Converted into NumPy arrays
  • Automatically normalized by the model's rescaling layer

Dataset Splits

The dataset is divided into:

Split Percentage
Training 70%
Validation 15%
Testing 15%

The splits are generated using:

  • random_state=42
  • Stratified sampling based on class labels

Data Augmentation

The following augmentation methods are applied during training:

  • Random rotation: 0.05
  • Random horizontal and vertical translation: 0.07
  • Random zoom: 0.07

These transformations are intended to improve robustness against small positioning, scale, and rotation differences in extracted Sudoku digits.

Training Configuration

The primary training configuration is:

Parameter Value
Maximum epochs 40
Batch size 32
Shuffle Enabled
Early stopping patience 6
Learning-rate reduction patience 2
Learning-rate reduction factor 0.5
Minimum learning rate 1e-6

The best model is selected according to validation loss.

Training callbacks include:

  • ModelCheckpoint
  • ReduceLROnPlateau
  • EarlyStopping

How to Use

Installation

pip install tensorflow opencv-python numpy huggingface_hub

Downloading the Model

from huggingface_hub import hf_hub_download

model_path = hf_hub_download(
    repo_id="hidemyas/sudoku-digit-recognition",
    filename="model.keras"
)

classes_path = hf_hub_download(
    repo_id="hidemyas/sudoku-digit-recognition",
    filename="classes.npy"
)

Running Inference

import cv2
import numpy as np
import tensorflow as tf
from huggingface_hub import hf_hub_download


MODEL_REPO = "hidemyas/sudoku-digit-recognition"

model_path = hf_hub_download(
    repo_id=MODEL_REPO,
    filename="model.keras"
)

classes_path = hf_hub_download(
    repo_id=MODEL_REPO,
    filename="classes.npy"
)

model = tf.keras.models.load_model(model_path)
classes = np.load(classes_path, allow_pickle=True)


def predict_digit(image_path: str):
    image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)

    if image is None:
        raise FileNotFoundError(
            f"Image could not be loaded: {image_path}"
        )

    image = cv2.resize(
        image,
        (28, 28),
        interpolation=cv2.INTER_AREA
    )

    image = image.astype(np.float32)

    # Shape: (28, 28) -> (1, 28, 28, 1)
    image = np.expand_dims(image, axis=-1)
    image = np.expand_dims(image, axis=0)

    probabilities = model.predict(image, verbose=0)[0]

    predicted_index = int(np.argmax(probabilities))
    predicted_digit = classes[predicted_index]
    confidence = float(probabilities[predicted_index])

    return {
        "digit": str(predicted_digit),
        "confidence": confidence
    }


result = predict_digit("digit.png")

print("Predicted digit:", result["digit"])
print("Confidence:", result["confidence"])

The input image should contain a single digit, ideally centered and extracted from a Sudoku cell.

Do not manually divide the pixel values by 255 when using the uploaded Keras model because normalization is already performed by the model's internal Rescaling layer.

OpenCV Array Usage

The model can also receive an existing OpenCV grayscale array:

import cv2
import numpy as np


def predict_opencv_image(model, classes, image):
    if image is None:
        raise ValueError("The input image cannot be None.")

    if len(image.shape) == 3:
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    image = cv2.resize(
        image,
        (28, 28),
        interpolation=cv2.INTER_AREA
    )

    image_array = image.astype(np.float32)
    image_array = np.expand_dims(image_array, axis=-1)
    image_array = np.expand_dims(image_array, axis=0)

    probabilities = model.predict(
        image_array,
        verbose=0
    )[0]

    predicted_index = int(np.argmax(probabilities))

    return {
        "digit": str(classes[predicted_index]),
        "confidence": float(probabilities[predicted_index]),
        "probabilities": probabilities.tolist()
    }

Intended Use

The model is intended for:

  • Recognizing printed digits in Sudoku puzzle cells
  • Computer-vision-based Sudoku solving applications
  • Educational image-classification projects
  • OpenCV and TensorFlow integration examples
  • Digit-recognition experiments involving Sudoku images

Out-of-Scope Uses

The model is not specifically designed for:

  • General handwritten digit recognition
  • Multi-digit number recognition
  • Full-page optical character recognition
  • Recognition of letters or symbols
  • Recognition of empty Sudoku cells
  • Images containing multiple digits
  • High-stakes document-processing applications

Limitations

The model's performance can be affected by:

  • Sudoku grid lines remaining in the cropped cell
  • Digits touching cell borders
  • Incorrect perspective transformation
  • Very small or blurred digits
  • Strong shadows or uneven lighting
  • Inverted foreground and background colors
  • Fonts that differ significantly from the training data
  • Multiple objects appearing inside one cell
  • Incorrectly cropped Sudoku cells

The model only classifies the supplied cell image. It does not independently determine whether the cell is empty.

Empty-cell detection should be handled separately before calling the digit classifier.

Recommended Input Preprocessing

For best results:

  1. Detect and rectify the Sudoku board.
  2. Divide the board into 81 cells.
  3. Remove cell margins and grid-line artifacts.
  4. Convert each cell to grayscale.
  5. Apply thresholding when necessary.
  6. Detect whether the cell is empty.
  7. Center the digit inside the cell.
  8. Resize the image to 28 Γ— 28.
  9. Pass the image to the model without external normalization.

A suitable input generally has:

  • A light or white background
  • A dark or black digit
  • One centered digit
  • Minimal grid-line artifacts
  • A square aspect ratio

Evaluation

The repository currently does not provide a finalized public evaluation report containing test accuracy, confusion matrix, precision, recall, or F1-score.

Reported metrics should be added after evaluating the final uploaded model on a held-out test set.

Example evaluation:

test_loss, test_accuracy = model.evaluate(
    testX,
    testY,
    verbose=0
)

print("Test loss:", test_loss)
print("Test accuracy:", test_accuracy)

Complete Sudoku Solver

The complete application is available at:

hidemyas/sudoku-solver

The project contains modules for:

  • Sudoku-board detection
  • Perspective correction
  • Cell extraction
  • Digit recognition
  • Sudoku-board construction
  • Backtracking-based puzzle solving

Repository Files

The model repository is expected to contain:

sudoku-digit-recognition/
β”œβ”€β”€ README.md
β”œβ”€β”€ model.keras
└── classes.npy
  • model.keras: Trained TensorFlow/Keras model
  • classes.npy: Original class-label ordering used by the model
  • README.md: Model card and usage documentation

The classes.npy file should be loaded during inference instead of assuming that the Softmax output indices directly correspond to digits.

Disclaimer

This model was developed primarily for educational and experimental use as part of a Sudoku-solving computer-vision project. Its predictions should be validated before being used in applications requiring high reliability.

Downloads last month
43
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Dataset used to train hidemyas/sudoku-digit-recognition