У меня есть большая коллекция PDF-файлов, содержащих отсканированный текст, который я хотел бы использовать для распознавания текста.
Нет рекламы (Abby, PhantomPDF, Acrobat Pro), службы (Google Vision API) или открытого источника ( Предварительно обученные модели, использующие инструмент tesseract, kraken), смогли распознать текст достаточно точно.
У меня есть несколько PDF-файлов в их первоначальном виде (с неповрежденным текстом), что означает, что у меня есть разумное количество точных, основополагающих данных обучения с огромным совпадением шрифтов, структуры страницы и т. д. c.
Кажется, что каждый метод обучения вашей собственной модели OCR требует настройки данных обучения это означает, что мне нужно разрезать каждую строку из сотен страниц обучающих PDF-файлов на отдельные изображения (тогда я могу просто разбить текст в обучающих PDF-файлах по строкам, чтобы создать соответствующие файлы gt.txt для tesseract или kraken ).
Я использовал инструменты для разделения PDF-файлов по страницам и преобразования / сохранения каждой страницы в файл изображения, но мне не удалось найти способ Tomate делает то же самое построчно. Но, из-за R {pdftools}
кажется, что получение y-координат каждой линии возможно ...
pdftools::pdf_data(pdf_path)[[3]][1:4, ]
#> width height x y space text
#> 1 39 17 245 44 TRUE Table
#> 2 13 17 288 44 TRUE of
#> 3 61 17 305 44 FALSE Contents
#> 4 41 11 72 74 FALSE Overview
... но мне неясно, как это можно отрегулировать в соответствии с масштабированием разрешения любой рутины PDF в изображение.
Все это, как говорится ...
Есть ли инструмент, который уже делает это?
Если нет , в каком направлении я должен направиться, чтобы построить свой собственный?
Кажется, что Magick полностью на это способен (как только я начинаю ориентироваться в пикселях), но это не решает вопрос о том, как перевести координаты y из что-то вроде {pdftools}
в пикселях в изображении, сгенерированном с помощью аргумента DPI (как у каждого? Инструмент преобразования PDF в изображение).
Edit # 1:
Получается координаты основаны на «объектных» местоположениях PDF, что не обязательно означает, что текст, который должен находиться на одной строке (и визуально), всегда отображается как таковой. Текст, который должен находиться в одной строке, может быть отключен на несколько пикселей.
Следующая лучшая вещь - обрезка рамок вокруг каждого из объектов. В R это помогает:
build_training_data <- function(pdf_paths, out_path = "training-data") {
out_path_mold <- "%s/%s-%d-%d.%s"
for (pdf_path in pdf_paths) {
prefix <- sub(".pdf", "", basename(pdf_path), fixed = TRUE)
pdf_data <- pdftools::pdf_data(pdf_path)
pdf_text <- pdftools::pdf_text(pdf_path)
pdf_heights <- pdftools::pdf_pagesize(pdf_path)$height
for (i_page in seq_along(pdf_data)) {
page_text <- pdf_text[[i_page]]
line_text <- strsplit(page_text, "\n")[[1L]]
page_image <- magick::image_read_pdf(pdf_path, pages = i_page)
image_stats <- magick::image_info(page_image)
scale_by <- image_stats$height / pdf_heights[[i_page]]
page_data <- pdf_data[[i_page]]
for (j_object in seq_len(nrow(page_data))) {
cat(sprintf("\r- year: %s, page: %d, object: %d ",
prefix, i_page, j_object))
image_path <- sprintf(out_path_mold, prefix, i_page, j_object)
text_path <- sprintf(out_path_mold, prefix, i_page, j_object)
geom <- magick::geometry_area(
height = page_data$height[[j_object]] * scale_by * 1.2,
width = page_data$width[[j_object]] * scale_by * 1.1,
x_off = page_data$x[[j_object]] * scale_by,
y_off = page_data$y[[j_object]] * scale_by
)
line_image <- magick::image_crop(page_image, geom)
magick::image_write(line_image, format = "png",
path = image_path)
writeLines(page_data$text[[j_object]], text_path)
}
}
}
}
Это определенно не оптимально.