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

move cv into backend directory #75

Merged
merged 7 commits into from
May 6, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 0 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
/.idea/
/.vscode/
/frontend/.vscode/
/cv/testImages/kanti_img1.jpg
/cv/testImages/kanti_img2.jpg
/cv/testImages/kanti_img1.jpeg
/cv/testImages/kanti_img2.jpeg
/cv/testImages/kanti_telegram_compressed_1.jpg
/cv/testImages/kanti_telegram_compressed_2.jpg
/cv/__pycache__/
/cv/Models/__pycache__/
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,11 @@ We should be using virtual environments to not have problems with other versions

1. Download Anaconda for Windows: https://www.anaconda.com/products/distribution#Downloads, add to PATH
2. Run 'conda create --name virtualenv python=3.8'
3. conda activate virtualenv
4. pip install opencv-contrib-python
5. pip3 install torch torchvision torchaudio
6. pip install keras
7. pip install tensorflow
8. pip install imutils
3. pip install -r requirements.txt

To deactivate the virtual environment: 'conda deactivate'

## Use anaconda with vscode

1. Ctrl+Shift+P -> Enter "Python: Select Interpreter"
2. Select the virtualenv you just created.
2. Select the virtualenv you just created.
2 changes: 1 addition & 1 deletion backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

## Start Unit Testing
1. Import all requirements using <code>pip install -r requirements.txt</code>
2. Navigate to the backend/app directory and execute <code>pytest</code>
2. Navigate to the backend/app directory and execute <code>pytest</code>
42 changes: 42 additions & 0 deletions backend/app/app_cv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import cv2
import time
from cv.DigitRecognizer import DigitRecognizer

IMAGEDIR = "cv/testImages/"

images = []

images.append(cv2.imread(IMAGEDIR + "kanti_img1.jpeg"))
images.append(cv2.imread(IMAGEDIR + "kanti_img2.jpeg"))
images.append(cv2.imread(IMAGEDIR + "kanti_telegram_compressed_1.jpg"))
images.append(cv2.imread(IMAGEDIR + "kanti_telegram_compressed_2.jpg"))
images.append(cv2.imread(IMAGEDIR + "straight.jpg"))
images.append(cv2.imread(IMAGEDIR + "perspective.jpg"))
images.append(cv2.imread(IMAGEDIR + "crooked.jpg"))
images.append(cv2.imread(IMAGEDIR + "lighting.jpg"))
images.append(cv2.imread(IMAGEDIR + "mirror.jpg"))
images.append(cv2.imread(IMAGEDIR + "multiple.jpg"))
images.append(cv2.imread(IMAGEDIR + "rug.jpg"))
images.append(cv2.imread(IMAGEDIR + "wavy.jpg"))
images.append(cv2.imread(IMAGEDIR + "weird_bg.jpg"))
images.append(cv2.imread(IMAGEDIR + "crunched.jpg"))


recognizer = DigitRecognizer()

cv_result = recognizer.recognize_digits_in_photo(images[0])

#cv2.imshow('image', image)
for index, image in enumerate(images):
start = time.time()
try:
cv_result = recognizer.recognize_digits_in_photo(image)
print(', '.join([str(exercise.score) for exercise in cv_result.exam.exercises]) + " | Total: " + str(cv_result.exam.score))

print("IMAGE " + str(index+1) + " PASSED")
except Exception as e:
print(e)
print("IMAGE " + str(index+1) + " DID NOT PASS")
pass
end = time.time()
print(end - start)
10 changes: 4 additions & 6 deletions backend/app/core/cv_result.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
class CVResult:
def __init__(self, candidate, exam, result_validated):
def __init__(self, candidate, exam):
self.candidate = candidate
self.exam = exam
self.result_validated = result_validated


class Candidate:
Expand All @@ -12,12 +11,11 @@ def __init__(self, number, date_of_birth):


class Exam:
def __init__(self, year, subject, total_score, total_score_confidence, exercises):
def __init__(self, year, subject, score, confidence, exercises):
self.year = year
self.subject = subject
self.total_score = total_score
#This is the confidence of the total score reached (how many points there are in the total cell)
self.total_score_confidence = total_score_confidence
self.score = score
self.confidence = confidence
self.exercises = exercises

def calc_exercises_score(self):
Expand Down
5 changes: 0 additions & 5 deletions backend/app/core/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
import datetime, os, uuid
from fastapi import UploadFile
from api.schema import BaseResponse, ExamFullResponse

import sys

sys.path.append(sys.path[0] + '/../../')
sys.path.append(sys.path[0] + '/../../cv/')
from cv.DigitRecognizer import DigitRecognizer

from .admin import get_exam_full
Expand Down
8 changes: 8 additions & 0 deletions backend/app/cv/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/cv/testImages/kanti_img1.jpg
/cv/testImages/kanti_img2.jpg
/cv/testImages/kanti_img1.jpeg
/cv/testImages/kanti_img2.jpeg
/cv/testImages/kanti_telegram_compressed_1.jpg
/cv/testImages/kanti_telegram_compressed_2.jpg
/cv/__pycache__/
/cv/Models/__pycache__/
File renamed without changes.
24 changes: 9 additions & 15 deletions cv/DigitRecognizer.py → backend/app/cv/DigitRecognizer.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import cv2
import base64
import numpy as np
from DocumentSegmentationCV import DocumentSegmentationCV
from DocumentSegmentationCNN import DocumentSegmentationCNN
from imutils import contours as imutils_contours
from Models.mobilenet import MobileNet
import Models.utils as utils

import sys
sys.path.append(sys.path[0] + '/..')
from backend.app.core.cv_result import *
from cv.Models.mobilenet import MobileNet
import cv.Models.utils as utils
from cv.DocumentSegmentationCV import DocumentSegmentationCV
from cv.DocumentSegmentationCNN import DocumentSegmentationCNN
import core.cv_result as cv_res

class DigitRecognizer:

Expand Down Expand Up @@ -66,7 +64,7 @@ def recognize_digits_in_photo(self, photo):

model = MobileNet()
model.compile()
model.load_weights('./cv/Models/MobileNet.h5')
model.load_weights('cv/Models/MobileNet.h5')
class_labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

exercises = []
Expand All @@ -93,19 +91,15 @@ def recognize_digits_in_photo(self, photo):

pred_class_label, pred_confidence = self.predict_handwritten_cell(result_cell, class_labels, model)

exercises.append(Exercise(index, pred_class_label, pred_confidence, "?"))
exercises.append(cv_res.Exercise(index, pred_class_label, pred_confidence, 0)) # TODO replace 0 with max_score
elif(index % column_count != 0):
#print("Last Handwritten Cell, 'Total'")

total_score, total_score_confidence = self.predict_double_number(result_cell, class_labels, model)

exam = Exam("?", "?", total_score, total_score_confidence, exercises)
exam = cv_res.Exam(2023, "Mathematik", total_score, total_score_confidence, exercises) # TODO replace year & subject

cv_res = CVResult(Candidate("?", "?"), exam=exam, result_validated=False)

if(exam.total_score == exam.calc_exercises_score()):
cv_res.result_validated = True
return cv_res
return cv_res.CVResult(cv_res.Candidate("NR-123", "2000-12-31"), exam=exam) # TODO replace number & date_of_birth


def predict_double_number(self, original_cell, class_labels, model):
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from keras.utils import plot_model
import Models.utils as utils
from .utils import get_val_generator, get_train_generator

class BaseModel(object):
def __init__(self, model, optimizer, callbacks = None):
Expand Down Expand Up @@ -30,9 +30,9 @@ def fit_generator(self, training_data, validation_data, epochs, batch_size):
x_train, y_train = training_data
x_val, y_val = validation_data

train_datagen = utils.get_train_generator(x_train, y_train,
train_datagen = get_train_generator(x_train, y_train,
batch_size = batch_size)
val_datagen = utils.get_val_generator(x_val, y_val,
val_datagen = get_val_generator(x_val, y_val,
batch_size = batch_size)
hist = self.model.fit_generator(train_datagen,
callbacks = self.callbacks,
Expand Down
5 changes: 2 additions & 3 deletions cv/Models/mobilenet.py → backend/app/cv/Models/mobilenet.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from keras.callbacks import ReduceLROnPlateau
from keras.applications import MobileNet as mobNet
from keras.layers import (Input, Conv2D, BatchNormalization, ZeroPadding2D,
GlobalAveragePooling2D, Activation, Dense, DepthwiseConv2D)
from keras.models import Model
from keras import optimizers
from Models.base_model import BaseModel
from Models.train import train
from .base_model import BaseModel
from .train import train

ALPHA = 1
MODEL_NAME = f'MobileNet' # This should be modified when the model name changes.
Expand Down
4 changes: 2 additions & 2 deletions cv/Models/train.py → backend/app/cv/Models/train.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import argparse
import Models.utils as utils
from .utils import load_mnist

def get_argument_parser(model_name):
'''
Expand Down Expand Up @@ -57,7 +57,7 @@ def train(model, model_name):
# load all arguments
args = get_argument_parser(model_name)

training_data, validation_data, test_data = utils.load_mnist()
training_data, validation_data, test_data = load_mnist()
print(f'[data loaded]')

# build and compile the model
Expand Down
1 change: 0 additions & 1 deletion cv/Models/utils.py → backend/app/cv/Models/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import numpy as np
from collections import defaultdict
from keras.utils import np_utils
from keras.datasets import mnist
from keras.preprocessing.image import ImageDataGenerator
Expand Down
File renamed without changes
File renamed without changes
Binary file added backend/app/cv/testImages/kanti_img1.jpeg
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 backend/app/cv/testImages/kanti_img2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
12 changes: 11 additions & 1 deletion backend/app/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# backend
fastapi==0.95.0
uvicorn==0.21.1
peewee==3.16.0
Expand All @@ -6,4 +7,13 @@ pytest==7.2.2
httpx==0.23.3
asyncio==3.4.3
nest-asyncio==1.5.1
python-multipart==0.0.5
python-multipart==0.0.5

# backend/cv
opencv-contrib-python==4.7.0.72
torch==2.0.0
torchvision==0.15.1
torchaudio==2.0.1
keras==2.12.0
tensorflow==2.12.0
imutils==0.5.4
38 changes: 0 additions & 38 deletions cv/app.py

This file was deleted.

7 changes: 0 additions & 7 deletions cv/requirement.txt

This file was deleted.