Ова упатство објаснува како да поставите систем за оптичко препознавање на знаци (OCR) кој користи Google Vision AI за читање на сложени, стари кирилични текстови. Резултатот е Searchable PDF (PDF со невидлив текстуален слој кој може да се пребарува преку Ctrl+F и да се копира), притоа зачувувајќи го оригиналниот изглед на скенираниот документ.
Зошто го направивме ова: Оваа локална скрипта е создадена како директен одговор на неможноста на стандардните комерцијални софтвери и бесплатни онлајн алатки прецизно да го прочитаат стариот македонски кириличен слог и да ја задржат сложената структура на весниците. Со поврзување на компјутерскиот вид на Google Vision во локална Python околина, го решивме проблемот со уништениот прелом на колоните и лошото препознавање. Резултатот е алатка која генерира перфектно пребарлив PDF (Searchable PDF) директно на вашиот компјутер, заобиколувајќи ги скапите лиценци и сложените cloud инфраструктури.

Важна напомена за Cloud Storage (Buckets): Стандардната процедура на Google за процесирање на цели PDF фајлови бара креирање на Google Cloud Storage Buckets и асинхроно праќање на податоците. За да го поедноставиме процесот за крајниот корисник, оваа скрипта е дизајнирана да ги заобиколи Buckets. Таа го чита PDF-от локално, страница по страница, и комуницира со Google само за препознавање на текстот. Целиот фајл останува и се креира на вашиот компјутер.
Фаза 1: подготовка на Google Cloud (Моторот)
За скриптата да може да го користи визуелниот алгоритам на Google, потребен ви е сервисен клуч (Service Account Key).
- Креирање проект:
- Одете на Google Cloud Console.
- Најавете се со вашата Google сметка.
- Во горниот лев агол, кликнете на паѓачкото мени за проекти и одберете New Project.
- Крстете го проектот (пр.
Arno-OCR-Archive) и кликнете Create.
- Овозможување на Billing (Наплата), не грижете се – бесплатно е!:
- За да се користат API услугите, Google бара да имате внесено платежна картичка (Billing Account).
- Одете во делот Billing од главното мени и поврзете сметка.
- Забелешка: Google Vision нуди 1000 бесплатни страници месечно. За лични и мали архивски проекти, нема да ви биде наплатено ништо, но картичката е задолжителна за верификација.
- Активирање на Vision API:
- Во лентата за пребарување горе, напишете Cloud Vision API.
- Кликнете на резултатот и притиснете го синото копче Enable.
- Вадење на сервисен клуч (JSON):
- Од главното мени лево, одете во IAM & Admin > Service Accounts.
- Кликнете Create Service Account (горе).
- Ставете име (пр.
ocr-bot) и кликнете Create and Continue, па Done. - Во листата ќе го видите новиот Service Account. Кликнете на трите точки од десната страна под Actions и одберете Manage keys.
- Кликнете Add Key > Create new key.
- Одберете формат JSON и кликнете Create.
- Фајлот автоматски ќе се симне на вашиот компјутер. Прекрстете го во
kluc.json.
Фаза 2: локална околина (Python)
За да ја извршите скриптата, потребен ви е инсталиран Python и три дополнителни библиотеки.
- Инсталација на Python:
- Симнете ја најновата верзија од python.org и инсталирајте ја.
- Клучно: При инсталацијата, задолжително штиклирајте ја опцијата
Add Python to PATH(на првиот прозорец).
- Инсталација на библиотеките:
- Отворете го терминалот на вашиот компјутер (На Windows: отворете Start, напишете
cmdи притиснете Enter. На Mac: отворетеTerminal). - Внесете ја следнава команда и притиснете Enter: pip install PyMuPDF google-cloud-vision tkinterdnd2
- Почекајте да заврши инсталацијата.
- Отворете го терминалот на вашиот компјутер (На Windows: отворете Start, напишете
Фаза 3: работен фолдер и скрипта
- Направете нов фолдер на вашиот компјутер каде што ќе работите (на пр.
C:\OCR_Arhiva). - Преместете го фајлот
kluc.jsonво овој фолдер. - Отворете Notepad (или било кој текстуален уредувач), залепете го кодот подолу и зачувајте го во истиот фолдер како
Arno_OCR_App.py.
Кодот на скриптата (ocr_skripta.py)
import warnings
warnings.filterwarnings("ignore", category=FutureWarning)
import os
import fitz
from google.cloud import vision
import threading
import tkinter as tk
from tkinter import messagebox
from tkinterdnd2 import DND_FILES, TkinterDnD
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "kluc.json"
font_path = r"C:\Windows\Fonts\arial.ttf"
def spasi_arhiva_logicka(vlezni_podatoci, izlezni_podatoci, status_label):
try:
status_label.config(text="[*] Се поврзувам со Google Vision...", fg="blue")
client = vision.ImageAnnotatorClient()
doc = fitz.open(vlezni_podatoci)
for page_num in range(len(doc)):
status_label.config(text=f"[*] Процесирам страница {page_num + 1} од {len(doc)}...")
page = doc[page_num]
try:
page.insert_font(fontname="cyrillic", fontfile=font_path)
except Exception:
pass
zoom = 300 / 72.0
mat = fitz.Matrix(zoom, zoom)
pix = page.get_pixmap(matrix=mat)
img_bytes = pix.tobytes("jpeg")
image = vision.Image(content=img_bytes)
response = client.document_text_detection(image=image)
if response.error.message:
status_label.config(text=f"[!] Грешка: {response.error.message}", fg="red")
continue
if response.full_text_annotation:
word_buffer = ""
delayed_text = ""
delayed_x0 = 0
delayed_y1 = 0
delayed_fontsize = 0
for page_info in response.full_text_annotation.pages:
for block in page_info.blocks:
for paragraph in block.paragraphs:
for word in paragraph.words:
current_word_text = ""
has_hyphen_break = False
for symbol in word.symbols:
current_word_text += symbol.text
if symbol.property and symbol.property.detected_break:
if symbol.property.detected_break.type_ == vision.TextAnnotation.DetectedBreak.BreakType.HYPHEN:
has_hyphen_break = True
if has_hyphen_break:
word_buffer += current_word_text.rstrip('-')
else:
final_word_text = word_buffer + current_word_text
word_buffer = ""
vertices = word.bounding_box.vertices
try:
# БЕЗБЕДНО ФОРМАТИРАЊЕ ЗА ДА НЕ СЕ ПРЕСЕЧЕ КОДОТ
x_coords = [v.x for v in vertices]
y_coords = [v.y for v in vertices]
x0 = min(x_coords) / zoom
y1 = max(y_coords) / zoom
font_size = max(4, y1 - min(y_coords) / zoom)
clean_word = final_word_text.strip()
if clean_word in [',', '.', '!', '?', ':', ';', '”', '’', ')', ']', '}']:
delayed_text += clean_word
else:
if delayed_text != "":
page.insert_text(fitz.Point(delayed_x0, delayed_y1), delayed_text, fontsize=delayed_fontsize, fontname="cyrillic", render_mode=3)
delayed_text = clean_word
delayed_x0 = x0
delayed_y1 = y1
delayed_fontsize = font_size
except Exception:
pass
if delayed_text != "":
try:
page.insert_text(fitz.Point(delayed_x0, delayed_y1), delayed_text, fontsize=delayed_fontsize, fontname="cyrillic", render_mode=3)
except Exception:
pass
doc.save(izlezni_podatoci)
status_label.config(text=f"[+] УСПЕШНО!\nЗачувано како:\n{os.path.basename(izlezni_podatoci)}", fg="green")
except Exception as e:
status_label.config(text=f"[!] СИСТЕМСКА ГРЕШКА:\n{str(e)}", fg="red")
def drop_event(event):
file_path = event.data
if file_path.startswith('{') and file_path.endswith('}'):
file_path = file_path[1:-1]
if not file_path.lower().endswith('.pdf'):
messagebox.showwarning("Грешка", "Ве молиме внесете само PDF фајлови!")
return
if not os.path.exists("kluc.json"):
messagebox.showerror("Нема клуч", "Фајлот 'kluc.json' не е пронајден во фолдерот!")
return
base_name, extension = os.path.splitext(file_path)
izlez_pdf = f"{base_name}-finished{extension}"
threading.Thread(target=spasi_arhiva_logicka, args=(file_path, izlez_pdf, lbl_status), daemon=True).start()
root = TkinterDnD.Tk()
root.title("Дигитален Археолог - OCR")
root.geometry("450x300")
root.configure(bg="#f0f0f0")
lbl_title = tk.Label(root, text="АРНО.МК OCR АЛАТКА", font=("Arial", 16, "bold"), bg="#f0f0f0")
lbl_title.pack(pady=20)
lbl_drop = tk.Label(root, text="Повлечи и пушти (Drag & Drop)\nстариот PDF тука",
font=("Arial", 12), bg="#e0e0e0", width=40, height=5, relief="solid", bd=2)
lbl_drop.pack(pady=10)
lbl_drop.drop_target_register(DND_FILES)
lbl_drop.dnd_bind('<<Drop>>', drop_event)
lbl_status = tk.Label(root, text="Спремно за работа.", font=("Arial", 10), bg="#f0f0f0")
lbl_status.pack(pady=15)
root.mainloop()

Фаза 4: Стартување на процесот
- Вашата папка сега треба да изгледа вака:
📄kluc.json
📄Arno_OCR_App.py - Отворете го терминалот (Command Prompt).
- Навигирајте до вашиот фолдер користејќи ја командата
cd(на пример,cd C:\OCR_Arhiva). Алтернативно, во Windows Explorer, одете во фолдерот, кликнете на лентата за адреси горе, избришете ја патеката, напишетеcmdи притиснете Enter. - Внесете ја следнава команда за да ја стартувате апликацијата:
python Arno_OCR_App.py - На екранот ќе се отвори графички прозорец.
- Едноставно фатете го PDF документот што сакате да го дигитализирате (од каде било на вашиот компјутер) и пуштете го (Drag & Drop) во сивата зона на прозорецот.
- Следете го статусот во живо. Откако процесот ќе заврши, во истиот фолдер каде што ви се наоѓа оригиналниот PDF фајл, ќе се појави нов фајл со наставка
-finished.pdf. - Отворете го новиот фајл. Навидум изгледа исто како стариот скениран документ, но обидете се да селектирате текст со глувчето или да пребарате збор преку
Ctrl+F.
That’s all folks!