PhotoMath - Code
From RoboWiki
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()