Spaces:
Sleeping
Sleeping
mertbozkurt
commited on
Commit
·
3b213d5
1
Parent(s):
0284357
Add application file
Browse files- Dockerfile +0 -3
- __pycache__/application.cpython-312.pyc +0 -0
- __pycache__/fastapi-den.cpython-312.pyc +0 -0
- __pycache__/functions.cpython-312.pyc +0 -0
- answers/test1-1.txt +25 -0
- answers/test1-2.txt +25 -0
- answers/test1-3.txt +25 -0
- answers/test1-4.txt +25 -0
- application.py +193 -0
- fastapi-den.py +59 -0
- functions.py +202 -0
- requirements.txt +48 -0
- test/test1.1.PNG +0 -0
- test/test1.jpeg +0 -0
- uploads/WhatsApp Image 2024-05-11 at 10.25.43.jpeg +0 -0
- uploads/test1.1.PNG +0 -0
Dockerfile
CHANGED
@@ -10,7 +10,4 @@ WORKDIR /
|
|
10 |
# Install requirements.txt
|
11 |
RUN pip install --no-cache-dir --upgrade -r /requirements.txt
|
12 |
|
13 |
-
# Start the FastAPI app on port 7860, the default port expected by Spaces
|
14 |
-
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
15 |
-
|
16 |
CMD ["uvicorn", "fastapi-den:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
10 |
# Install requirements.txt
|
11 |
RUN pip install --no-cache-dir --upgrade -r /requirements.txt
|
12 |
|
|
|
|
|
|
|
13 |
CMD ["uvicorn", "fastapi-den:app", "--host", "0.0.0.0", "--port", "7860"]
|
__pycache__/application.cpython-312.pyc
ADDED
Binary file (8.75 kB). View file
|
|
__pycache__/fastapi-den.cpython-312.pyc
ADDED
Binary file (2.7 kB). View file
|
|
__pycache__/functions.cpython-312.pyc
ADDED
Binary file (8.25 kB). View file
|
|
answers/test1-1.txt
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
1 a
|
2 |
+
2 b
|
3 |
+
3 c
|
4 |
+
4 d
|
5 |
+
5 e
|
6 |
+
6 d
|
7 |
+
7 c
|
8 |
+
8 b
|
9 |
+
9 a
|
10 |
+
10 b
|
11 |
+
11 c
|
12 |
+
12 d
|
13 |
+
13 e
|
14 |
+
14 d
|
15 |
+
15 c
|
16 |
+
16 b
|
17 |
+
17 a
|
18 |
+
18 b
|
19 |
+
19 c
|
20 |
+
20 d
|
21 |
+
21 e
|
22 |
+
22 d
|
23 |
+
23 c
|
24 |
+
24 b
|
25 |
+
25 a
|
answers/test1-2.txt
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
1 b
|
2 |
+
2 c
|
3 |
+
3 d
|
4 |
+
4 e
|
5 |
+
5 d
|
6 |
+
6 c
|
7 |
+
7 b
|
8 |
+
8 a
|
9 |
+
9 b
|
10 |
+
10 c
|
11 |
+
11 d
|
12 |
+
12 e
|
13 |
+
13 d
|
14 |
+
14 c
|
15 |
+
15 b
|
16 |
+
16 a
|
17 |
+
17 b
|
18 |
+
18 c
|
19 |
+
19 d
|
20 |
+
20 e
|
21 |
+
21 d
|
22 |
+
22 c
|
23 |
+
23 b
|
24 |
+
24 a
|
25 |
+
25 b
|
answers/test1-3.txt
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
1 c
|
2 |
+
2 d
|
3 |
+
3 e
|
4 |
+
4 d
|
5 |
+
5 c
|
6 |
+
6 b
|
7 |
+
7 c
|
8 |
+
8 d
|
9 |
+
9 e
|
10 |
+
10 d
|
11 |
+
11 c
|
12 |
+
12 b
|
13 |
+
13 a
|
14 |
+
14 b
|
15 |
+
15 c
|
16 |
+
16 d
|
17 |
+
17 e
|
18 |
+
18 d
|
19 |
+
19 c
|
20 |
+
20 b
|
21 |
+
21 a
|
22 |
+
22 b
|
23 |
+
23 c
|
24 |
+
24 d
|
25 |
+
25 e
|
answers/test1-4.txt
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
1 a
|
2 |
+
2 b
|
3 |
+
3 c
|
4 |
+
4 d
|
5 |
+
5 e
|
6 |
+
6 d
|
7 |
+
7 c
|
8 |
+
8 b
|
9 |
+
9 a
|
10 |
+
10 b
|
11 |
+
11 c
|
12 |
+
12 d
|
13 |
+
13 e
|
14 |
+
14 d
|
15 |
+
15 c
|
16 |
+
16 b
|
17 |
+
17 a
|
18 |
+
18 b
|
19 |
+
19 c
|
20 |
+
20 d
|
21 |
+
21 e
|
22 |
+
22 d
|
23 |
+
23 c
|
24 |
+
24 b
|
25 |
+
25 a
|
application.py
ADDED
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2
|
2 |
+
import numpy as np
|
3 |
+
import functions
|
4 |
+
import json
|
5 |
+
#fotograf ozellikleri
|
6 |
+
heightImg = 300*4
|
7 |
+
widthImg = 210*4
|
8 |
+
#pathImage = "denemeler/100luk_numarali.jpg"
|
9 |
+
questions=25
|
10 |
+
choices=6
|
11 |
+
|
12 |
+
a1 = functions.read_answers("answers/test1-1.txt")
|
13 |
+
a2 = functions.answers2numbers(a1)
|
14 |
+
|
15 |
+
|
16 |
+
a3 = functions.read_answers("answers/test1-2.txt")
|
17 |
+
a4 = functions.answers2numbers(a3)
|
18 |
+
|
19 |
+
|
20 |
+
a5 = functions.read_answers("answers/test1-3.txt")
|
21 |
+
a6 = functions.answers2numbers(a5)
|
22 |
+
|
23 |
+
|
24 |
+
a7 = functions.read_answers("answers/test1-4.txt")
|
25 |
+
a8 = functions.answers2numbers(a7)
|
26 |
+
|
27 |
+
def optic1(ans_txt1,ans_txt2,ans_txt3,ans_txt4,pathImage, save_images= True):
|
28 |
+
#cevap anahtarini dosyadan okuma ve sayiya cevirme
|
29 |
+
|
30 |
+
ans_1 = ans_txt1
|
31 |
+
ans_2 = ans_txt2
|
32 |
+
ans_3 = ans_txt3
|
33 |
+
ans_4 = ans_txt4
|
34 |
+
|
35 |
+
#perspektif islemleri icin cozunurluk
|
36 |
+
wrap_h = 18*20
|
37 |
+
wrap_v = 18*20
|
38 |
+
#img = pathImage #eger girdi dogrudan np arrayse
|
39 |
+
#fotonun okunmasi ------------------------------------------------------------------------------------------------
|
40 |
+
img = cv2.imread(pathImage)
|
41 |
+
#img = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
|
42 |
+
"""cv2.imshow("Image", img)
|
43 |
+
cv2.waitKey(0)"""
|
44 |
+
img = cv2.resize(img, (widthImg, heightImg)) # RESIZE IMAGE
|
45 |
+
imgBiggestContour = img.copy()
|
46 |
+
imgFinal = img.copy()
|
47 |
+
imgContours = img.copy()
|
48 |
+
imgBlank = np.zeros((heightImg,widthImg, 3), np.uint8)
|
49 |
+
|
50 |
+
#donusumler---------------------------------------------------------------------------------
|
51 |
+
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # CONVERT IMAGE TO GRAY SCALE
|
52 |
+
imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1) # ADD GAUSSIAN BLUR
|
53 |
+
imgCanny = cv2.Canny(imgBlur,10,70) # APPLY CANNY
|
54 |
+
|
55 |
+
#CONTOURS-------------------------------------------------------
|
56 |
+
contours, hierarchy = cv2.findContours(imgCanny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
|
57 |
+
cv2.drawContours(imgContours, contours, -1, (0, 255, 0), 10) # DRAW ALL DETECTED CONTOURS
|
58 |
+
|
59 |
+
#dortgen bulma--------------------------------------------------
|
60 |
+
rectCon = functions.rectContour(contours)
|
61 |
+
"""rectCon_np = rectCon[0].astype(np.uint8)
|
62 |
+
cv2.imshow("Image", rectCon_np)"""
|
63 |
+
biggestContour = functions.getCornerPoints(rectCon[0])
|
64 |
+
secondContour = functions.getCornerPoints(rectCon[1])
|
65 |
+
thirdContour = functions.getCornerPoints(rectCon[2])
|
66 |
+
#fourthContour = functions.getCornerPoints(rectCon[3])
|
67 |
+
|
68 |
+
#main
|
69 |
+
if biggestContour.size != 0 and secondContour.size != 0:
|
70 |
+
|
71 |
+
cv2.drawContours(imgBiggestContour, biggestContour,-1,(0,255,0),20)
|
72 |
+
cv2.drawContours(imgBiggestContour, secondContour,-1,(255,0,0),20) #sondk' kalinlik ortada renk
|
73 |
+
cv2.drawContours(imgBiggestContour, thirdContour,-1,(0,0,255),20) #sondk' kalinlik ortada renk
|
74 |
+
#cv2.drawContours(imgBiggestContour, fourthContour,-1,(0,0,20),20) #sondk' kalinlik ortada renk
|
75 |
+
|
76 |
+
biggestContour=functions.reorder(biggestContour)
|
77 |
+
#cevap siklari icin -************************************************************
|
78 |
+
pts1 = np.float32(biggestContour)
|
79 |
+
pts2 = np.float32([[0, 0],[wrap_v, 0], [0, wrap_h],[wrap_v, wrap_h]])
|
80 |
+
matrix = cv2.getPerspectiveTransform(pts1, pts2)
|
81 |
+
|
82 |
+
imgWarpColored_1 = cv2.warpPerspective(img, matrix, (wrap_v, wrap_h))
|
83 |
+
imgWarpGray_1 = cv2.cvtColor(imgWarpColored_1,cv2.COLOR_BGR2GRAY)
|
84 |
+
imgThresh_1 = cv2.threshold(imgWarpGray_1,0,255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
|
85 |
+
|
86 |
+
#second buyuk icin perspektif
|
87 |
+
secondContour=functions.reorder(secondContour)
|
88 |
+
pts1_2 = np.float32(secondContour)
|
89 |
+
pts2_2 = np.float32([[0, 0],[wrap_v, 0], [0, wrap_h],[wrap_v, wrap_h]])
|
90 |
+
matrix_2 = cv2.getPerspectiveTransform(pts1_2, pts2_2)
|
91 |
+
imgWarpColored_2 = cv2.warpPerspective(img, matrix_2, (wrap_v, wrap_h))
|
92 |
+
imgWarpGray_2 = cv2.cvtColor(imgWarpColored_2,cv2.COLOR_BGR2GRAY)
|
93 |
+
#imgThresh_2 = cv2.threshold(imgWarpGray_2, 170, 255,cv2.THRESH_BINARY_INV )[1]
|
94 |
+
imgThresh_2 = cv2.threshold(imgWarpGray_2,0,255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
|
95 |
+
|
96 |
+
#student id
|
97 |
+
bubbles = functions.split_num(imgThresh_2, 10, 10)
|
98 |
+
myPixelVal_2 = functions.pixelVal(10,10,bubbles)
|
99 |
+
myPixelVal_2 = functions.id_reorder(myPixelVal_2)
|
100 |
+
student_id = functions.id_answers(10,myPixelVal_2)
|
101 |
+
#print(student_id)
|
102 |
+
|
103 |
+
#soru kisimi
|
104 |
+
column_3 = functions.splitColumn(imgThresh_1)
|
105 |
+
boxes_1 = functions.splitBoxes(column_3[0])
|
106 |
+
boxes_2 = functions.splitBoxes(column_3[1])
|
107 |
+
boxes_3 = functions.splitBoxes(column_3[2])
|
108 |
+
boxes_4 = functions.splitBoxes(column_3[3])
|
109 |
+
|
110 |
+
#boxes_1
|
111 |
+
myPixelVal_1 = functions.pixelVal(questions,choices,boxes_1)
|
112 |
+
for sublist in myPixelVal_1:
|
113 |
+
if sublist.any(): # Alt liste boş değilse
|
114 |
+
sublist[0] = 0
|
115 |
+
|
116 |
+
|
117 |
+
myIndex_1 = functions.user_answers(questions,myPixelVal_1)
|
118 |
+
grading_1, wrong_ans_1, empty_1 = functions.grading(ans_1,questions,myIndex_1)
|
119 |
+
|
120 |
+
#boxes_2
|
121 |
+
myPixelVal_2 = functions.pixelVal(questions,choices,boxes_2)
|
122 |
+
myIndex_2 = functions.user_answers(questions,myPixelVal_2)
|
123 |
+
grading_2, wrong_ans_2, empty_2 = functions.grading(ans_2,questions,myIndex_2)
|
124 |
+
|
125 |
+
#boxes_3
|
126 |
+
myPixelVal_3 = functions.pixelVal(questions,choices,boxes_3)
|
127 |
+
myIndex_3 = functions.user_answers(questions,myPixelVal_3)
|
128 |
+
grading_3, wrong_ans_3 ,empty_3 = functions.grading(ans_3,questions,myIndex_3)
|
129 |
+
|
130 |
+
#boxes_3
|
131 |
+
myPixelVal_4 = functions.pixelVal(questions,choices,boxes_4)
|
132 |
+
myIndex_4 = functions.user_answers(questions,myPixelVal_4)
|
133 |
+
grading_4, wrong_ans_4 ,empty_4 = functions.grading(ans_4,questions,myIndex_4)
|
134 |
+
|
135 |
+
resim_listesi = [img,imgGray,imgBlur,imgCanny,imgContours,imgBiggestContour,imgThresh_1,imgThresh_2]
|
136 |
+
student_idFix = ""
|
137 |
+
for number in student_id:
|
138 |
+
|
139 |
+
student_idFix += str(number)
|
140 |
+
if save_images:
|
141 |
+
for i in range(0,len(resim_listesi)):
|
142 |
+
cv2.imwrite(f"images/{student_idFix}___{i}.jpg",resim_listesi[i])
|
143 |
+
|
144 |
+
|
145 |
+
grading = [grading_1,grading_2,grading_3,grading_4]
|
146 |
+
wrong_ans = [wrong_ans_1,wrong_ans_2,wrong_ans_3,wrong_ans_4]
|
147 |
+
empty = [empty_1,empty_2,empty_3,empty_4]
|
148 |
+
myIndexs = [myIndex_1,myIndex_2,myIndex_3,myIndex_4]
|
149 |
+
|
150 |
+
# Convert variables to NumPy arrays if they are not already
|
151 |
+
grading_1 = np.array(grading_1)
|
152 |
+
grading_2 = np.array(grading_2)
|
153 |
+
grading_3 = np.array(grading_3)
|
154 |
+
grading_4 = np.array(grading_4)
|
155 |
+
|
156 |
+
# Convert tolist() only if variables are NumPy arrays
|
157 |
+
grading = [grading_1.tolist(), grading_2.tolist(), grading_3.tolist(), grading_4.tolist()]
|
158 |
+
|
159 |
+
wrong_ans_1 = np.array(wrong_ans_1)
|
160 |
+
wrong_ans_2 = np.array(wrong_ans_2)
|
161 |
+
wrong_ans_3 = np.array(wrong_ans_3)
|
162 |
+
wrong_ans_4 = np.array(wrong_ans_4)
|
163 |
+
|
164 |
+
wrong_ans = [wrong_ans_1.tolist(), wrong_ans_2.tolist(), wrong_ans_3.tolist(), wrong_ans_4.tolist()]
|
165 |
+
|
166 |
+
empty_1 = np.array(empty_1)
|
167 |
+
empty_2 = np.array(empty_2)
|
168 |
+
empty_3 = np.array(empty_3)
|
169 |
+
empty_4 = np.array(empty_4)
|
170 |
+
|
171 |
+
empty = [empty_1.tolist(), empty_2.tolist(), empty_3.tolist(), empty_4.tolist()]
|
172 |
+
|
173 |
+
# Similarly, apply the same conversion for other lists like wrong_ans, empty, and myIndexs
|
174 |
+
|
175 |
+
# Verileri bir sözlükte topla
|
176 |
+
data = {"student_id": student_idFix,"grading": grading,"wrong_ans": wrong_ans, "empty": empty}
|
177 |
+
|
178 |
+
# JSON formatına dönüştür ve ekrana yazdır
|
179 |
+
json_data = json.dumps(data, indent=4)
|
180 |
+
json_data = json.loads(json_data)
|
181 |
+
print(json_data)
|
182 |
+
return json_data
|
183 |
+
|
184 |
+
"""json_data = optic1(ans_txt1=a2,
|
185 |
+
ans_txt2=a4,
|
186 |
+
ans_txt3=a6,
|
187 |
+
ans_txt4=a8,
|
188 |
+
pathImage="test/test1.1.PNG",
|
189 |
+
save_images=True
|
190 |
+
)"""
|
191 |
+
"""json_data = json.loads(json_data)
|
192 |
+
a = json_data["grading"]
|
193 |
+
print(a)"""
|
fastapi-den.py
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI, UploadFile, File
|
2 |
+
from fastapi.responses import JSONResponse
|
3 |
+
import shutil
|
4 |
+
import os
|
5 |
+
import application
|
6 |
+
import functions
|
7 |
+
#fotograf ozellikleri
|
8 |
+
heightImg = 300*4
|
9 |
+
widthImg = 210*4
|
10 |
+
#pathImage = "denemeler/100luk_numarali.jpg"
|
11 |
+
questions=25
|
12 |
+
choices=6
|
13 |
+
|
14 |
+
a1 = functions.read_answers("answers/test1-1.txt")
|
15 |
+
a2 = functions.answers2numbers(a1)
|
16 |
+
|
17 |
+
|
18 |
+
a3 = functions.read_answers("answers/test1-2.txt")
|
19 |
+
a4 = functions.answers2numbers(a3)
|
20 |
+
|
21 |
+
|
22 |
+
a5 = functions.read_answers("answers/test1-3.txt")
|
23 |
+
a6 = functions.answers2numbers(a5)
|
24 |
+
|
25 |
+
|
26 |
+
a7 = functions.read_answers("answers/test1-4.txt")
|
27 |
+
a8 = functions.answers2numbers(a7)
|
28 |
+
|
29 |
+
app = FastAPI()
|
30 |
+
|
31 |
+
# Upload endpoint
|
32 |
+
@app.post("/upload/")
|
33 |
+
async def upload_image(image: UploadFile = File(...)):
|
34 |
+
try:
|
35 |
+
# Upload received file to a directory
|
36 |
+
upload_dir = "uploads"
|
37 |
+
os.makedirs(upload_dir, exist_ok=True)
|
38 |
+
with open(os.path.join(upload_dir, image.filename), "wb") as buffer:
|
39 |
+
shutil.copyfileobj(image.file, buffer)
|
40 |
+
|
41 |
+
# Process the uploaded image (you can replace this with your processing function)
|
42 |
+
result = application.optic1(ans_txt1=a2,
|
43 |
+
ans_txt2=a4,
|
44 |
+
ans_txt3=a6,
|
45 |
+
ans_txt4=a8,
|
46 |
+
pathImage= os.path.join(upload_dir, image.filename),
|
47 |
+
|
48 |
+
)
|
49 |
+
print(os.path.join(upload_dir, image.filename))
|
50 |
+
# Return result as JSON
|
51 |
+
return JSONResponse(content=result)
|
52 |
+
except Exception as e:
|
53 |
+
return JSONResponse(content={"error": str(e)})
|
54 |
+
|
55 |
+
|
56 |
+
|
57 |
+
if __name__ == "__main__":
|
58 |
+
import uvicorn
|
59 |
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
functions.py
ADDED
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2
|
2 |
+
import numpy as np
|
3 |
+
|
4 |
+
def rectContour(contours):
|
5 |
+
rectCon = []
|
6 |
+
for i in contours:
|
7 |
+
area = cv2.contourArea(i) #alan hesabi
|
8 |
+
#piksel alani 50den byukse gecerlidir
|
9 |
+
if area > 30:
|
10 |
+
peri = cv2.arcLength(i, True)
|
11 |
+
approx = cv2.approxPolyDP(i, 0.02 * peri, True) #kac tane koseye sahip oldugu
|
12 |
+
if len(approx) == 4: #4 ise dortgendir
|
13 |
+
rectCon.append(i)
|
14 |
+
rectCon = sorted(rectCon, key=cv2.contourArea,reverse=True) #alanlari hesaplicak ve siralicak ki ona gore alanlari belirleyelim
|
15 |
+
#print(len(rectCon))
|
16 |
+
return rectCon
|
17 |
+
|
18 |
+
def getCornerPoints(cont):
|
19 |
+
peri = cv2.arcLength(cont, True)
|
20 |
+
approx = cv2.approxPolyDP(cont, 0.02 * peri, True) #kose degerleri
|
21 |
+
return approx
|
22 |
+
|
23 |
+
|
24 |
+
def reorder(myPoints):
|
25 |
+
|
26 |
+
myPoints = myPoints.reshape((4, 2)) #fazla koseliyi kaldiralim
|
27 |
+
#print(myPoints)
|
28 |
+
myPointsNew = np.zeros((4, 1, 2), np.int32)
|
29 |
+
add = myPoints.sum(1)
|
30 |
+
#print(add)
|
31 |
+
#print(np.argmax(add))
|
32 |
+
myPointsNew[0] = myPoints[np.argmin(add)] #[0,0]
|
33 |
+
myPointsNew[3] =myPoints[np.argmax(add)] #[w,h]
|
34 |
+
diff = np.diff(myPoints, axis=1)
|
35 |
+
myPointsNew[1] =myPoints[np.argmin(diff)] #[w,0]
|
36 |
+
myPointsNew[2] = myPoints[np.argmax(diff)] #[h,0]
|
37 |
+
|
38 |
+
return myPointsNew
|
39 |
+
|
40 |
+
#siklari bolmek icin 20 tane soru vertical/ 5 tane isaret alani +1 tane soru sayisi yazan yer
|
41 |
+
#6 horizatanl bolmek
|
42 |
+
def splitBoxes(img):
|
43 |
+
# Bölme işlemi yapmadan önce boyutları eşit olacak şekilde ayarlayın
|
44 |
+
|
45 |
+
img = img[5:]
|
46 |
+
if img.shape[0] % 25 != 0:
|
47 |
+
img = img[:-(img.shape[0] % 25), :]
|
48 |
+
rows = np.vsplit(img,25) #vertical
|
49 |
+
boxes=[]
|
50 |
+
for r in rows:
|
51 |
+
cols= np.hsplit(r,6) #horizantal
|
52 |
+
|
53 |
+
for box in cols:
|
54 |
+
boxes.append(box)
|
55 |
+
"""cv2.imshow(" s",box)
|
56 |
+
cv2.waitKey(0)"""
|
57 |
+
return boxes
|
58 |
+
|
59 |
+
#ogrenci numarasi alani icin ayni fonksiyonu kullandik
|
60 |
+
#yuakrdakisini silip sadece bu da kullanilabilir dogru degerler ile
|
61 |
+
#ogrenci numarasi alani 0-9 arasi sayilardan 10 tane isaretleme yeri iceriyor
|
62 |
+
#10x10seklinde boleriz
|
63 |
+
def split_num(img,vertical, horizantal):
|
64 |
+
rows = np.vsplit(img,vertical) #vertical
|
65 |
+
boxes=[]
|
66 |
+
for r in rows:
|
67 |
+
cols= np.hsplit(r,horizantal) #horizantal
|
68 |
+
for box in cols:
|
69 |
+
boxes.append(box)
|
70 |
+
return boxes
|
71 |
+
|
72 |
+
#yan yana 3 tane birlesik ders alani oldugu icin onlari 3 ayri
|
73 |
+
#sekle getiriyor
|
74 |
+
def splitColumn(img):
|
75 |
+
column = np.hsplit(img,4)
|
76 |
+
|
77 |
+
return column
|
78 |
+
|
79 |
+
|
80 |
+
#puan hesaplama alani
|
81 |
+
#soru sayisi dogru cevaplari ve ogrenci cevaplarini aliyor
|
82 |
+
#bunlari karsilastirip yeni bir listeye 1/0 seklinde kodluyor
|
83 |
+
#1ler toplanip puan hesaplanmis oluyor
|
84 |
+
def grading(answers,num_questions,myAnswers):
|
85 |
+
grading=[]
|
86 |
+
wrong_ans = []
|
87 |
+
empty = []
|
88 |
+
|
89 |
+
for x in range(0,num_questions):
|
90 |
+
if answers[x] == myAnswers[x]:
|
91 |
+
grading.append(1)
|
92 |
+
|
93 |
+
elif myAnswers[x] == -1:
|
94 |
+
grading.append(0)
|
95 |
+
wrong_ans.append(x+1)
|
96 |
+
|
97 |
+
elif myAnswers[x] == 0:
|
98 |
+
empty.append(x+1)
|
99 |
+
|
100 |
+
else:
|
101 |
+
grading.append(0)
|
102 |
+
wrong_ans.append(x+1)
|
103 |
+
|
104 |
+
|
105 |
+
score = (sum(grading)/num_questions)*100
|
106 |
+
return score ,wrong_ans,empty
|
107 |
+
|
108 |
+
#piksel degerlerinde kullanici cevaplarini
|
109 |
+
#okuyupu index seklinde listeye kaydediyor
|
110 |
+
def user_answers(num_questions,myPixelVal):
|
111 |
+
myIndex=[]
|
112 |
+
|
113 |
+
for x in range (0,num_questions):
|
114 |
+
arr = myPixelVal[x]
|
115 |
+
t =70.0
|
116 |
+
#empty answers
|
117 |
+
if arr[1] < t and arr[2] < t and arr[3] < t and arr[4] < t and arr[5] < t:
|
118 |
+
|
119 |
+
myIndex.append(0)
|
120 |
+
|
121 |
+
#2 or more answers
|
122 |
+
elif (arr[1]>t and arr[2]>t) or ( arr[1]>t and arr[3]>t) or (arr[1]>t and arr[4]>t) or (arr[1]>t and arr[5]> t) or (arr[2]>t and arr[3]> t) or (arr[2]>t and arr[4]> t) or (arr[2]>t and arr[5]> t) or (arr[3]>t and arr[4]> t) or (arr[3]>t and arr[5]> t) or (arr[4]>t and arr[5]>t) :
|
123 |
+
myIndex.append(-1)
|
124 |
+
|
125 |
+
else :
|
126 |
+
myIndexVal = np.where(arr == np.amax(arr))
|
127 |
+
myIndex.append(myIndexVal[0][0])
|
128 |
+
print(myIndex)
|
129 |
+
return myIndex
|
130 |
+
|
131 |
+
#student id kismi yukardan asagiya dogru karsilastirma yaparak
|
132 |
+
#isretli alan tespit edilecegi icin satir ve sutunlari tekrar duzenlemiz gerekti
|
133 |
+
#[[1,2,3],[4,5,6],[7,8,9]] ----> [[1,4,7],[2,5,8],[3,6,9]]
|
134 |
+
def id_reorder(myPixelVal):
|
135 |
+
duz_liste = []
|
136 |
+
for sutun in range(len(myPixelVal[0])):
|
137 |
+
for satir in range(len(myPixelVal)):
|
138 |
+
duz_liste.append(myPixelVal[satir][sutun])
|
139 |
+
yeni_liste = []
|
140 |
+
satir = []
|
141 |
+
for eleman in duz_liste:
|
142 |
+
satir.append(eleman)
|
143 |
+
if len(satir) == len(myPixelVal):
|
144 |
+
yeni_liste.append(satir)
|
145 |
+
satir = []
|
146 |
+
return yeni_liste
|
147 |
+
|
148 |
+
#ogrenci numarasi kisminin piksel degerine gore hangisinin iseretli
|
149 |
+
#oldugunun tespiti
|
150 |
+
def id_answers(vertical_num,myPixelVal):
|
151 |
+
myIndex=[]
|
152 |
+
for x in range (0,vertical_num):
|
153 |
+
arr = myPixelVal[x]
|
154 |
+
myIndexVal = np.where(arr == np.amax(arr))
|
155 |
+
myIndex.append(myIndexVal[0][0])
|
156 |
+
return myIndex
|
157 |
+
|
158 |
+
def pixelVal(num_questions,choices,box):
|
159 |
+
countR=0 #rows
|
160 |
+
countC=0 #column
|
161 |
+
myPixelVal = np.zeros((num_questions,choices))
|
162 |
+
for image in box:
|
163 |
+
totalPixels = cv2.countNonZero(image)
|
164 |
+
myPixelVal[countR][countC]= totalPixels
|
165 |
+
countC += 1
|
166 |
+
if (countC==choices):countC=0;countR +=1
|
167 |
+
return myPixelVal
|
168 |
+
|
169 |
+
#dosyadan cevap anahtarinin okunmasi
|
170 |
+
def read_answers(dosya_adi):
|
171 |
+
with open(dosya_adi, 'r') as f:
|
172 |
+
satirlar = f.readlines()
|
173 |
+
|
174 |
+
okunan_veriler = []
|
175 |
+
for satir in satirlar:
|
176 |
+
sutunlar = satir.split()
|
177 |
+
okunan_veriler.append(sutunlar[1])
|
178 |
+
|
179 |
+
return okunan_veriler
|
180 |
+
|
181 |
+
|
182 |
+
#dosyadan okunan cevaplarin numerik hale getirilmesi
|
183 |
+
def answers2numbers(answers):
|
184 |
+
num_answers = []
|
185 |
+
for i in answers:
|
186 |
+
if i == "a":
|
187 |
+
num_answers.append(1)
|
188 |
+
elif i == "b":
|
189 |
+
num_answers.append(2)
|
190 |
+
elif i == "c":
|
191 |
+
num_answers.append(3)
|
192 |
+
elif i == "d":
|
193 |
+
num_answers.append(4)
|
194 |
+
elif i == "e":
|
195 |
+
num_answers.append(5)
|
196 |
+
else:
|
197 |
+
print("Oppss Check Txt file")
|
198 |
+
return num_answers
|
199 |
+
|
200 |
+
|
201 |
+
|
202 |
+
|
requirements.txt
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
annotated-types==0.6.0
|
2 |
+
anyio==4.3.0
|
3 |
+
certifi==2024.2.2
|
4 |
+
click==8.1.7
|
5 |
+
colorama==0.4.6
|
6 |
+
dnspython==2.6.1
|
7 |
+
email_validator==2.1.1
|
8 |
+
fastapi==0.111.0
|
9 |
+
fastapi-cli==0.0.3
|
10 |
+
h11==0.14.0
|
11 |
+
httpcore==1.0.5
|
12 |
+
httptools==0.6.1
|
13 |
+
httpx==0.27.0
|
14 |
+
idna==3.7
|
15 |
+
Jinja2==3.1.4
|
16 |
+
markdown-it-py==3.0.0
|
17 |
+
MarkupSafe==2.1.5
|
18 |
+
mdurl==0.1.2
|
19 |
+
mkl-fft
|
20 |
+
mkl-random
|
21 |
+
mkl-service==2.4.0
|
22 |
+
numpy
|
23 |
+
opencv-python==4.9.0.80
|
24 |
+
orjson==3.10.3
|
25 |
+
pandas==2.2.2
|
26 |
+
pillow==10.3.0
|
27 |
+
pydantic==2.7.1
|
28 |
+
pydantic_core==2.18.2
|
29 |
+
Pygments==2.18.0
|
30 |
+
python-dateutil==2.9.0.post0
|
31 |
+
python-dotenv==1.0.1
|
32 |
+
python-multipart==0.0.9
|
33 |
+
pytz==2024.1
|
34 |
+
PyYAML==6.0.1
|
35 |
+
rich==13.7.1
|
36 |
+
setuptools==69.5.1
|
37 |
+
shellingham==1.5.4
|
38 |
+
six==1.16.0
|
39 |
+
sniffio==1.3.1
|
40 |
+
starlette==0.37.2
|
41 |
+
typer==0.12.3
|
42 |
+
typing_extensions==4.11.0
|
43 |
+
tzdata==2024.1
|
44 |
+
ujson==5.9.0
|
45 |
+
uvicorn==0.29.0
|
46 |
+
watchfiles==0.21.0
|
47 |
+
websockets==12.0
|
48 |
+
wheel==0.43.0
|
test/test1.1.PNG
ADDED
test/test1.jpeg
ADDED
uploads/WhatsApp Image 2024-05-11 at 10.25.43.jpeg
ADDED
uploads/test1.1.PNG
ADDED