Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Project Addition]: Real Time Sudoku Solver #799

Merged
merged 12 commits into from
Jun 16, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Real Time Sudoku Solver/Dataset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Real Time Sudoku Solver

1. In the Models Folder, Run the `sudoku testing.ipynb` file. You need not run other files. This file itself will do all the work for you.
2. Make sure your webcam is connected and all the requirements is satisfied.
3. As soon as the window opens, show your sudoku image (as shown in the video demonstration).
4. Your sudoku is solved!
Binary file added Real Time Sudoku Solver/Images/1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Real Time Sudoku Solver/Images/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Real Time Sudoku Solver/Images/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Real Time Sudoku Solver/Images/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Real Time Sudoku Solver/Images/5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Real Time Sudoku Solver/Images/6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
455 changes: 455 additions & 0 deletions Real Time Sudoku Solver/Model/RealTimeSudokuSolver.ipynb

Large diffs are not rendered by default.

Binary file not shown.
143 changes: 143 additions & 0 deletions Real Time Sudoku Solver/Model/sudoku testing.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"importing Jupyter notebook from sudokuSolver.ipynb\n"
]
}
],
"source": [
"import cv2\n",
"import numpy as np\n",
"import keras\n",
"from tensorflow.keras.models import Sequential\n",
"from tensorflow.keras.layers import Dense, Dropout, Flatten\n",
"from tensorflow.keras.layers import Conv2D, MaxPooling2D\n",
"from tensorflow.keras import backend as K\n",
"\n",
"import import_ipynb\n",
"%run RealTimeSudokuSolver.ipynb\n",
"%run sudokuSolver.ipynb\n",
"# --->import RealTimeSudokuSolve\n",
"from scipy import ndimage\n",
"import math\n",
"# --->import sudokuSolver\n",
"import copy\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# This is the main file. Just run all cells in this file\n",
"# you need not run other files. This file itself will do all the work for you.\n",
"\n",
"# I have trained the CNN model and saved the architecture in digitRecognition.h5 file.\n",
"\n",
"def showImage(img, name, width, height):\n",
" new_image = np.copy(img)\n",
" new_image = cv2.resize(new_image, (width, height))\n",
" cv2.imshow(name, new_image)\n",
"\n",
"# Load and set up Camera\n",
"cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)\n",
"cap.set(3, 1280) # HD Camera\n",
"cap.set(4, 720)\n",
"\n",
"# Loading model (Load weights and configuration seperately to speed up model and predictions)\n",
"input_shape = (28, 28, 1)\n",
"num_classes = 9\n",
"model = Sequential()\n",
"model.add(Conv2D(32, kernel_size=(3, 3),\n",
" activation='relu',\n",
" input_shape=input_shape))\n",
"model.add(Conv2D(64, (3, 3), activation='relu'))\n",
"model.add(MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(Dropout(0.25))\n",
"model.add(Flatten())\n",
"model.add(Dense(128, activation='relu'))\n",
"model.add(Dropout(0.5))\n",
"model.add(Dense(num_classes, activation='softmax'))\n",
"\n",
"# Load weights from pre-trained model. This model is trained in digitRecognition.py\n",
"model.load_weights(\"digitRecognition.h5\") \n",
"\n",
"old_sudoku = None # Used to compare new sudoku or old sudoku\n",
"while(True):\n",
" ret, frame = cap.read() # Read the frame\n",
" if ret == True:\n",
" \n",
" # RealTimeSudokuSolver.recognize_sudoku_and_solve\n",
" sudoku_frame = recognize_sudoku_and_solve(frame, model, old_sudoku) \n",
" showImage(sudoku_frame, \"Real Time Sudoku Solver\", 1066, 600)\n",
" if cv2.waitKey(1) == ord('q'): # Hit q if you want to stop the camera\n",
" break\n",
" else:\n",
" break\n",
"\n",
"cap.release()\n",
"cv2.destroyAllWindows()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
149 changes: 149 additions & 0 deletions Real Time Sudoku Solver/Model/sudokuSolver.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"class EntryData:\n",
" def __init__(self, r, c, n):\n",
" self.row = r\n",
" self.col = c\n",
" self.choices = n\n",
"\n",
" def set_data(self, r, c, n):\n",
" self.row = r\n",
" self.col = c\n",
" self.choices = n\n",
" \n",
"# Solve Sudoku using Best-first search\n",
"def solve_sudoku(matrix):\n",
" cont = [True]\n",
" # See if it is even possible to have a solution\n",
" for i in range(9):\n",
" for j in range(9):\n",
" if not can_be_correct(matrix, i, j): # If it is not possible, stop\n",
" return\n",
" sudoku_helper(matrix, cont) # Otherwise try to solve the Sudoku puzzle\n",
"\n",
"# Helper function - The heart of Best First Search\n",
"def sudoku_helper(matrix, cont):\n",
" if not cont[0]: # Stopping point 1\n",
" return\n",
"\n",
" # Find the best entry (The one with the least possibilities)\n",
" best_candidate = EntryData(-1, -1, 100)\n",
" for i in range(9):\n",
" for j in range(9):\n",
" if matrix[i][j] == 0: # If it is unfilled\n",
" num_choices = count_choices(matrix, i, j)\n",
" if best_candidate.choices > num_choices:\n",
" best_candidate.set_data(i, j, num_choices)\n",
"\n",
" # If didn't find any choices, it means...\n",
" if best_candidate.choices == 100: # Has filled all board, Best-First Search done! Note, whether we have a solution or not depends on whether all Board is non-zero\n",
" cont[0] = False # Set the flag so that the rest of the recursive calls can stop at \"stopping points\"\n",
" return\n",
"\n",
" row = best_candidate.row\n",
" col = best_candidate.col\n",
"\n",
" # If found the best candidate, try to fill 1-9\n",
" for j in range(1, 10):\n",
" if not cont[0]: # Stopping point 2\n",
" return\n",
"\n",
" matrix[row][col] = j\n",
"\n",
" if can_be_correct(matrix, row, col):\n",
" sudoku_helper(matrix, cont)\n",
"\n",
" if not cont[0]: # Stopping point 3\n",
" return\n",
" matrix[row][col] = 0 # Backtrack, mark the current cell empty again\n",
" \n",
"\n",
"# Count the number of choices haven't been used\n",
"def count_choices(matrix, i, j):\n",
" can_pick = [True,True,True,True,True,True,True,True,True,True]; # From 0 to 9 - drop 0\n",
" \n",
" # Check row\n",
" for k in range(9):\n",
" can_pick[matrix[i][k]] = False\n",
"\n",
" # Check col\n",
" for k in range(9):\n",
" can_pick[matrix[k][j]] = False;\n",
"\n",
" # Check 3x3 square\n",
" r = i // 3\n",
" c = j // 3\n",
" for row in range(r*3, r*3+3):\n",
" for col in range(c*3, c*3+3):\n",
" can_pick[matrix[row][col]] = False\n",
"\n",
" # Count\n",
" count = 0\n",
" for k in range(1, 10): # 1 to 9\n",
" if can_pick[k]:\n",
" count += 1\n",
"\n",
" return count\n",
"\n",
"# Return true if the current cell doesn't create any violation\n",
"def can_be_correct(matrix, row, col):\n",
" \n",
" # Check row\n",
" for c in range(9):\n",
" if matrix[row][col] != 0 and col != c and matrix[row][col] == matrix[row][c]:\n",
" return False\n",
"\n",
" # Check column\n",
" for r in range(9):\n",
" if matrix[row][col] != 0 and row != r and matrix[row][col] == matrix[r][col]:\n",
" return False\n",
"\n",
" # Check 3x3 square\n",
" r = row // 3\n",
" c = col // 3\n",
" for i in range(r*3, r*3+3):\n",
" for j in range(c*3, c*3+3):\n",
" if row != i and col != j and matrix[i][j] != 0 and matrix[i][j] == matrix[row][col]:\n",
" return False\n",
" \n",
" return True\n",
"\n",
"# Return true if the whole board has been occupied by some non-zero number\n",
"# If this happens, the current board is the solution to the original Sudoku\n",
"def all_board_non_zero(matrix):\n",
" for i in range(9):\n",
" for j in range(9):\n",
" if matrix[i][j] == 0:\n",
" return False\n",
" return True"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
8 changes: 8 additions & 0 deletions Real Time Sudoku Solver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Real Time Sudoku Solver

As the name suggests, the application solves standard Sudoku puzzle in real time. The application is based primarily on Image Processing and Machine Learning(CNN).

After the application starts, through video capturing, it identifies the Sudoku board, solves the puzzle and writes the solution on board itself.

## Video Demonstration
![Real Time Sudoku Solver](https://github.com/abckhush/DL-Simplified/assets/127378920/6485b261-b624-46e5-8947-61c13390fe11)
5 changes: 5 additions & 0 deletions Real Time Sudoku Solver/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
keras==2.3.1
numpy==1.22.0
opencv-python==4.2.0.34
scipy==1.4.1
import-ipynb==0.1.3