1

Тема: AHK: Исправить слово с ошибкой

Здравствуйте!

Ищу знающих, которые могут подсказать как можно решить данную проблему.

Есть эталон правильных слов:


Арбуз
Персик
Мандарин
Ананас

Есть OCR методика считывания текста с экрана.
Иногда OCR может неправильно перевести слово и оно может выглядеть примерно так:


Арбу3
Герсик
Мандагин
Ана4ас

Неточность может быть любая, но как правило ошибка имеет место быть в некоторых местах.
Я никак не могу придумать способ, чтобы написанные слова проверялись по эталону и, в случае ошибки написания, исправлялись.

Помогите решить проблему советом или примером, пожалуйста!

2

Re: AHK: Исправить слово с ошибкой

А в вашем эталоне есть слова:
Арбузом
Арбуза
Персики?
Иначе проверка становится бессмысленной.

3 (изменено: Clannad5, 2022-07-10 13:20:33)

Re: AHK: Исправить слово с ошибкой

Foma
А почему бессмысленным?
Можете объяснить?

Арбуз, Персик - это лишь пример.

На деле мне нужно сверять имена персонажей и если потребуется - корректировать имя, в случае неверного определения.

4 (изменено: ypppu, 2022-07-10 14:02:01)

Re: AHK: Исправить слово с ошибкой

Думаю, нереально полностью автоматизировать OCR. Так или иначе будут ошибки распознавания. И нет гарантий, что автоисправляльщик исправит правильно. Он порой пропускает неправильные, порой правильные принимает за неправильные.
Если по-простому, то можно сделать так: AutoHotkey помещает текст в программу, умеющую автоматически находить и исправлять ошибки (MS Word, либо браузер). Когда программа проверит весь текст, при помощи AutoHotkey сохраняем исправленный текст в файл.

5 (изменено: Clannad5, 2022-07-10 14:24:59)

Re: AHK: Исправить слово с ошибкой

ypppu
Видимо вы меня не полностью поняли.

Я не собираюсь каждое слово исправлять которое будет найдено.
Мне нужно лишь работать примерно со 150 названием персонажей.

То есть, к примеру у меня есть эталон Никита. Я знаю сколько в нём количества букв, какие есть буквы, но..
Ocr может найти мне hикита или никиГа.

У меня в планах проверять какие он нашел буквы, например "Н", "И", "К", "И", "?", "А".
Проверять сколько он нашел букв и оценивать найденное в процентном соотношение и если они совпадают с эталоном на 70-90% то присваивать ему это имя персонажа "Никита".

Так же, пока я это писал, в голову пришла мысль использования RegEx, он ведь способен искать слова, в котором ему неизвестно значение одной буквы? Возможно это поможет решить мою проблему.
Хотя, если так подумать, OCR может любую букву изменить, тогда RegEx уже сложнее будет реализовать, если только не пробегаться по каждой букве со знаком ".".

6

Re: AHK: Исправить слово с ошибкой

То есть у Вас уже имеется готовый список из ≈150 названий персонажей, и есть критерий (скажем, 80%) на сколько букв слово может отклоняться от имеющихся в списке?

7

Re: AHK: Исправить слово с ошибкой

ypppu
Совершенно верно.

OCR ни разу не добавлял лишнею букву, максимум что он делал - менял нужную.
Зачастую он путал либо букву Т с Г, либо букву Й с И, но я чувствую, что он может спутать и любую другую.

Неправильное определение происходит очень редко, но всё же происходит и я бы хотел избавиться от этой проблемы с конкретными нужными мне именами.
Вот я и думаю, если я пришел к двум вариантам, может быть у других будет что-то еще на уме.

8

Re: AHK: Исправить слово с ошибкой

Предположим, в списке персонажей есть ФедяС и ФедяМ. OCR-программа обнаружила "ФедяЛ". Какой решение в этом случае должен принять скрипт?

9

Re: AHK: Исправить слово с ошибкой

ypppu

В списке есть только эти имена:


Aatrox
Ahri
Akali
Akshan
Alistar
Amumu
Anivia
Annie
Aphelios
Ashe
Aurelion Sol
Azir
Bard
Bel'Veth
Blitzcrank
Brand
Braum
Caitlyn
Camille
Cassiopeia
Cho'Gath
Corki
Darius
Diana
Dr. Mundo
Draven
Ekko
Elise
Evelynn
Ezreal
Fiddlesticks
Fiora
Fizz
Galio
Gangplank
Garen
Gnar
Gragas
Graves
Gwen
Hecarim
Heimerdinger
Illaoi
Irelia
Ivern
Janna
Jarvan IV
Jax
Jayce
Jhin
Jinx
Kai'Sa
Kalista
Karma
Karthus
Kassadin
Katarina
Kayle
Kayn
Kennen
Kha'Zix
Kindred
Kled
Kog'Maw
LeBlanc
Lee Sin
Leona
Lillia
Lissandra
Lucian
Lulu
Lux
Malphite
Malzahar
Maokai
Master Yi
Miss Fortune
Mordekaiser
Morgana
Nami
Nasus
Nautilus
Neeko
Nidalee
Nocturne
Nunu & Willump
Olaf
Orianna
Ornn
Pantheon
Poppy
Pyke
Qiyana
Quinn
Rakan
Rammus
Rek'Sai
Rell
Renata Glasc
Renekton
Rengar
Riven
Rumble
Ryze
Samira
Sejuani
Senna
Seraphine
Sett
Shaco
Shen
Shyvana
Singed
Sion
Sivir
Skarner
Sona
Soraka
Swain
Sylas
Syndra
Tahm Kench
Taliyah
Talon
Taric
Teemo
Thresh
Tristana
Trundle
Tryndamere
Twisted Fate
Twitch
Udyr
Urgot
Varus
Vayne
Veigar
Vel'Koz
Vex
Vi
Viego
Viktor
Vladimir
Volibear
Warwick
Wukong
Xayah
Xerath
Xin Zhao
Yasuo
Yone
Yorick
Yuumi
Zac
Zed
Zeri
Ziggs
Zilean
Zoe
Zyra

10

Re: AHK: Исправить слово с ошибкой

Суть проблемы не меняется. В списке есть Kayle и Kayn. OCR-программа обнаружила "Kaym". Какой решение в этом случае должен принять скрипт?

11

Re: AHK: Исправить слово с ошибкой

ypppu
Kayn, т.к количество букв совпадает.

12

Re: AHK: Исправить слово с ошибкой

Clannad5 пишет:

На деле мне нужно сверять имена персонажей

  Если только имена в единственном числе и без склонений, то моё замечание отпадает.

А количество букв - не гарантия. Сравните "Dorn", прочитанный как "Dom". Возможна ещё куча вариантов.

13 (изменено: ypppu, 2022-07-10 17:50:03)

Re: AHK: Исправить слово с ошибкой

Ну тогда алгоритм такой:

{ ;НАЧАЛО ЦИКЛА (скрипт перебирает по списку)

ЕСЛИ есть точное совпадение, ТО поставить отметку "есть точное совпадение", запомнить результат и выйти из цикла
ИНАЧЕ
           {
            ЕСЛИ есть частичное совпадение,  проверить степень совпадения
                   {
                   ЕСЛИ строка не сильно отличается от имеющегося варианта,
                   ТО  поставить отметку "есть частичное совпадение" и запомнить этот вариант в качестве частичного совпадения
                   }
            }
} ;КОНЕЦ ЦИКЛА

После цикла проверяем наличие отметки о точном либо частичном совпадении. Если ни той, ни другой нет, считать, что исходная строка отличается от всех имеющихся вариантов.

14

Re: AHK: Исправить слово с ошибкой

ypppu
О! Вот с запоминанием на будущее - звучит шикарно!
По сути, если слово спорное, то можно выводить окошко с просьбой соотнести сомнительное имя с нужным и запомнить на будущее.

15

Re: AHK: Исправить слово с ошибкой

В tesseract можно использовать custom dictionary с нужными словами.

16

Re: AHK: Исправить слово с ошибкой

Пока только до такого додумался.
Он еще сырой, но принцип такой, какой мне нужен.

A = Зоя
Array := ["Атрокс","Ари","Акали","Акшан","Алистар","Амуму","Анивия","Энни","Афелий","Эш","Аурелион Сол","Азир","Бард","Бел'вет","Блицкранк","Брэнд","Браум","Кейтлин","Камилла","Кассиопея","Чо'Гат","Корки","Дариус","Диана","Доктор Мундо","Дрейвен","Экко","Элиза","Эвелинн","Эзреаль","Фиддлстикс","Фиора","Физз","Галио","Ганкпланк","Гарен","Гнар","Грагас","Грейвз","Гвен","Гекарим","Хеймердингер","Иллаой","Ирелия","Иверн","Жанна","Джарван IV","Джакс","Джейс","Джин","Джинкс","Кай'Са","Калиста","Карма","Картус","Кассадин","Катарина","Кейл","Кайн","Кеннен","Ка'Зикс","Киндред","Клед","Ког'Мао","Ле Блан","Ли Син","Леона","Лилия","Лиссандра","Люциан","Лулу","Люкс","Мальфит","Мальзахар","Маокай","Мастер Йи","Мисс Фортуна","Мордекайзер","Моргана","Нами","Насус","Наутилус","Нико","Нидали","Ноктюрн","Нуну и Виллумп","Олаф","Орианна","Орн","Пантеон","Поппи","Пайк","Киана","Квинн","Рэйкан","Раммус","Рек'Сай","Релл","Рената Гласк","Ренектон","Ренгар","Ривен","Рамбл","Райз","Самира","Седжуани","Сенна","Серафина","Сетт","Шако","Шен","Шивана","Синджед","Сион","Сивир","Скарнер","Сона","Сорака","Свейн","Сайлас","Синдра","Таам Кенч","Талия","Талон","Тарик","Тимо","Треш","Тристана","Трандл","Триндамир","Твистед Фэйт","Твич","Удир","Ургот","Варус","Вейн","Вейгар","Вел'Коз","Векс","Вай","Виего","Виктор","Владимир","Волибир","Варвик","Вуконг","Шая","Зерат","Ксин Жао","Ясуо","Ёнэ","Йорик","Юми","Зак","Зед","Зери","Зиггс","Зилиан","Зоя","Зайра"]
	C = 0
    C := StrLen(A)
	A := StrSplit(A)
	
for index, element in Array
{
	B := 	StrSplit(element)
	
Sum = 0
	Loop, %C%
	{
	If  A[A_Index] = B[A_Index]
		Sum++
}
Sum := Sum/C*100
Sum := Rtrim(Sum, 0) | Rtrim(Sum, .)
if Sum > 70
Msgbox, % "Совпадение составило " Sum "%, это: " element
}

	

17

Re: AHK: Исправить слово с ошибкой

Вы можете попробовать такую функцию для сравнения строк, но не уверен, что она вам подойдет:

strDiff(string1, string2, ignoreRegister := 1, maxOffset = 5)
{
	StringCaseSense, Locale

	if (ignoreRegister && string1 = string2)
	{
		return (string1 == string2 ? 0 : 0.2 / StrLen(string1))
	}
	if (string1 == "" || string2 == "")
	{
		return (string1 = string2 ? 0 : 1)
	}

	StringSplit, n, string1
	StringSplit, m, string2

	ni := 1, mi := 1, lcs := 0

	while(ni <= n0 && mi <= m0)
	{
		if (n%ni% == m%mi%)
		{
			EnvAdd, lcs, 1
		}
		else if (ignoreRegister && n%ni% = m%mi%)
		{
			EnvAdd, lcs, 0.8
		}
		else
		{
			loop, %maxOffset%
			{
				oi := ni + A_Index, pi := mi + A_Index
				if (n%oi% = m%mi% && oi <= n0)
				{
					ni := oi, lcs += (n%oi% == m%mi% ? 1 : (ignoreRegister ? 0.8 : 0))
					Break
				}
				if ((n%ni% = m%pi% && pi <= m0))
				{
					mi := pi, lcs += (n%ni% == m%pi% ? 1 : (ignoreRegister ? 0.8 : 0))
					Break
				}
			}
		}
		EnvAdd, ni, 1
		EnvAdd, mi, 1
	}
	return ((n0 + m0)/2 - lcs) / (n0 > m0 ? n0 : m0)
}
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

18 (изменено: Clannad5, 2022-07-11 07:11:20)

Re: AHK: Исправить слово с ошибкой

Phoenixxx_Czar
Вроде работает, но мне интересно, что он сравнивает?Так же буквы или что-то еще?

UPD:

Работает, но не со всеми именами. К примеру возникает проблема с именем "Зайра". Если ввести "Зойра", то нужно отклоняться от 0 аж на целых 0.6, что, конечно же, начинает находить многих других персонажей.

Мой же метод находит сходство более точно, но опять же, с отклонением по символам, будет так же тупить я думаю.
Хотя можно совместить один метод с другим, дабы сократить количество схожих имён и, соответственно, провести более точный поиск, но тут опять же не уверен.

Вот пример, где можете ввести "Зойра":

Array := ["Атрокс","Ари","Акали","Акшан","Алистар","Амуму","Анивия","Энни","Афелий","Эш","Аурелион Сол","Азир","Бард","Бел'вет","Блицкранк","Брэнд","Браум","Кейтлин","Камилла","Кассиопея","Чо'Гат","Корки","Дариус","Диана","Доктор Мундо","Дрейвен","Экко","Элиза","Эвелинн","Эзреаль","Фиддлстикс","Фиора","Физз","Галио","Ганкпланк","Гарен","Гнар","Грагас","Грейвз","Гвен","Гекарим","Хеймердингер","Иллаой","Ирелия","Иверн","Жанна","Джарван IV","Джакс","Джейс","Джин","Джинкс","Кай'Са","Калиста","Карма","Картус","Кассадин","Катарина","Кейл","Кайн","Кеннен","Ка'Зикс","Киндред","Клед","Ког'Мао","Ле Блан","Ли Син","Леона","Лилия","Лиссандра","Люциан","Лулу","Люкс","Мальфит","Мальзахар","Маокай","Мастер Йи","Мисс Фортуна","Мордекайзер","Моргана","Нами","Насус","Наутилус","Нико","Нидали","Ноктюрн","Нуну и Виллумп","Олаф","Орианна","Орн","Пантеон","Поппи","Пайк","Киана","Квинн","Рэйкан","Раммус","Рек'Сай","Релл","Рената Гласк","Ренектон","Ренгар","Ривен","Рамбл","Райз","Самира","Седжуани","Сенна","Серафина","Сетт","Шако","Шен","Шивана","Синджед","Сион","Сивир","Скарнер","Сона","Сорака","Свейн","Сайлас","Синдра","Таам Кенч","Талия","Талон","Тарик","Тимо","Треш","Тристана","Трандл","Триндамир","Твистед Фэйт","Твич","Удир","Ургот","Варус","Вейн","Вейгар","Вел'Коз","Векс","Вай","Виего","Виктор","Владимир","Волибир","Варвик","Вуконг","Шая","Зерат","Ксин Жао","Ясуо","Ёнэ","Йорик","Юми","Зак","Зед","Зери","Зиггс","Зилиан","Зоя","Зайра"]
 
	InputBox, string1, Введите имя персонажа,, 300, 200, 200, 200
for index, element in Array
{
string2 := element
ignoreRegister = 1
a := strDiff(string1, string2, ignoreRegister)
if a < 0.6 ;; отклонение от 0 до 1 с плавающей запятой.
{
	c := string2
MsgBox, % "a = " a " Скорее всего вы ввели " c
}


strDiff(string1, string2, ignoreRegister, maxOffset = 5)
{
	StringCaseSense, Locale

	if (ignoreRegister && string1 = string2)
	{
		return (string1 == string2 ? 0 : 0.2 / StrLen(string1))
	}
	if (string1 == "" || string2 == "")
	{
		return (string1 = string2 ? 0 : 1)
	}

	StringSplit, n, string1
	StringSplit, m, string2

	ni := 1, mi := 1, lcs := 0

	while(ni <= n0 && mi <= m0)
	{
		if (n%ni% == m%mi%)
		{
			EnvAdd, lcs, 1
		}
		else if (ignoreRegister && n%ni% = m%mi%)
		{
			EnvAdd, lcs, 0.8
		}
		else
		{
			loop, %maxOffset%
			{
				oi := ni + A_Index, pi := mi + A_Index
				if (n%oi% = m%mi% && oi <= n0)
				{
					ni := oi, lcs += (n%oi% == m%mi% ? 1 : (ignoreRegister ? 0.8 : 0))
					Break
				}
				if ((n%ni% = m%pi% && pi <= m0))
				{
					mi := pi, lcs += (n%ni% == m%pi% ? 1 : (ignoreRegister ? 0.8 : 0))
					Break
				}
			}
		}
		EnvAdd, ni, 1
		EnvAdd, mi, 1
	}
	return ((n0 + m0)/2 - lcs) / (n0 > m0 ? n0 : m0)
}
}

19

Re: AHK: Исправить слово с ошибкой

Sift3 - сверхбыстрый и точный алгоритм расстояния между строками. Чем выше возвращаемое значение, тем больше отличаются две строки. Значение 0.0 означает, что обе строки равны.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)