Мне нужна идея по обработке текста для субтитров SRT - PullRequest
2 голосов
/ 13 января 2020

Название говорит, что мне действительно нужно банкомат. По сути, я создал набор инструментов OCR на основе Tesseract и ImageMagick. Мне удалось довести его до такой степени, что выходной текст очень последовательный. Я использую это для распознавания некоторых старых жестких субтитров и превращения их в мягкие субтитры SRT. Чтобы сделать снимки экрана для ввода изображения, я использую модифицированную версию старого сценария оболочки, который я нашел и переписал в возрасте go. Те получают подачу во второй скрипт, который обрабатывает их в форму, читаемую imagemagick. На данный момент я мог бы легко выполнить оставшуюся часть работы вручную, но я бы хотел автоматизировать все, кроме последнего прохода корректуры, если это возможно.

Пример текста (из текущего проекта)

03:04.418  Their parents have always written    letters thanking us. =  
03:05.018  Their parents have always written    letters thanking us. =  
03:05.619  Their parents have always written    letters thanking us. =  
03:06.219  Their parents have always written    letters thanking us. =  
03:06.820  Their parents have always written    letters thanking us. =  
03:07.421  Their parents have always written    letters thanking us. =  
03:08.021  Their parents have always written    letters thanking us. =  
03:08.622  This seminary was highly reeemmended.    | am relieved te leave her in your care. =  
03:09.222  This seminary was highly reeemmended.    | am relieved te leave her in your care. =  
03:09.823  This seminary was highly reeemmended.    | am relieved te leave her in your care. =  
03:10.424  This seminary was highly reeemmended.    | am relieved te leave her in your care. =  
03:11.024  This seminary was highly reeemmended.    | am relieved te leave her in your care. =  
03:11.625  This seminary was highly reeemmended.    | am relieved te leave her in your care. =  
03:12.225  In additien te all the previeus requests se far..."  
03:12.826  In additien te all the previeus requests se far..."  
03:13.427  In additien te all the previeus requests se far..."  
03:14.027  In additien te all the previeus requests se far..."  
03:14.628  In additien te all the previeus requests se far..."

В основном я хочу сопоставить текст и извлечь метки времени из первой и последней строк и установить их в формате srt

1
00:03:04,418 --> 00:03:08,021
Their parents have always written
letters thanking us. =  

2
00:03:08,622 --> 00:03:08,622
This seminary was highly reeemmended
| am relieved te leave her in your care. = 

3
00:03:12,225 --> 00:03:14,628
In additien te all the previeus requests se far..."

На данный момент я согласен с тем, что это отдельный скрипт.

В основном sub.txt в sub.srt out. Затем сделайте проход корректуры. Теперь в обнаруженном тексте есть немного Изменчивости, но это минимально. Меня иногда определяют как | или [, и это иногда смешивает o и e в некоторых нечетных угловых случаях. Редактировать 2 февраля 2020 года: я сделал некоторые изменения и настройки, чтобы получить то, что я хотел. И МОЙ сценарий оболочки и Ivans. Я удалил пустые подстроки, созданные сценарием ivans и моим, а также.

ОБНОВЛЕННАЯ обработка и сценарий ocr BTW

#!/bin/bash -x

cd "$1"
mkdir ocr

for f in *.png ;
do
base="$(basename "$f" | cut -d "." -f 1,2)"
echo "$base"
if [[ -z "$2" ]] ; 
then
tran="$(convert "$f"  -separate -average  -crop +0+720 -threshold 11% -fill black -draw 'color 700,10 floodfill' +repage ocr/"$base".png)"

else
tran="$(convert "$f"  -separate -average  -crop +0+720 -negate -threshold 15% -fill white -draw 'color 700,10 floodfill' +repage ocr/"$base".png)"

fi 
$tran
cd ocr
magick mogrify -pointsize 50 -fill blue -draw 'text 1400,310 "L" ' +repage "$base".png
cd ..


done
cd ocr
for i in *.png ;
do base2="$(basename "$i" | cut -d "." -f 1,2 | cut -d ":" -f 2,3)"
tesseract "$i" stdout -c page_separator='' --psm 6 --oem 1 --dpi 300 | { tr '\n' ' '; tr -s  [:space:] ' ';  echo; } >> text.txt
echo "$base2""  " >> time.txt

done
awk '{printf ("%s", $0); getline < "text.txt"; print $0 }' time.txt >> out.txt
sed -i 's/|/I/g' out.txt
sed -i 's/\[/I/g' out.txt
#sed -i 's/L//g' out.txt
#sed -i 's/=//g' out.txt
sed -i 's/.$//' out.txt
sed -i 's/.$//' out.txt

while read line ; do
sed "/[[:alpha:]]/ !d" >> sub.txt
done <out.txt
exit

Создание детали синим цветом L должно гарантировать, что каждая строка имеет что-то в нем для сопоставления с отметкой времени.

ОБНОВЛЕННЫЙ СКРИПТ ИВАНА СТО

#!/bin/bash -x

sub="$1"            # path to sub file
OLD=$IFS            # remember current delimiter
IFS=$'\n'           # set delimiter to the new line
raw=( $(cat $sub) ) # load sub into raw array
IFS=$OLD            # set default delimiter back

reset () {
    unset raw[0]        # remove 1-st item from array
    raw=( "${raw[@]}" ) # rearange array
}

output () {

    printf "00:$time1 --> 00:$time3\n$text1\n\n"

    }

speen () {
    time3=$time2
    reset
    test=( "${raw[@]::2}" ) # get two more items
    test2=( ${test[0]} )    # split 2-nd item
    time2=${test2[0]}       # get 2-nd timing
    text2=${test2[@]:1}     # get 2-nd text

    # if only one item in test than this is the end, return


    [[ "${test[1]}" ]] || { printf "00:$time1 --> 00:$time2\n$text1\n\n"; raw=; return; }
    #   compare,     speen more if match,  print ang go further if not 

    [[ "$text1" == "$text2" ]] && speen || output
}

N=1 # set counter
while [[ "${raw[@]}" ]]; do # loop through data
    echo $((N++))       # print and inc counter
    test1=( $raw )      # get 1-st item
    time1=${test1[0]}   # get 1-st timing
    text1=${test1[@]:1}
    # get 1-st text
    speen
done

Я только что добавил третью переменную времени, чтобы сохранить старое значение time2 как time3. По сути, устранение незаполненной временной метки нарушило Его соответствие. Я понял, что time2 была первой несоответствующей отметкой времени. Поэтому мне нужно было сохранить предыдущий из последнего l oop. Таким образом time3=$time2 Затем оставьте значение time2. Затем используйте старое время2 (теперь время3), чтобы напечатать подстроку.

1 Ответ

2 голосов
/ 13 января 2020

Закончено этим

#!/bin/bash

sub=file            # path to sub file
OLD=$IFS            # remember current delimiter
IFS=$'\n'           # set delimiter to the new line
raw=( $(cat $sub) ) # load sub into raw array
IFS=$OLD            # set default delimiter back

reset () {
    unset raw[0]        # remove 1-st item from array
    raw=( "${raw[@]}" ) # rearange array
}

output () {
    text1=${text1//|/I} # change | to I in text
    text1=${text1//[/I} # change [ to I in text
    printf "$time1 --> $time2\n$text1\n\n"    
}

speen () {
    reset
    test=( "${raw[@]::2}" ) # get two more items
    test2=( ${test[0]} )    # split 2-nd item
    time2=${test2[0]}       # get 2-nd timing
    text2=${test2[@]:1}     # get 2-nd text
    # if only one item in test than this is the end, return
    [[ "${test[1]}" ]] || { printf "$time1 --> $time2\n$text1\n\n"; raw=; return; }
    #   compare,     speen more if match,  print ang go further if not 
    [[ "$text1" == "$text2" ]] && speen || output
}

N=1 # set counter
while [[ "${raw[@]}" ]]; do # loop through data
    echo $((N++))       # print and inc counter
    test1=( $raw )      # get 1-st item
    time1=${test1[0]}   # get 1-st timing
    text1=${test1[@]:1} # get 1-st text
    speen
done
...