Spaces:
Sleeping
Sleeping
Commit
·
cfd19ee
1
Parent(s):
c323a09
Update app.py
Browse files
app.py
CHANGED
@@ -6,6 +6,141 @@ import cv2
|
|
6 |
from tensorflow.keras.models import load_model
|
7 |
from PIL import Image
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
def main():
|
10 |
st.title('Sudoku Solver')
|
11 |
|
|
|
6 |
from tensorflow.keras.models import load_model
|
7 |
from PIL import Image
|
8 |
|
9 |
+
def preprocess(image):
|
10 |
+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
11 |
+
blur = cv2.GaussianBlur(gray, (3,3),6)
|
12 |
+
#blur = cv2.bilateralFilter(gray,9,75,75)
|
13 |
+
threshold_img = cv2.adaptiveThreshold(blur,255,1,1,11,2)
|
14 |
+
return threshold_img
|
15 |
+
|
16 |
+
def main_outline(contour):
|
17 |
+
biggest = np.array([])
|
18 |
+
max_area = 0
|
19 |
+
for i in contour:
|
20 |
+
area = cv2.contourArea(i)
|
21 |
+
if area >50:
|
22 |
+
peri = cv2.arcLength(i, True)
|
23 |
+
approx = cv2.approxPolyDP(i , 0.02* peri, True)
|
24 |
+
if area > max_area and len(approx) ==4:
|
25 |
+
biggest = approx
|
26 |
+
max_area = area
|
27 |
+
return biggest ,max_area
|
28 |
+
|
29 |
+
def reframe(points):
|
30 |
+
points = points.reshape((4, 2))
|
31 |
+
points_new = np.zeros((4,1,2),dtype = np.int32)
|
32 |
+
add = points.sum(1)
|
33 |
+
points_new[0] = points[np.argmin(add)]
|
34 |
+
points_new[3] = points[np.argmax(add)]
|
35 |
+
diff = np.diff(points, axis =1)
|
36 |
+
points_new[1] = points[np.argmin(diff)]
|
37 |
+
points_new[2] = points[np.argmax(diff)]
|
38 |
+
return points_new
|
39 |
+
|
40 |
+
def splitcells(img):
|
41 |
+
rows = np.vsplit(img,9)
|
42 |
+
boxes = []
|
43 |
+
for r in rows:
|
44 |
+
cols = np.hsplit(r,9)
|
45 |
+
for box in cols:
|
46 |
+
boxes.append(box)
|
47 |
+
return boxes
|
48 |
+
|
49 |
+
def CropCell(cells):
|
50 |
+
Cells_croped = []
|
51 |
+
for image in cells:
|
52 |
+
|
53 |
+
img = np.array(image)
|
54 |
+
img = img[4:46, 6:46]
|
55 |
+
img = Image.fromarray(img)
|
56 |
+
Cells_croped.append(img)
|
57 |
+
|
58 |
+
return Cells_croped
|
59 |
+
|
60 |
+
def read_cells(cell,model):
|
61 |
+
|
62 |
+
result = []
|
63 |
+
for image in cell:
|
64 |
+
# preprocess the image as it was in the model
|
65 |
+
img = np.asarray(image)
|
66 |
+
img = img[4:img.shape[0] - 4, 4:img.shape[1] -4]
|
67 |
+
img = cv2.resize(img, (32, 32))
|
68 |
+
img = img / 255
|
69 |
+
img = img.reshape(1, 32, 32, 1)
|
70 |
+
# getting predictions and setting the values if probabilities are above 65%
|
71 |
+
|
72 |
+
predictions = model.predict(img)
|
73 |
+
classIndex = model.predict_classes(img)
|
74 |
+
probabilityValue = np.amax(predictions)
|
75 |
+
|
76 |
+
if probabilityValue > 0.65:
|
77 |
+
result.append(classIndex[0])
|
78 |
+
else:
|
79 |
+
result.append(0)
|
80 |
+
return result
|
81 |
+
|
82 |
+
#This function finds the next box to solve
|
83 |
+
|
84 |
+
def next_box(quiz):
|
85 |
+
for row in range(9):
|
86 |
+
for col in range(9):
|
87 |
+
if quiz[row][col] == 0:
|
88 |
+
return (row, col)
|
89 |
+
return False
|
90 |
+
|
91 |
+
#Function to fill in the possible values by evaluating rows collumns and smaller cells
|
92 |
+
|
93 |
+
def possible (quiz,row, col, n):
|
94 |
+
#global quiz
|
95 |
+
for i in range (0,9):
|
96 |
+
if quiz[row][i] == n and row != i:
|
97 |
+
return False
|
98 |
+
for i in range (0,9):
|
99 |
+
if quiz[i][col] == n and col != i:
|
100 |
+
return False
|
101 |
+
|
102 |
+
row0 = (row)//3
|
103 |
+
col0 = (col)//3
|
104 |
+
for i in range(row0*3, row0*3 + 3):
|
105 |
+
for j in range(col0*3, col0*3 + 3):
|
106 |
+
if quiz[i][j]==n and (i,j) != (row, col):
|
107 |
+
return False
|
108 |
+
return True
|
109 |
+
|
110 |
+
#Recursion function to loop over untill a valid answer is found.
|
111 |
+
|
112 |
+
def solve(quiz):
|
113 |
+
val = next_box(quiz)
|
114 |
+
if val is False:
|
115 |
+
return True
|
116 |
+
else:
|
117 |
+
row, col = val
|
118 |
+
for n in range(1,10): #n is the possible solution
|
119 |
+
if possible(quiz,row, col, n):
|
120 |
+
quiz[row][col]=n
|
121 |
+
if solve(quiz):
|
122 |
+
return True
|
123 |
+
else:
|
124 |
+
quiz[row][col]=0
|
125 |
+
return
|
126 |
+
|
127 |
+
def Solved(quiz):
|
128 |
+
for row in range(9):
|
129 |
+
if row % 3 == 0 and row != 0:
|
130 |
+
print("....................")
|
131 |
+
|
132 |
+
for col in range(9):
|
133 |
+
if col % 3 == 0 and col != 0:
|
134 |
+
print("|", end=" ")
|
135 |
+
|
136 |
+
if col == 8:
|
137 |
+
print(quiz[row][col])
|
138 |
+
else:
|
139 |
+
print(str(quiz[row][col]) + " ", end="")
|
140 |
+
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
def main():
|
145 |
st.title('Sudoku Solver')
|
146 |
|