Difference between revisions of "PhotoMath - Code"

From RoboWiki
Jump to: navigation, search
(Created page with "Return back to project page: PhotoMath - Jakub Vojtek Python code for the PhotoMath project: <syntaxhighlight lang=python> </syn...")
 
 
Line 3: Line 3:
 
Python code for the PhotoMath project:
 
Python code for the PhotoMath project:
 
<syntaxhighlight lang=python>  
 
<syntaxhighlight lang=python>  
 +
import cv2
 +
import pytesseract
 +
from buildhat import Motor, ForceSensor
 +
import time
 +
import re
 +
import numpy as np
 +
from datetime import datetime
 +
 +
motor_a = Motor('A')
 +
button = ForceSensor('D')
 +
 +
doors_open = True
 +
 +
cam_width = 320
 +
cam_height = 240
 +
camera = cv2.VideoCapture(0)
 +
camera.set(cv2.CAP_PROP_FRAME_WIDTH, cam_width)
 +
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, cam_height)
 +
 +
# Path to Tesseract executable (change this according to your installation)
 +
pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract'
 +
 +
 +
def close_doors(force):
 +
    global doors_open
 +
    if doors_open:
 +
        motor_a.run_for_degrees(720, 10)
 +
        doors_open = False
 +
        time.sleep(3)
 +
        process_and_open_door()
 +
    else:
 +
        pass
 +
 +
button.when_pressed = close_doors
 +
 +
 +
def read_text(image):
 +
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 +
    gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
 +
    text = pytesseract.image_to_string(gray, config='--psm 6')
 +
    return text
 +
 +
 +
def preprocess_expression(expression):
 +
    expression = expression.replace('\n', '').strip()
 +
    expression = re.sub(r'(?<=[^\s\(\)]) (?=[^\s\(\)])', ' ', expression)
 +
    expression = re.sub(r'(?<=[^\s\(\)])[\+\-\*/\(\)](?=[^\s\(\)])', ' \\g<0> ', expression)
 +
    return expression
 +
 +
 +
def validate_expression(expression):
 +
    return re.match(r'^[\d\s\+\-\*/\(\)]+$', expression)
 +
 +
 +
def simple_calculator(expression):
 +
    try:
 +
        result = round(eval(expression), 4)
 +
        return result
 +
    except Exception as e:
 +
        return "Error: {}".format(str(e))
 +
 +
 +
def process_and_open_door():
 +
    global doors_open
 +
    ret, frame = camera.read()
 +
    frame = frame[cam_height // 2 - 45: cam_height - 90, :cam_width - 70]
 +
    text = read_text(frame)
 +
    print("Extracted text:", text.encode('utf-8'))
 +
    expression = preprocess_expression(text)
 +
    if validate_expression(expression):
 +
        result = simple_calculator(expression)
 +
        print("Solution: ", result)
 +
        annotate_and_save_image(frame, text, result)
 +
    else:
 +
        print("Invalid expression")
 +
    motor_a.run_for_degrees(720, 10)  # Open the door again
 +
    doors_open = True
 +
 +
 +
def annotate_and_save_image(image, text, result):
 +
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
 +
    annotated_image = image.copy()
 +
    cv2.putText(annotated_image, f"Text: {text}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
 +
    cv2.putText(annotated_image, f"Result: {result}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
 +
    filename = f"equation_{timestamp}.png"
 +
    cv2.imwrite(filename, annotated_image)
 +
    print(f"Saved image: {filename}")
 +
 +
 +
if __name__ == '__main__':
 +
    while True:
 +
        ret, frame = camera.read()
 +
 +
        frame = frame[cam_height // 2 - 45: cam_height - 90, :cam_width - 70]
 +
        cv2.imshow("Camera", frame)
 +
 +
        key = cv2.waitKey(1) & 0xFF
 +
 +
        # Exit loop if 'q' is pressed
 +
        if key == ord('q'):
 +
            break
 +
 +
    camera.release()
 +
    cv2.destroyAllWindows()
  
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 11:01, 7 June 2024

Return back to project page: PhotoMath - Jakub Vojtek

Python code for the PhotoMath project:

 
import cv2
import pytesseract
from buildhat import Motor, ForceSensor
import time
import re
import numpy as np
from datetime import datetime

motor_a = Motor('A')
button = ForceSensor('D')

doors_open = True

cam_width = 320
cam_height = 240
camera = cv2.VideoCapture(0)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, cam_width)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, cam_height)

# Path to Tesseract executable (change this according to your installation)
pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract'


def close_doors(force):
    global doors_open
    if doors_open:
        motor_a.run_for_degrees(720, 10)
        doors_open = False
        time.sleep(3)
        process_and_open_door()
    else:
        pass

button.when_pressed = close_doors


def read_text(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    text = pytesseract.image_to_string(gray, config='--psm 6')
    return text


def preprocess_expression(expression):
    expression = expression.replace('\n', '').strip()
    expression = re.sub(r'(?<=[^\s\(\)]) (?=[^\s\(\)])', ' ', expression)
    expression = re.sub(r'(?<=[^\s\(\)])[\+\-\*/\(\)](?=[^\s\(\)])', ' \\g<0> ', expression)
    return expression


def validate_expression(expression):
    return re.match(r'^[\d\s\+\-\*/\(\)]+$', expression)


def simple_calculator(expression):
    try:
        result = round(eval(expression), 4)
        return result
    except Exception as e:
        return "Error: {}".format(str(e))


def process_and_open_door():
    global doors_open
    ret, frame = camera.read()
    frame = frame[cam_height // 2 - 45: cam_height - 90, :cam_width - 70]
    text = read_text(frame)
    print("Extracted text:", text.encode('utf-8'))
    expression = preprocess_expression(text)
    if validate_expression(expression):
        result = simple_calculator(expression)
        print("Solution: ", result)
        annotate_and_save_image(frame, text, result)
    else:
        print("Invalid expression")
    motor_a.run_for_degrees(720, 10)  # Open the door again
    doors_open = True


def annotate_and_save_image(image, text, result):
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    annotated_image = image.copy()
    cv2.putText(annotated_image, f"Text: {text}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
    cv2.putText(annotated_image, f"Result: {result}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
    filename = f"equation_{timestamp}.png"
    cv2.imwrite(filename, annotated_image)
    print(f"Saved image: {filename}")


if __name__ == '__main__':
    while True:
        ret, frame = camera.read()

        frame = frame[cam_height // 2 - 45: cam_height - 90, :cam_width - 70]
        cv2.imshow("Camera", frame)

        key = cv2.waitKey(1) & 0xFF

        # Exit loop if 'q' is pressed
        if key == ord('q'):
            break

    camera.release()
    cv2.destroyAllWindows()