import cv2  # подключение библеотеки OpenCV
import pytesseract  # подключение библеотеки PyTesseract
import time  # подключение библеотеки Time

Sp_M = 'etyopahkxcbm'  # переменная типа string, содержащая в себе символы номерного знака
Sp_R = '\|/'  # разделительная строка между номером и регионом
Sp_L = 'ETYOPAHKXCBM'  # переменная типа string, содержащая в себе символы номерного знака
Sp_N = '0123456789'  # переменная типа string, содержащая в себе все цифры для номерного знака
past = ''  # инициализация переменной
now = ''  # инициализация переменной

pytesseract.pytesseract.tesseract_cmd = 'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'  # адресс библеотеки PyTesseract на компьютере
face_cascade_db = cv2.CascadeClassifier(cv2.data.haarcascades+"haarcascade_russian_plate_number.xml")  # подлючение доп каскады для распознавания номера

cap = cv2.VideoCapture(1)  # подключение камеры и получение данных с неё для программы

while True:
    success, img = cap.read()  # захват изображения с камеры

    config = r'--oem 3 --psm 6'  # установка параметров распознавания текста на фото

    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    plate = face_cascade_db.detectMultiScale(img_gray, 1.1, 19)  # обнаружение координат автомобильного номера на фото - (локализация)
    for (x, y, w, h) in plate:  # цикл, с использованием полученных координат
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)  # обрисовывание номера на фото
        cropped = img[y:y+h, x:x+w]  # доп фото, содержащее только автомобильный номер
        t = pytesseract.image_to_string(cropped, config=config)  # перевод изображения в текстовую переменную - (сегментация)
        if (len(t)>=8):  # минимальная длина автомобильного номера с учётом региона не менее 8 символов
            if (t != past):  # условие не вывода одного и того же номера
                for i in range(len(t)):  # разбор каждого символа номера отдельно - (классификация)
                    if(i==0 or i==4 or i==5):  # первый, пятый и шестой символ в номера - буквы - (алгоритм формирования номера)
                        if(t[i] in Sp_M):  # на случай, если программа распознаёт символ как строчную букву
                            now += (chr(ord(t[i]) - 32))  # вывод заглавной буквы номера
                        if(t[i] in Sp_L):  # символ соответствует одному из заранее установленного списка
                            now += (t[i])  # вывод заглавной буквы номера
                    else:  # со второго по четвёртый и последние три символа - цифры номерного знака  - (алгоритм формирования номера)
                        if(t[i] in Sp_N):  #  символ соответствует одному из заранее установленного списка
                            now += (t[i])  # вывод цифры номерного знака
                if (len(now)>=8):  # если полученный номер содержит минимальное кол-во символов,
                    print(now)  # то программа его выводит в консоль
                    print('')  # после завершения распознавания номерного знака, перенос на следующую строку
                    now = ''  # сброс переменной для следующего цикла
                past = t  # необходимо для сравнения
    cv2.imshow('ta-da', img)  # вывод первоначального изображения с обрисованым номерным знаком
    time.sleep(0.5)  # таймер с задержкой в одну секунду
    if cv2.waitKey(1) & 0xff == ord('q'):  # условия остановки программы
        break  # команда для остановки работы програмы

cap.release()  # остановка видеозахвата с камеры
cv2.destroyAllWindows()  # остановка демонстрации работы программы