Тессеракт "Ошибка в pixCreateNoInit: сбой pix_malloc для данных"
Пытаясь запустить эту функцию внутри функции, основанной на этом, однако, поскольку xPDF может конвертировать PDF-файлы в PNG, я пропустил шаг преобразования ImageMagick, а также неисправную логику в процессе функции (i), поскольку pdftopng требует root name и в данном случае это "ocrbook-000001.png", который выдает ошибку при поиске PNG имени исходного файла PDF.
Моя проблема сейчас в том, чтобы заставить Tesseract сделать что-нибудь с моими файлами PNG. Я получаю ошибку:
Tesseract Open Source OCR Engine v3.05.01 with Leptonica
Error in pixCreateNoInit: pix_malloc fail for data
Error in pixCreate: pixd not made
Error in pixReadStreamPng: pix not made
Error in pixReadStream: png: no pix returned
Error in pixRead: pix not read
Error during processing.
Вот мой код:
lapply(myfiles, function(i){
shell(shQuote(paste0("pdftopng -f 1 -l 10 -r 600 ", i, " ocrbook")))
mypngs <- list.files(path = dest, pattern = "png", full.names = TRUE)
lapply(mypngs, function(z){
shell(shQuote(paste0("tesseract ", z, " out")))
file.remove(paste0(z))
})
})
2 ответа
По-видимому, проблема заключалась в том, что DPI было установлено слишком высоким, чтобы Tesseract мог с ним справиться. Изменение параметра PDFtoPNG DPI с 600 на 150, по-видимому, устранило проблему. Кажется, для Tesseract существует максимальное значение DPI для понимания и понимания того, что делать.
Я также исправил свой код из статического соглашения об именах в более динамичный, который имитирует оригинальные имена файлов.
dest <- "C:\\users\\YOURNAME\\desktop"
files <- tools::file_path_sans_ext(list.files(path = dest, pattern = "pdf", full.names = TRUE))
lapply(files, function(i){
shell(shQuote(paste0("pdftoppm -f 1 -l 10 -r 150 ", i,".pdf", " ",i)))
})
myppms <- tools::file_path_sans_ext(list.files(path = dest, pattern = "ppm", full.names = TRUE))
lapply(myppms, function(y){
shell(shQuote(paste0("magick ", y,".ppm"," ",y,".tif")))
file.remove(paste0(y,".ppm"))
})
mytiffs <- tools::file_path_sans_ext(list.files(path = dest, pattern = "tif", full.names = TRUE))
lapply(mytiffs, function(z){
shell(shQuote(paste0("tesseract ", z,".tif", " ",z)))
file.remove(paste0(z,".tif"))
})
Фон
Похоже, вы уже решили свою проблему. Ура! Я пишу этот ответ, потому что столкнулся с очень похожей проблемой при вызове tesseract из R и хотел поделиться некоторыми обходными путями, которые я придумал, на случай, если кто-то еще наткнется на этот пост и ему понадобятся дополнительные идеи по устранению неполадок.
В моем случае я преобразовывал кучу факсов (около 3000 отдельных pdf-файлов, большинство из них от 1 до 15 страниц) в текст. Я использовал функцию применения, чтобы сделать текст каждого отдельного факса отдельной записью в списке (длина = количество факсов = ~ 3000). Затем факсы были преобразованы в вектор, а затем этот вектор был объединен с вектором имен файлов для создания фрейма данных. Наконец, я записал фрейм данных в файл csv. (См. ниже код, который я использовал).
Проблема заключалась в том, что я продолжал получать ту же строку ошибок, что и вы:
Tesseract Open Source OCR Engine v3.05.01 with Leptonica
Error in pixCreateNoInit: pix_malloc fail for data
Error in pixCreate: pixd not made
Error in pixReadStreamPng: pix not made
Error in pixReadStream: png: no pix returned
Error in pixRead: pix not read
Error during processing.
Вслед за этой ошибкой:error in FUN(X[[i]], ...) : basic_string::_M_construct null not valid
В чем я думаю проблема
Что было странно для меня, так это то, что я повторно запускал код несколько раз, и всегда это был другой факс, где возникала ошибка. Похоже, это также происходило чаще, когда я пытался сделать что-то еще, что использовало много ОЗУ или ЦП (открытие команд Microsoft и т. д.). Я попытался изменить DPI, как было предложено в первом ответе, и это, похоже, не сработало.
Также было заметно, что во время работы этого кода я регулярно использовал почти 100% ОЗУ и 50% ЦП (на основе диспетчера задач Windows).
Когда я запускал этот процесс (на аналогичной партии из примерно 3000 факсов) на Linux-машине со значительно большим объемом ОЗУ и ЦП, я никогда не сталкивался с этой проблемой.
, похоже, ошибка C++. Я не знаком с С++, но это звучит так, будто это какая-то общая ошибка, которая может указывать на то, что что-то, что должно было быть создано, не было создано.
Исходя из всего этого, я думаю, что проблема в том, что у R заканчивается память, и в ответ каким-то образом память, доступная для некоторых базовых процессов tesseract, отключается. Это означает, что не хватает памяти для преобразования pdf в png и последующего извлечения текста, который вызывает эти ошибки. Это приводит к тому, что текстовый BLOB-объект не создается там, где он ожидается, и завершается ошибка C++:
Возможные обходные пути
Итак, я не уверен ни в одном из того, что я только что сказал, но исходя из этого предположения, вот несколько идей, которые я придумал для людей, использующих пакет tesseract в R, которые сталкиваются с похожими проблемами:
Переключитесь с Rstudio на Rgui: это само по себе решило мою проблему. С помощью Rgui я смог завершить весь процесс обработки 3000 факсов без каких-либо ошибок. Rgui также использовал от 100 до 400 МБ вместо 1000+, которые использовал Rstudio, и около 25% ЦП вместо 50%. Помещение R в путь и запуск R из консоли или запуск R в фоновом режиме может еще больше сократить использование памяти.
Закройте все процессы, интенсивно использующие память, на время выполнения кода. Команды Microsoft, видеоконференции, потоковая передача, докер в Windows и подсистема Windows Linux — все это огромные пожиратели памяти.
более низкий DPI. Как было предложено в первом ответе, это также, вероятно, уменьшит использование памяти.
разбить процесс. Я думаю, что запуск моих процессов в пакетах примерно по 500 мог бы также уменьшить объем рабочей памяти, которую R должен занимать перед записью в файл.
Все это быстрые и простые решения, которые можно реализовать в R без необходимости изучения C++ или обновления оборудования. Более надежное решение, вероятно, потребует дополнительной настройки параметров тессеракта, реализации процесса на C++, изменения параметров выделения памяти для R и операционной системы или покупки дополнительной оперативной памяти.
Пример кода
# Load Libraries
library(tesseract)
dir.create("finished_data")
# Define Functions
ocr2 <- function(pdf_path){
# tell tesseract which language to guess
eng <- tesseract("eng")
#convert to png first
#pngfile <- pdftools::pdf_convert(pdf_path, dpi = 300)
# tell tesseract to convert the pdf at pdf_path
seperated_pages <- tesseract::ocr(pdf_path, engine = eng)
#combine all the pages into one page
combined_pages <- paste(seperated_pages, collapse = "**new page**")
# I delete png files as I go to avoid overfilling the hard drive
# because work computer has no hard drive space :'(
png_file_paths <- list.files(pattern = "png$")
file.remove(png_file_paths)
combined_pages
}
# find pdf_paths
fax_file_paths <- list.files(path="./raw_data",
pattern = "pdf$",
recursive = TRUE)
#this converts all the pdfs to text using the ocr
faxes <- lapply(paste0("./raw_data/",fax_file_paths),
ocr2)
fax_table <- data.frame(file_name= fax_file_paths, file_text= unlist(faxes))
write.csv(fax_table, file = paste0("./finished_data/faxes_",format(Sys.Date(),"%b-%d-%Y"), "_test.csv"),row.names = FALSE)