Тема компьютерного зрения достаточно обширна: в ней рассматриваются различные способы распознавания статичных изображений и видео. Однако многие из предлагаемых в интернете решений требуют повышенных вычислительных мощностей, сложного ПО и специального оборудования.
В этой статье мы не будем рассматривать что‑то сложное, а вместо этого разберём создание простого сервера для распознавания изображений на Python.
Выбор языка Python для работы с OCR не случаен. Этот язык поддерживает множество библиотек и фреймворков, некоторые из которых мы будем использовать для создания нашего сервера.
Начинаем установку
Для начала нам потребуется установить Tesseract, открытую компьютерную систему для распознавания текстов и Leptonica, библиотеку с открытым исходным кодом, написанную C, предназначенную для обработки и анализа изображений. С её помощью можно выполнять различные операции преобразования, масштабирования, перемещения, сдвига изображений. Также, с её помощью можно работать с различными форматами изображений (JPEG, PNG, TIFF, WebP, JP2, BMP, PNM, PS, GIF и PDF).
Итак, давайте установим все необходимые пакеты.
$ sudo apt-get update
$ sudo apt -y install leptonica-progs
$ sudo apt install tesseract-ocr
Также для работы Tesseract нам потребуется создать переменную среды:
$ export TESSDATA_PREFIX=/usr/local/share/
В завершение установки ставим языковые пакеты. Пакет для английского языка уже установлен. Установим пакет для русского:
$ sudo apt-get install tesseract-ocr-rus
Можно также установить пакеты для всех известных Tesseract языков (потребуется порядка 700 Мб), с помощью команды:
$ sudo apt-get install tesseract-ocr-all
Далее установим библиотеки, необходимые для работы непосредственно Python.
Для начала давайте убедимся, установлен ли Python3.
$ python3 --version
Скорее всего, он у вас уже установлен, но если вдруг чего‑то не хватает, то выполните команду:
$ sudo apt install python3 python3-pip –y
Далее мы будем использовать pip для установки пакетов:
$ pip install pipenv
Создадим каталог для своего проекта:
$ mkdir ocr_server && cd ocr_server && pipenv install --three
Активируем наше виртуальное окружение и устанавливаем необходимые зависимости.
$ pipenv shell
$ pipenv install pytesseract Pillow
Здесь мы также устанавливаем библиотеку Pillow, которая является форком библиотеки Python Imaging Library (PIL) для работы с изображениями в различных форматах на Python.
И в завершении мы установим Flask, который далее будет использоваться как веб-сервер, на который мы будем загружать изображения для распознавания.
$ pipenv install Flask
Собственно, все необходимые для работы компоненты мы установили. Теперь перейдём к написанию кода.
Пишем код
В простейшем случае нам достаточно просто вызвать функцию pytesseract.image_to_string()
, которая попытается распознать текст на картинке.
try:
from PIL import Image
except ImportError:
import Image
import pytesseract
def ocr_core(filename):
text = pytesseract.image_to_string(Image.open(filename))
return text
print(ocr_core('example.png'))
Мы не будем усложнять, и в качестве тестового файла 'example.png' используем следующее изображение:

В результате получаем следующее:

Далее давайте добавим функциональность для загрузки изображений на веб-сервер Flask и передадим их в функцию ocr_core
, которую мы написали выше. В результате мы отобразим изображение рядом с извлеченным текстом в нашем веб‑приложении:
import os
from flask import Flask, render_template, request
# импортируем OCR функцию
from ocr_core import ocr_core
# папка для хранения изображений
UPLOAD_FOLDER = '/static/uploads/'
# разрешаем только определенные типы файлов
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
app = Flask(__name__)
# функция для проверки расширений
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
# функция route, в которой определяется домашняя страница
@app.route('/')
def home_page():
return render_template('index.html')
# функция для загрузки файлов
@app.route('/upload', methods=['GET', 'POST'])
def upload_page():
if request.method == 'POST':
# check if there is a file in the request
if 'file' not in request.files:
return render_template('upload.html', msg='No file selected')
file = request.files['file']
# if no file is selected
if file.filename == '':
return render_template('upload.html', msg='No file selected')
if file and allowed_file(file.filename):
# вызываем функцию ocr_core
extracted_text = ocr_core(file)
# извлекаем текст и отображаем его
return render_template('upload.html',
msg='Successfully processed',
extracted_text=extracted_text,
img_src=UPLOAD_FOLDER + file.filename)
elif request.method == 'GET':
return render_template('upload.html')
if __name__ == '__main__':
app.run()
Это код бекэнда веб-сервера, в котором всё достаточно просто: есть дефолтная страница и есть страница, на которой мы можем загружать изображения, а также есть функция, вызывающая процесс OCR и выводящая результат.
Код страницы index.html мы здесь не приводим, так как это может быть любая статичная заглушка; или можно страницу загрузки, приведённую ниже, использовать как дефолтную.
Код файла upload.html
<!DOCTYPE html>
<html>
<head>
<title>Upload Image</title>
</head>
<body>
{% if msg %}
<h1>{{ msg }}</h1>
{% endif %}
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
<h1>Result:</h1>
{% if img_src %}
<img src="{{ img_src }}">
{% endif %}
{% if extracted_text %}
<p> The extracted text from the image above is: <b> {{ extracted_text }} </b></p>
{% else %}
The extracted text will be displayed here
{% endif %}
</body>
</html>
Код в фигурных скобках — это шаблоны Jinja, которые позволяют отображать текст в определённых сценариях с помощью тегов {% if%}
{% endif%}
. Мы также можем передавать сообщения из нашего приложения Flask для отображения на веб‑странице с помощью тегов {{ }}
.
В итоге страница с загрузкой будет иметь следующий вид:

А после загрузки нашего тестового примера example.png мы получим следующее:

Заключение
Конечно, в этой статье мы рассмотрели достаточно простой пример работы с распознаванием изображений. Но целью было показать, как можно достаточно легко и без лишних затрат реализовать простой веб-сервер для OCR на Python.
Всем, кому интересна тема компьютерного зрения, рекомендую обратить внимание на открытый урок 17 февраля на тему «Аугментация данных в компьютерном зрении».
Рассмотрим, что такое аугментация и зачем она нужна, познакомимся с torchvision transforms и albumentations, разберём написание случайной композиции аугментаций. Если актуально, записывайтесь на странице курса «Компьютерное зрение».
Комментарии (5)
KEugene
11.02.2025 11:06Не очень давно попадался проект python + arduino где реле срабатывало при распознавании правильного автомобильного номера. Питон нужен был, чтобы определить (распознать на фото) автономер и сравнить с базой разрешенных номеров. Но какая разница в размерах используемого ПО!
Rurik82
11.02.2025 11:06Изображения на сервере не сохраняются. Соответственно и отображаться в форме с результатом по пути '/static/uploads/' не будут....
Rurik82
11.02.2025 11:06try:
from PIL import Image
except ImportError:
import ImageЕсли я правильно понимаю, такой код нужен когда вместо Pillow используется оригинальная библиотека PIL. Что более 10 лет как неактуально. Тем более при использовании Python3
surly
Так любой может. Распознавание русского текста покажите.
IgorSh63
Распознавание кириллицы с помощью предложенного tesseract фреймворка тоже возможно.
Параметрами определяется.