Spaces:
Sleeping
Sleeping
File size: 5,561 Bytes
1a5455d 2b4a005 1a5455d 0f53078 1a5455d b75b567 1b4dd95 cfd19ee b7b5aa9 cfd19ee b7b5aa9 cfd19ee b7b5aa9 cfd19ee b7b5aa9 cfd19ee b7b5aa9 cfd19ee 87b01f5 cfd19ee 87b01f5 cfd19ee 87b01f5 cfd19ee 87b01f5 cfd19ee 87b01f5 cfd19ee 87b01f5 cfd19ee 2b4a005 1a5455d 2b4a005 1a5455d 2b4a005 05bfa3c 53610b5 05bfa3c 2b4a005 b7b5aa9 2b4a005 b7b5aa9 2b4a005 b7b5aa9 2b4a005 1a5455d 2b4a005 1a5455d 2b4a005 b7b5aa9 2b4a005 122de80 9b08fea 9ede33d b2a1451 cb54a47 2b4a005 38f06f9 2b4a005 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
import streamlit as st
import seaborn as sns
import matplotlib.pyplot as plt
import os, random
import cv2
from tensorflow.keras.models import load_model
from PIL import Image
import numpy as np
model = load_model('sudoku_net.h5')
def preprocess(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3),6)
#blur = cv2.bilateralFilter(gray,9,75,75)
threshold_img = cv2.adaptiveThreshold(blur,255,1,1,11,2)
return threshold_img
def main_outline(contour):
biggest = np.array([])
max_area = 0
for i in contour:
area = cv2.contourArea(i)
if area >50:
peri = cv2.arcLength(i, True)
approx = cv2.approxPolyDP(i , 0.02* peri, True)
if area > max_area and len(approx) ==4:
biggest = approx
max_area = area
return biggest ,max_area
def reframe(points):
points = points.reshape((4, 2))
points_new = np.zeros((4,1,2),dtype = np.int32)
add = points.sum(1)
points_new[0] = points[np.argmin(add)]
points_new[3] = points[np.argmax(add)]
diff = np.diff(points, axis =1)
points_new[1] = points[np.argmin(diff)]
points_new[2] = points[np.argmax(diff)]
return points_new
def splitcells(img):
rows = np.vsplit(img,9)
boxes = []
for r in rows:
cols = np.hsplit(r,9)
for box in cols:
boxes.append(box)
return boxes
def CropCell(cells):
Cells_croped = []
for image in cells:
img = np.array(image)
img = img[4:46, 6:46]
img = Image.fromarray(img)
Cells_croped.append(img)
return Cells_croped
def read_cells(cell,model):
result = []
for image in cell:
# preprocess the image as it was in the model
img = np.asarray(image)
img = img[4:img.shape[0] - 4, 4:img.shape[1] -4]
img = cv2.resize(img, (32, 32))
img = img / 255
img = img.reshape(1, 32, 32, 1)
# getting predictions and setting the values if probabilities are above 65%
predictions = model.predict(img)
classIndex = np.argmax(predictions, axis=1)
probabilityValue = np.amax(predictions)
if probabilityValue > 0.65:
result.append(classIndex[0])
else:
result.append(0)
return result
#This function finds the next box to solve
def find_empty(board):
for i in range(len(board)):
for j in range(len(board)):
if board[i][j] == 0:
return i,j
return None
#Function to fill in the possible values by evaluating rows collumns and smaller cells
def valid(board, num, pos):
# check row
for i in range(len(board)):
if board[pos[0]][i]==num and pos[1]!=i:
return False
# check column
for i in range(len(board)):
if board[i][pos[1]]==num and pos[0]!=i:
return False
# check 3X3 cube
box_x=pos[0]//3
box_y=pos[1]//3
for i in range(box_x*3,box_x+3):
for j in range(box_y*3,box_y+3):
if board[i][j]==num and [i,j]!=pos:
return False
return True
#function to loop over untill a valid answer is found.
def solve(board):
find=find_empty(board)
if not find:
return True
else:
row,col=find
for i in range(1,10):
if valid(board,i,[row,col]):
board[row][col]=i
if solve(board):
return True
board[row][col]=0
return False
def main():
st.title('Sudoku Solver')
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
col1, col2 = st.columns(2)
puzzle = Image.open(uploaded_file)
col1.image(puzzle, use_column_width=True)
puzzle = np.asarray(puzzle)
# Resizing puzzle to be solved
puzzle = cv2.resize(puzzle, (450,450))
# Preprocessing Puzzle
su_puzzle = preprocess(puzzle)
# Finding the outline of the sudoku puzzle in the image
su_contour_1= su_puzzle.copy()
su_contour_2= puzzle.copy()
su_contour, hierarchy = cv2.findContours(su_puzzle,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(su_contour_1, su_contour,-1,(0,255,0),3)
black_img = np.zeros((450,450,3), np.uint8)
su_biggest, su_maxArea = main_outline(su_contour)
if su_biggest.size != 0:
su_biggest = reframe(su_biggest)
cv2.drawContours(su_contour_2,su_biggest,-1, (0,255,0),10)
su_pts1 = np.float32(su_biggest)
su_pts2 = np.float32([[0,0],[450,0],[0,450],[450,450]])
su_matrix = cv2.getPerspectiveTransform(su_pts1,su_pts2)
su_imagewrap = cv2.warpPerspective(puzzle,su_matrix,(450,450))
su_imagewrap =cv2.cvtColor(su_imagewrap, cv2.COLOR_BGR2GRAY)
sudoku_cell = splitcells(su_imagewrap)
sudoku_cell_croped= CropCell(sudoku_cell)
grid = read_cells(sudoku_cell_croped, model)
grid = np.asarray(grid)
grid = np.reshape(grid,(9,9))
solve(grid)
# Display the solution or appropriate message
if solve(grid):
st.subheader("Sudoku Solved:")
st.write(grid)
else:
col2.write("No solution found.")
if __name__ == '__main__':
main()
|