Author Topic: Анализ текста в окне  (Read 108255 times)

0 Members and 1 Guest are viewing this topic.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Анализ текста в окне
« Reply #120 on: August 15, 2017, 09:33:20 PM »
dramster, спасибо, буду разбираться!
Пока на вскидку два вопроса:
а)Не увидел обращения к подпрограмме kontrast (строка 332). Она нужна?
б)Строки 393-396 по сути можно вынести в самое начало основной части программы?

а. подпрограмма kontrast нужна в редких случаях, когда очень сложно отделить символ от фона. работает она очень медленно, особенно если облась распознавания большая. но на капчах, это все равно быстрее, чем отправка и ожидание с сервисов распознавания. подробнее  о контрасте тут http://crapware.aidf.org/forum/index.php?topic=2399.0

б. совершенно верно. можно поставить где угодно, но выше основного скрипта. эта обрезка нужна лишь для первого запуска, когда файла "data.txt" не существует, а по алгоритму к этому файлу идет обращение и поиск строк, которых также не существует.
сильно не охота щас вникать, но возможно, после всех моих извращений по скрипту, этот кусок и не нужен.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Анализ текста в окне
« Reply #121 on: August 15, 2017, 10:01:05 PM »
1.Алгоритм: качаю капчу, вот такого типа(во вложении).
2. все пиксели, ргб которых менее 700,000  превращаю в белый
3. около цифр присутствует фон сильный, из менее насыщенного цвета самой цифры(например цифра красная, а обводка розовая) - я это убираю так: все пиксели с ргб выше 13,000,000 превращаю в белый, затем превращаю все в ч/б и убираю точки, рядом с которыми менее двух закрашенных пикселей
4. затем определяю границы каждой цифры, заношу в массивы(тут тоже косяк с цифрами которые наезжают друг на друга, я без понятия как можно отделять программно.)
5. затем создал матрицу как здесь драмстерhttp://crapware.aidf.org/forum/index.php?topic=2336.msg14743#msg14743, но он использовал 4 координат по вертикали, а я пять взял.
6. потом проверка - если находим комбинацию нужную, то знаем что это за цифра, если нет то ввод вручную.
Недостатки моего способа:1. не знаю как отделить две цифры.
2. из-за коррекции шума, порой режется цифра до неузнаваемости(единичка страдает, бывает отрезается наполовину) или 4, короче некоторые числа сильно обрезаются.

я так понял, что отделить цифры от фона у тебя получилось. насчет "точки, рядом с которыми менее двух закрашенных пикселей", давно уже хотел написать такой алгоритм, чтобы убирать лишнее, делать "толщину" цифр меньше, вроде не сложно, но както руки не доходят  :(.

Quote
тут тоже косяк с цифрами которые наезжают друг на друга, я без понятия как можно отделять программно.
с твоим вариантом сразу в голову пришла идея разделять такие цифры по цветам (я надеюсь там количество цветов ограничено). но есть затык с цифрами одинакового цвета находящиеся рядом, как в твоей последней капче 8 и 7 . хотя таких случае наверно не много, можно и пропустить. нужно пробовать. надеюсь идею понял - с начала ищешь красные цифры - распознаешь, потом зеленые - распознаешь, и тд.

Quote
но он использовал 4 координат по вертикали, а я пять взял.
бери обновленный вариант отсюда http://crapware.aidf.org/forum/index.php?topic=88.msg23101#msg23101 . там у меня с каждой из четырех сторон по пять точек. в этоге выходит строка типа 01110311112042200240~ . плюс возможность выставления точности $accur, где при его значении =1 , строка будет иметь цифры от 0 до 9. а при увеличении этого значения - будут только нолики и единички. помогает в при случаях, когда какието цифры похожи друг на друга, типа 1 и 7, или 8 и 0 . если цифры обычные и не искривлены, то смело можно присваивать этой переменно 6-7, быстрее обучится.

Quote
единичка страдает, бывает отрезается наполовину.
тут тебе в помощь контраст. http://crapware.aidf.org/forum/index.php?topic=2399.0 . там какраз  таки есть пример с таким случаем.
 капча
колормод 8
в двойке прострел

$mid=170 $k=255
$mid=190 $k=255




Автоматизатор

  • Зашел в гости
  • *
  • Posts: 12
    • View Profile
Re: Анализ текста в окне
« Reply #122 on: August 15, 2017, 10:06:41 PM »
я так понял, что отделить цифры от фона у тебя получилось. насчет "точки, рядом с которыми менее двух закрашенных пикселей", давно уже хотел написать такой алгоритм, чтобы убирать лишнее, делать "толщину" цифр меньше, вроде не сложно, но както руки не доходят  :(.

Спасибо за советы, сейчас буду пробовать) только один нюанс, я ушел с кликера, поэтому чистый код взять не смогу, только алгоритмы. Кликер медленный, а я работаю с пост и гет запросами, регулярками, поэтому пока на delphi

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Анализ текста в окне
« Reply #123 on: August 15, 2017, 10:38:25 PM »
я так понял, что отделить цифры от фона у тебя получилось. насчет "точки, рядом с которыми менее двух закрашенных пикселей", давно уже хотел написать такой алгоритм, чтобы убирать лишнее, делать "толщину" цифр меньше, вроде не сложно, но както руки не доходят  :(.
ради интереса, попробуй обработать вот такую капчу (новая капча с фрибитко.ин) своей прогай.
 


выйдет там оставить только буквы или нет? эта капча давно мне мозг мозолит, никак не возьмусь :D .

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Анализ текста в окне
« Reply #124 on: August 16, 2017, 12:21:14 AM »
всеже набросал сам скриптик по анализу количества соседних пикселей.

Code: (clickermann) [Select]
$limit = 4   //лимит соседник пикселей
$x1 = 1049
$y1 = 1371
$x2 = 1232
$y2 = 1433

GETSCREEN
SCREENSHOTEX($x1,$y1,$x2,$y2)

FOR($a=0,$a<5)   //количество прогонов
     
   UNDEFINE($pxl_replace)   
   FOR($y=$y1,$y<$y2+1)
      FOR($x=$x1,$x<$x2+1)
         
         $point = 0
         IF(pxl($x,$y) = 0)
            IF(pxl($x-1,$y) = 0)
               inc($point)
            END_IF
            IF(pxl($x-1,$y-1) = 0)
               inc($point)
            END_IF
            IF(pxl($x,$y-1) = 0)
               inc($point)
            END_IF
            IF(pxl($x+1,$y-1) = 0)
               inc($point)
            END_IF
            IF(pxl($x+1,$y) = 0)
               inc($point
            END_IF
            IF(pxl($x+1,$y+1) = 0)
               inc($point)
            END_IF
            IF(pxl($x,$y+1) = 0)
               inc($point)
            END_IF
            IF(pxl($x-1,$y+1) = 0)
               inc($point)
            END_IF
           
            IF($point < $limit)
               arrpush($pxl_replace, $x)
               arrpush($pxl_replace, $y)
            END_IF
           
         END_IF
         
      END_CYC
   END_CYC
   
   FOR($i_pxl=0,$i_pxl<arrsize($pxl_replace),2)
      PXLREPLACE($pxl_replace[$i_pxl],$pxl_replace[$i_pxl+1],$pxl_replace[$i_pxl],$pxl_replace[$i_pxl+1],0,16777215)
   END_CYC
   
   SCREENSHOTEX($x1,$y1,$x2,$y2)
END_CYC
halt

результат:

делал по пять прогонов отсеивания, первый скрин - оригинал

$limit = 4






визуально результат отличный, но для автораспознавания врядли подойдет, да и буквы залазят друг на друга

$limit = 5







как нибудь попробую, придется долго обучать, но результат скорее всего меня не обрадует  :(



Автоматизатор

  • Зашел в гости
  • *
  • Posts: 12
    • View Profile
Re: Анализ текста в окне
« Reply #125 on: August 16, 2017, 08:37:00 AM »
я так понял, что отделить цифры от фона у тебя получилось. насчет "точки, рядом с которыми менее двух закрашенных пикселей", давно уже хотел написать такой алгоритм, чтобы убирать лишнее, делать "толщину" цифр меньше, вроде не сложно, но както руки не доходят  :(.
ради интереса, попробуй обработать вот такую капчу (новая капча с фрибитко.ин) своей прогай.
 


выйдет там оставить только буквы или нет? эта капча давно мне мозг мозолит, никак не возьмусь :D .

Вот такая ситуация получилась: сначала подсчтитал цвета, там было много серого намешано, также белого и черного. весь серый превращаем в черный, оставляя ч/б изображение:
0;6935//черный
16777215;12104//белый

Затем по такому алгоритму:
С изначальной переменной black3=9, проходим последовательно все 8 точек относительно центрального пикселя и при белой соседней точке отнимаем black3:=black3-1. А затем чистим, если black3=3/4/5/6(На свой выбор) Я прогнал твою картинку по 1 -ничего не изменилось.
2 -
3-
4 -
5 -
6-

Мне нравится фильтр по 4 точкам, а дальше уже можно просто отсечь лишнее, определив наиболее большую кучность черных точек
« Last Edit: August 16, 2017, 09:02:15 AM by Автоматизатор »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: Анализ текста в окне
« Reply #126 on: August 16, 2017, 12:45:34 PM »
всеже набросал сам скриптик по анализу количества соседних пикселей...

Позвольте чуть оптимизировать (чёт меня пробило)
Code: (clickermann) [Select]
//===  Вариант 2  ==============================================================
SUB(NoDirt_2, $x1,$y1, $x2,$y2, $limit)
    GETSCREEN($x1-1,$y1-1, $x2+1,$y2+1)
    SCREENSHOTEX($x1,$y1, $x2,$y2)
   
    FOR($a=0, $a < 5)   // количество прогонов
        UNDEFINE($pRepl)
        FOR($y=$y1, $y < $y2+1)
            FOR($x=$x1, $x < $x2+1)
                IF(PXL($x, $y) = 0)
                    $point = PXLCOUNT($x-1, $y-1, $x+1, $y+1, 0) - 1
                    IF($point < $limit)
                        ARRPUSH($pRepl, $x)
                        ARRPUSH($pRepl, $y)
                    END_IF
                END_IF
            END_CYC
        END_CYC
       
        //LOGWRITE("$pRepl  ", ARRSIZE($pRepl)/2)
        FOR($i_pxl=0, $i_pxl < ARRSIZE($pRepl), 2)
            PXLREPLACE($pRepl[$i_pxl],$pRepl[$i_pxl+1],$pRepl[$i_pxl],$pRepl[$i_pxl+1], 0, 16777215)
        END_CYC
       
        SCREENSHOTEX($x1,$y1, $x2,$y2)
    END_CYC
END_SUB

Quote
//NoDirt_1($Gx1,$Gy1, $Gx2,$Gy2, $Glimit)
// время выполнения NoDirt_ : 39374 мс
// 0:0:39.374

//NoDirt_2($Gx1,$Gy1, $Gx2,$Gy2, $Glimit)
// время выполнения NoDirt_ : 26448 мс
// 0:0:26.448


И следом же позакрашивать дыры
[spoiler=Код]
Code: (clickermann) [Select]
//===  Вариант 1  ==============================================================
SUB(NoHoles_1, $x1,$y1, $x2,$y2)
    GETSCREEN($x1-1,$y1-1, $x2+1,$y2+1)
    UNDEFINE($pRepl)
    FOR($y=$y1, $y < $y2)
        FOR($x=$x1, $x < $x2)
            IF(PXL($x, $y) = 16777215)
                $point = PXLCOUNT($x, $y, $x+1, $y+1, 0)
                IF($point = 3)
                    ARRPUSH($pRepl, $x)
                    ARRPUSH($pRepl, $y)
                END_IF
            END_IF
        END_CYC
    END_CYC
   
    //LOGWRITE("$pRepl  ", ARRSIZE($pRepl)/2)
    FOR($i_pxl=0, $i_pxl < ARRSIZE($pRepl), 2)
        PXLREPLACE($pRepl[$i_pxl],$pRepl[$i_pxl+1],$pRepl[$i_pxl],$pRepl[$i_pxl+1], 16777215, 0)
    END_CYC
    SCREENSHOTEX($Gx1,$Gy1, $Gx2,$Gy2, "NoHoles_")
END_SUB
[/spoiler]


а лучше так
Code: (clickermann) [Select]
//===  Вариант 2  ==============================================================
SUB(NoHoles_2, $x1,$y1, $x2,$y2)
    GETSCREEN($x1-1,$y1-1, $x2+1,$y2+1)
    UNDEFINE($pRepl)
    FOR($y=$y1, $y < $y2)
        FOR($x=$x1, $x < $x2)
            $point = PXLCOUNT($x, $y, $x+1, $y+1, 0)
            IF($point = 3)
                ARRPUSH($pRepl, $x)
                ARRPUSH($pRepl, $y)
            END_IF
        END_CYC
    END_CYC
   
    //LOGWRITE("$pRepl  ", ARRSIZE($pRepl)/2)
    FOR($i_pxl=0, $i_pxl < ARRSIZE($pRepl), 2)
        PXLREPLACE($pRepl[$i_pxl],$pRepl[$i_pxl+1],$pRepl[$i_pxl]+1,$pRepl[$i_pxl+1]+1, 16777215, 0)
    END_CYC
    SCREENSHOTEX($Gx1,$Gy1, $Gx2,$Gy2, "NoHoles_")
END_SUB



gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
Re: Анализ текста в окне
« Reply #127 on: August 29, 2017, 07:07:28 PM »
вот накалякал под вышеуказанную заготовку
dramster, для ситуации глюкнутой картинки (изначально по ряду причин захват не той области для распознавания), как во вложении - у меня происходит зацикливание строк 43-62. Если я правильно понимаю, то это за счет строки 54 $h_str_temp = 0 и того, что нижний артефакт меньше чем $h_str.
Не подскажешь, как убрать зацикливание, какие дополнительные проверки ввести?

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Анализ текста в окне
« Reply #128 on: August 29, 2017, 09:54:53 PM »
да, действительно, не сталкивался с таким случаем. скрипт думает, что строка не превысила минимальную высоту $h_str, и пытается пропустить ее, но далее то рабочая область заканчивается, и цикл лупит без перерыва.

в данный момент у меня не та машина чтобы норм потестить, да и времени и сил нету, через недельку пересмотрю и перепроверю. примерно прикинул как исправить баг. добавил еще условие в цикл, ну и еще.... в общем вот, замени глючный цикл вот этим.
Code: (clickermann) [Select]
$h_str_temp=0
while(($h_str_temp<$h_str)&($y1_text<$y2_text))
   
   while((PXLCOUNT($x1_text,$y1_text,$x2_text,$y1_text,$back_color)<$x2_text-$x1_text+1)&($y1_text<$y2_text))
      inc($y1_text)
      inc($h_str_temp)
   END_CYC
   
   IF(($h_str_temp<$h_str)&($y1_text<$y2_text))
      while((PXLCOUNT($x1_text,$y1_text,$x2_text,$y1_text,$back_color)=$x2_text-$x1_text+1)&($y1_text<$y2_text))
         inc($y1_text)
      END_CYC
      $h_str_temp = 0
     
      $del_arr = arrpop($x1_line_arr)
      $del_arr = arrpop($y1_line_arr)
      arrpush($x1_line_arr, $x1_text)
      arrpush($y1_line_arr, $y1_text)
   END_IF
   
END_CYC

потести.

по идее можно было просто минимальную высоту $h_str уменьшить, и все проблемы.


gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
Re: Анализ текста в окне
« Reply #129 on: August 29, 2017, 10:49:23 PM »
...
по идее можно было просто минимальную высоту $h_str уменьшить, и все проблемы.
Нет, вариант уменьшения высоты не подойдет - а вдруг артефакт окажется высотой в одну пикселю? :)
За скрипт спасибо, буду тестировать потом отпишусь

gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
Re: Анализ текста в окне
« Reply #130 on: September 08, 2017, 01:16:43 AM »
За скрипт спасибо, буду тестировать потом отпишусь
Докладываю: для однотипных цифр работает просто влет, схватил по паре-тройке разных вариантов написания и уверенно все распознает.
В конкретной игре, с которой вожусь - большинство цифр плавающие, по шрифту одни и те же, но размер может отличаться до полутора раз. Поэтому скриптом уже наловилось по 30-40 их вариантов, и обучение еще не завершилось. Но алгоритм распознавания отличный ))
Правда, обнаружилась еще бяка - иногда по экрану в игре гуляют произвольные человечки, которые топчутся и по цифрам, и в итоге при распознавании может выдать ошибку (см скрин). Редко, но бывает. Можно ли как-то на эту ошибку сразу программно реагировать и просто говорить что сценарий прерывать не надо?

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: Анализ текста в окне
« Reply #131 on: September 08, 2017, 09:05:45 AM »
Так на ноль делите батенька. Так недолго и вселенную аннигилировать  ;D

Я так понял это в месте
Code: (clickermann) [Select]
$right_1 = ROUND($right_1 / (INT(($y2_char-$y1_char+1)/2)) / $accur, -1)*10И им подобных.

Как минимум высчитать заранее
Code: (clickermann) [Select]
INT(($y2_char-$y1_char+1)/2)Записать в переменную и проверять на 0. Тем более это выражение встречается во всех пяти вычислениях $right, от $right_1 до $right_5

Ну и в других направлениях посмотреть аналогичные места.
« Last Edit: September 08, 2017, 09:07:23 AM by Vint »


gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
Re: Анализ текста в окне
« Reply #132 on: September 08, 2017, 07:10:54 PM »
ммм...
Но это означает, если я правильно понимаю, что алгоритм не отсеивает малые строки, что должна делать переменная $h_str ? Или я не правильно понял ее значение?

Чтобы было не совсем абстрактно, привожу полностью код, с которым вожусь. Блок по распознаванию - строка 412. Предполагаю, что все-таки что-то не то с подпрограммой lines, строка 33.
... опс, "Сообщение превышает максимально допустимую длину (20000 знаков).", придется обрезать

Code: (clickermann) [Select]
#name "Фарм Наземный"

//   Начало основной программы - строка 800

//   Изменяемые переменные
$glob_map_SUMMARNO=500 // общее число повторений работы по карте
$glob_map_for_centrirovanie_MAX_1=15 // как часто прыгаем в начало, минимальное значение
$glob_map_for_centrirovanie_MAX_2=20 // как часто прыгаем в начало, максимальное значение
$max_lvl_shaht=15 // максимальный уровень шахт, которые можем атаковать
$verojatn_proverki_voisk=1 // доля вероятности проверки войск, чем выше - тем реже проверяем
$rezhim_obuchenia=0 // если =1 то при не вводе цифры будет остановка программы

////////////////////////////////////////////////////////////////////////////////
//////////  описание важных подпрограмм                                            ////
////////////////////////////////////////////////////////////////////////////////
//lines($x1_text,$y1_text,$x2_text,$y2_text) // определяет координаты строк
//ответ - массивы   $x1_line_arr,$y1_line_arr,$x2_line_arr,$y2_line_arr
/////////
//pos_size($x1_line,$y1_line,$x2_line,$y2_line) // координаты и количество символов
//ответ - массивы   $x1_char_arr,$y1_char_arr,$x2_char_arr,$y2_char_arr
////////
//shape($x1_char,$y1_char,$x2_char,$y2_char)  //очертание каждого символа
//ответ - строка очертания вида  01110311112042200240~
////////
//reader($shape)  //обучение и распознавание
//если цифра не распознана, то вылезет окно ввода, где нужно вписать нужную цифру, на эту цифру указывает курсор.
//ответ - строка $all_str

////////////////////////////////////////////////////////////////////////////////
/////////разбивает текст на строки//////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

SUB(lines,$x1_text,$y1_text,$x2_text,$y2_text)
   UNDEFINE ($x1_line_arr)
   UNDEFINE ($y1_line_arr)
   UNDEFINE ($x2_line_arr)
   UNDEFINE ($y2_line_arr)
   //   print("===>подпрогр Lines")
   
   IF_PIXEL_IN($x1_text,$y1_text, $x1_text,$y2_text, $char_color)
      print("...(текст не влазит в границы распознавания слева)")
      $uspeh_raspoznav=0
      GOTO(to_end_lines)
   END_IF
   
   IF_PIXEL_IN($x2_text,$y1_text, $x2_text,$y2_text, $char_color)
      print("...(текст не влазит в границы распознавания справа)")
      $uspeh_raspoznav=0
      GOTO(to_end_lines)
   END_IF
   
   IF(PXLCOUNT($x1_text,$y1_text,$x2_text,$y1_text,$back_color)<$x2_text-$x1_text+1)
      print("...(первая строка обрезана, НЕ учитывается)") // в т.ч. скидывает помехи?
      while(PXLCOUNT($x1_text,$y1_text,$x2_text,$y1_text,$back_color)<$x2_text-$x1_text+1)
         inc($y1_text)
      END_CYC
      if ($y1_text=$y2_text)   //т.е. вообще везде какие-то помехи
         $uspeh_raspoznav=0
         GOTO(to_end_lines)
      end_if
   END_IF
   
   while($y1_text<$y2_text)
      //      print("исходное $y1_text= ", $y1_text, " и $y2_text=", $y2_text)
      while((PXLCOUNT($x1_text,$y1_text,$x2_text,$y1_text,$back_color)=$x2_text-$x1_text+1)&($y1_text<$y2_text))
         inc($y1_text)
      END_CYC
      //      print("взяли для границ цифр $y1_text= ", $y1_text)
     
      IF($y1_text<$y2_text)
         arrpush($x1_line_arr, $x1_text)
         arrpush($y1_line_arr, $y1_text)
         
         $h_str_temp=0
         while(($h_str_temp<$h_str)&($y1_text<$y2_text))
           
            while((PXLCOUNT($x1_text,$y1_text,$x2_text,$y1_text,$back_color)<$x2_text-$x1_text+1)&($y1_text<$y2_text))
               inc($y1_text)
               inc($h_str_temp)
            END_CYC
            //            print("сюда дошли?_2-1 $h_str_temp=", $h_str_temp, " $h_str=", $h_str, " $y1_text=", $y1_text, " $y2_text=", $y2_text)     
            IF(($h_str_temp<$h_str)&($y1_text<$y2_text))
               
               while((PXLCOUNT($x1_text,$y1_text,$x2_text,$y1_text,$back_color)=$x2_text-$x1_text+1)&($y1_text<$y2_text))
                  inc($y1_text)
               END_CYC
               $h_str_temp = 0
               $del_arr = arrpop($x1_line_arr)
               $del_arr = arrpop($y1_line_arr)
               arrpush($x1_line_arr, $x1_text)
               arrpush($y1_line_arr, $y1_text)
            END_IF
         END_CYC
      END_IF
     
      IF(PXLCOUNT($x1_text,$y1_text,$x2_text,$y1_text,$back_color)=$x2_text-$x1_text+1)
         arrpush($x2_line_arr, $x2_text)
         arrpush($y2_line_arr, $y1_text-1)
      else
         print("...(последняя строка обрезана, НЕ учитывается)")
         $del_arr = arrpop($x1_line_arr)
         $del_arr = arrpop($y1_line_arr)
      END_IF
   END_CYC
   
   //   print("итог Lines- количество строк = ",arrsize($x1_line_arr))
   
   // координаты в лог и скрины
   //FOR($a=0,$a<arrsize($x1_line_arr))
   //      print($x1_line_arr[$a]," ",$y1_line_arr[$a]," ",$x2_line_arr[$a]," ",$y2_line_arr[$a])
   //   SCREENSHOTEX($x1_line_arr[$a],$y1_line_arr[$a],$x2_line_arr[$a],$y2_line_arr[$a], ["подпрогр_Lines_скрин_итога_"])
   //END_CYC
   
   IF(arrsize($x1_line_arr)=0)
      print("...(текста не найдено)")
      $uspeh_raspoznav=0
      GOTO(to_end_lines)
      //      ggclick1(795, 15, 3)  //свернули окно игры
      //      halt
   END_IF
   
   to_end_lines:
   
END_SUB

////////////////////////////////////////////////////////////////////////////////
/////////размер и количество символов в строке//////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
SUB(pos_size,$x1_line,$y1_line,$x2_line,$y2_line)
   //   print("===>подпрогр pos_size")
   UNDEFINE ($x1_char_arr)
   UNDEFINE ($y1_char_arr)
   UNDEFINE ($x2_char_arr)
   UNDEFINE ($y2_char_arr)
   
   
   FOR($x1_line_temp=$x1_line,$x1_line_temp<$x2_line+1)
      FOR($y1_line_temp=$y1_line,$y1_line_temp<$y2_line+1)
         IF(pxl($x1_line_temp,$y1_line_temp)=$char_color)
            arrpush($x1_char_arr,$x1_line_temp)
            while(PXLCOUNT($x1_line_temp,$y1_line,$x1_line_temp,$y2_line,$back_color)<$y2_line-$y1_line+1)
               inc($x1_line_temp)
            END_CYC
            arrpush($x2_char_arr,$x1_line_temp-1)
         END_IF
      END_CYC
   END_CYC
   
   FOR($i_char=0,$i_char<arrsize($x1_char_arr))
      SCANPXL ($pix_temp,$x1_char_arr[$i_char],$y1_line,$x2_char_arr[$i_char],$y2_line,$char_color)
      arrpush($y1_char_arr,$pix_temp[1])
      arrpush($y2_char_arr,$pix_temp[arrsize($pix_temp)-1])
      UNDEFINE ($pix_temp)
   END_CYC
   
   
   //   print("количество символов в строке - ",arrsize($x1_char_arr))
   
   //скрины каждого символа
   //   FOR($a=0,$a<arrsize($x1_char_arr))
   //      SCREENSHOTEX($x1_char_arr[$a],$y1_char_arr[$a],$x2_char_arr[$a],$y2_char_arr[$a], ["подпр_Pos_size_очертание_символа_"])
   //   END_CYC
   
END_SUB
////////////////////////////////////////////////////////////////////////////////
////////////////очертание символов//////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
SUB(shape,$x1_char,$y1_char,$x2_char,$y2_char)
   //   print("===>подпрогр shape")
   UNDEFINE($left_1)
   UNDEFINE($left_2)
   UNDEFINE($left_3)
   UNDEFINE($left_4)
   UNDEFINE($left_5)
   UNDEFINE($right_1)
   UNDEFINE($right_2)
   UNDEFINE($right_3)
   UNDEFINE($right_4)
   UNDEFINE($right_5)
   UNDEFINE($up_1)
   UNDEFINE($up_2)
   UNDEFINE($up_3)
   UNDEFINE($up_4)
   UNDEFINE($up_5)
   UNDEFINE($down_1)
   UNDEFINE($down_2)
   UNDEFINE($down_3)
   UNDEFINE($down_4)
   UNDEFINE($down_5)
   int(($y2_char-$y1_char+1)/2)
   
   //лево
   FOR($temp=$x1_char,(pxl($temp,$y2_char)!$char_color)&($temp<$x2_char))
      inc($left_1)
   END_CYC
   $left_1 = ROUND($left_1/($x2_char-$x1_char+1)/$accur,-1)*10
   IF($left_1 > 9)
      $left_1 = 9
   END_IF
   FOR($temp=$x1_char,(pxl($temp,$y2_char-ROUND(($y2_char-$y1_char)/4,0))!$char_color)&($temp<$x2_char))
      inc($left_2)
   END_CYC
   $left_2 = ROUND($left_2/($x2_char-$x1_char+1)/$accur,-1)*10
   IF($left_2 > 9)
      $left_2 = 9
   END_IF
   FOR($temp=$x1_char,(pxl($temp,$y2_char-ROUND(($y2_char-$y1_char)/2,0))!$char_color)&($temp<$x2_char))
      inc($left_3)
   END_CYC
   $left_3 = ROUND($left_3/($x2_char-$x1_char+1)/$accur,-1)*10
   IF($left_3 > 9)
      $left_3 = 9
   END_IF
   FOR($temp=$x1_char,(pxl($temp,$y1_char+ROUND(($y2_char-$y1_char)/4,0))!$char_color)&($temp<$x2_char))
      inc($left_4)
   END_CYC
   $left_4 = ROUND($left_4/($x2_char-$x1_char+1)/$accur,-1)*10
   IF($left_4 > 9)
      $left_4 = 9
   END_IF
   FOR($temp=$x1_char,(pxl($temp,$y1_char)!$char_color)&($temp<$x2_char))
      inc($left_5)
   END_CYC
   $left_5 = ROUND($left_5/($x2_char-$x1_char+1)/$accur,-1)*10
   IF($left_5 > 9)
      $left_5 = 9
   END_IF
   
   //право
   FOR($temp=$x2_char,(pxl($temp,$y2_char)!$char_color)&($temp>$x1_char),-1)
      inc($right_1)
   END_CYC
   $right_1 = $right_1 + (int(($y2_char-$y1_char+1)/2)-($x2_char-$x1_char))
   $right_1 = ROUND($right_1/(int(($y2_char-$y1_char+1)/2))/$accur,-1)*10
   IF($right_1 > 9)
      $right_1 = 9
   END_IF
   FOR($temp=$x2_char,(pxl($temp,$y2_char-ROUND(($y2_char-$y1_char)/4,0))!$char_color)&($temp>$x1_char),-1)
      inc($right_2)
   END_CYC
   $right_2 = $right_2 + (int(($y2_char-$y1_char+1)/2)-($x2_char-$x1_char))
   $right_2 = ROUND($right_2/(int(($y2_char-$y1_char+1)/2))/$accur,-1)*10
   IF($right_2 > 9)
      $right_2 = 9
   END_IF
   FOR($temp=$x2_char,(pxl($temp,$y2_char-ROUND(($y2_char-$y1_char)/2,0))!$char_color)&($temp>$x1_char),-1)
      inc($right_3)
   END_CYC
   $right_3 = $right_3 + (int(($y2_char-$y1_char+1)/2)-($x2_char-$x1_char))
   $right_3 = ROUND($right_3/(int(($y2_char-$y1_char+1)/2))/$accur,-1)*10
   IF($right_3 > 9)
      $right_3 = 9
   END_IF
   FOR($temp=$x2_char,(pxl($temp,$y1_char+ROUND(($y2_char-$y1_char)/4,0))!$char_color)&($temp>$x1_char),-1)
      inc($right_4)
   END_CYC
   $right_4 = $right_4 + (int(($y2_char-$y1_char+1)/2)-($x2_char-$x1_char))
   $right_4 = ROUND($right_4/(int(($y2_char-$y1_char+1)/2))/$accur,-1)*10
   IF($right_4 > 9)
      $right_4 = 9
   END_IF
   FOR($temp=$x2_char,(pxl($temp,$y1_char)!$char_color)&($temp>$x1_char),-1)
      inc($right_5)
   END_CYC
   $right_5 = $right_5 + (int(($y2_char-$y1_char+1)/2)-($x2_char-$x1_char))
   $right_5 = ROUND($right_5/(int(($y2_char-$y1_char+1)/2))/$accur,-1)*10
   IF($right_5 > 9)
      $right_5 = 9
   END_IF
   
   //верх
   FOR($temp=$y1_char,(pxl($x1_char,$temp)!$char_color)&($temp<$y2_char))
      inc($up_1)
   END_CYC
   $up_1 = ROUND($up_1/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($up_1 > 9)
      $up_1 = 9
   END_IF
   FOR($temp=$y1_char,(pxl($x1_char+ROUND(($x2_char-$x1_char)/4,0),$temp)!$char_color)&($temp<$y2_char))
      inc($up_2)
   END_CYC
   $up_2 = ROUND($up_2/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($up_2 > 9)
      $up_2 = 9
   END_IF
   FOR($temp=$y1_char,(pxl($x1_char+ROUND(($x2_char-$x1_char)/2,0),$temp)!$char_color)&($temp<$y2_char))
      inc($up_3)
   END_CYC
   $up_3 = ROUND($up_3/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($up_3 > 9)
      $up_3 = 9
   END_IF
   FOR($temp=$y1_char,(pxl($x2_char-ROUND(($x2_char-$x1_char)/4,0),$temp)!$char_color)&($temp<$y2_char))
      inc($up_4)
   END_CYC
   $up_4 = ROUND($up_4/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($up_4 > 9)
      $up_4 = 9
   END_IF
   FOR($temp=$y1_char,(pxl($x2_char,$temp)!$char_color)&($temp<$y2_char))
      inc($up_5)
   END_CYC
   $up_5 = ROUND($up_5/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($up_5 > 9)
      $up_5 = 9
   END_IF
   
   //низ
   FOR($temp=$y2_char,(pxl($x1_char,$temp)!$char_color)&($temp>$y1_char),-1)
      inc($down_1)
   END_CYC
   $down_1 = ROUND($down_1/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($down_1 > 9)
      $down_1 = 9
   END_IF
   FOR($temp=$y2_char,(pxl($x1_char+ROUND(($x2_char-$x1_char)/4,0),$temp)!$char_color)&($temp>$y1_char),-1)
      inc($down_2)
   END_CYC
   $down_2 = ROUND($down_2/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($down_2 > 9)
      $down_2 = 9
   END_IF
   FOR($temp=$y2_char,(pxl($x1_char+ROUND(($x2_char-$x1_char)/2,0),$temp)!$char_color)&($temp>$y1_char),-1)
      inc($down_3)
   END_CYC
   $down_3 = ROUND($down_3/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($down_3 > 9)
      $down_3 = 9
   END_IF
   FOR($temp=$y2_char,(pxl($x2_char-ROUND(($x2_char-$x1_char)/4,0),$temp)!$char_color)&($temp>$y1_char),-1)
      inc($down_4)
   END_CYC
   $down_4 = ROUND($down_4/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($down_4 > 9)
      $down_4 = 9
   END_IF
   FOR($temp=$y2_char,(pxl($x2_char,$temp)!$char_color)&($temp>$y1_char),-1)
      inc($down_5)
   END_CYC
   $down_5 = ROUND($down_5/($y2_char-$y1_char+1)/$accur,-1)*10
   IF($down_5 > 9)
      $down_5 = 9
   END_IF
   
   
   //   print($left_1," ",$left_2," ",$left_3," ",$left_4," ",$left_5)
   //   print($right_1," ",$right_2," ",$right_3," ",$right_4," ",$right_5)
   //   print($up_1," ",$up_2," ",$up_3," ",$up_4," ",$up_5)
   //   print($down_1," ",$down_2," ",$down_3," ",$down_4," ",$down_5)
   
   $shape_str=STRCONCAT($left_1,$left_2,$left_3,$left_4,$left_5,$right_1,$right_2,$right_3,$right_4,$right_5,$up_1,$up_2,$up_3,$up_4,$up_5,$down_1,$down_2,$down_3,$down_4,$down_5,"~")
   
   //print($shape_str)
   
END_SUB

////////////////////////////////////////////////////////////////////////////////
////////////////распознавание и обучение////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

SUB(reader,$shape,$n_char,$file_name_to_raspoznav)
   
   //   print("===>подпрогр reader")
   FOR($n_str=1,$n_str<TFCOUNT($file_name_to_raspoznav)+1)
      IF(STRPOS (TFREAD ($file_name_to_raspoznav,$n_str), $shape) > 0)
         $t_char = STRCUT(TFREAD ($file_name_to_raspoznav,$n_str), 1, STRPOS(TFREAD($file_name_to_raspoznav,$n_str),":~")-1)
         //         print("символ: ", $t_char)
         strfilter($t_char, "*", 0 )
         $all_str = STRCONCAT ($all_str,$t_char)
         $n_str=TFCOUNT($file_name_to_raspoznav)+1
         $check=0
      else
         $check=1
      END_IF
   END_CYC
   
   IF($check=1)
      move(int(($x2_char_arr[$n_char]-$x1_char_arr[$n_char])/2)+$x1_char_arr[$n_char],$y2_char_arr[$n_char])
      $char_write = INPUTBOX(STRCONCAT("введи цифру под номером ",$n_char+1), "", 120)
      IF($char_write = "")
         if ($rezhim_obuchenia=1)
            print("cancel - полный останов")
            halt
         else
            print("cancel - цифру не распознали и не знаем, НО продолжаем")
            $uspeh_raspoznav=0
            $all_str = STRCONCAT (99,$all_str)
         end_if
      END_IF
      $all_str = STRCONCAT ($all_str,$char_write)
      $check=0    //////////////////
     
      FOR($n_str=1,$n_str<TFCOUNT($file_name_to_raspoznav)+1)
         IF(STRPOS (TFREAD ($file_name_to_raspoznav,$n_str), STRCONCAT($char_write,":~")) =1)
            TFWRITE ($file_name_to_raspoznav,STRCONCAT(TFREAD($file_name_to_raspoznav,$n_str),$shape))
            TFDELETE ($file_name_to_raspoznav,$n_str)
            $n_str=TFCOUNT($file_name_to_raspoznav)+1
            $check=0
         else
            $check=1
         END_IF
      END_CYC
      IF($check=1)
         TFWRITE ($file_name_to_raspoznav,STRCONCAT($char_write,":~",$shape))
      END_IF
   END_IF
   
END_SUB

/////////////////////////////////////////////////////////////////////////////////
//==============================================================================
// головная подпрограмма для распознавания                                ///////
/////////////////////////////////////////////////////////////////////////////////
IF(TFCOUNT("data_gorizont.ini") = 0)
   TFWRITE ("data_gorizont.ini"," ")
END_IF
IF(TFCOUNT("data_number_voisk.ini") = 0)
   TFWRITE ("data_number_voisk.ini"," ")
END_IF

UNDEFINE ($all_str)
$all_str = ""
UNDEFINE ($uspeh_raspoznav)
$uspeh_raspoznav = 1  // если $uspeh_raspoznav=0 то был сбой в распознавании

sub(raspoznav, $rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2,$file_name_to_raspoznav_vhod)
   
   UNDEFINE ($all_str)
   $all_str = ""
   UNDEFINE ($uspeh_raspoznav)
   $uspeh_raspoznav = 1  // если $uspeh_raspoznav=0 то был сбой в распознавании
   
   //   GETSCREEN()
   //   COLORMODE(6)
   //       SCREENSHOT(["my_analiz-Тестовый__6_до_"])
   
   //обязательная обработка изображения до двух цветов
   GETSCREEN($rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2)
   COLORMODE(7, $rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2)
   
   //   print("координаты к распозн: ", $rasp_x1, " ", $rasp_y1, " ", $rasp_x2, " ", $rasp_y2)
   SCREENSHOTEX($rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2, ["my_analiz_уровень_шахты_ИЛИ_цифры_- до обработки"])
   
   
   PXLREPLACE ($rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2, 8355839, 8355711)
   PXLREPLACE ($rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2, 8388607, 8355711)
   PXLREPLACE ($rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2, 8388479, 8355711)
   PXLREPLACE ($rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2, 11632561, 8355711)

   PXLREPLACE(234,80,234,100, -1, 8355711)      //это вручную для количества войск
   PXLREPLACE(200,100,234,100, -1, 8355711)
   PXLREPLACE(200,80,234,100, 16353673, 15724527)  //  синий
   PXLREPLACE(200,80,234,100, 14778337, 8355711)  //    розовый


   
   SCREENSHOTEX($rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2, ["my_analiz_уровень_шахты_ИЛИ_цифры_- в рамках распознавания"])
   
 
   lines($rasp_x1,$rasp_y1,$rasp_x2,$rasp_y2)
   //   print("подпрогр Lines закончили, начинаем цикл")
   if ($uspeh_raspoznav=1)
      FOR($line=0,$line<arrsize($x1_line_arr))        // цикл можно убрать, т.к. все в одну строчку
         pos_size($x1_line_arr[$line],$y1_line_arr[$line],$x2_line_arr[$line],$y2_line_arr[$line])
         
         FOR($char=0,$char<arrsize($x1_char_arr))
            shape($x1_char_arr[$char],$y1_char_arr[$char],$x2_char_arr[$char],$y2_char_arr[$char])
            reader($shape_str,$char, $file_name_to_raspoznav_vhod)
         END_CYC
      END_CYC
   else
      $all_str = 0
   end_if
   
   if ($uspeh_raspoznav=0)
      $all_str = 0
   end_if
   
   //   print("итог распознавания в подпрогр= ", $all_str)
end_sub


////////////////////////////////////////////////////////////////////////////////
//        ОСНОВНАЯ ПРОГРАММА                                               /////
////////////////////////////////////////////////////////////////////////////////

print("--------------")
print("Начинаем фармить на поверхности")

//   параметры для распознавания
$char_color = 16777215   // цвет символов
$back_color = 8355711  //  цвет фона
$accur = 5       //точность  (1 - макс точность; рекомендуется =5)
$h_str = 7     //минимальная высота строки
         
 
....



потести.
Сейчас только обратил внимание, что в процитированном коде условие строки 9 должно выполняться всегда, т.к. идентично строке 2 ? У меня это соответственно строки 75 и 72
« Last Edit: September 08, 2017, 07:14:54 PM by gsukhado »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Анализ текста в окне
« Reply #133 on: September 08, 2017, 10:38:56 PM »
 примерно понял природу появления ошибки. тут дело в том, что в первую очередь сканируются строки (для определения количества  строк и их координат). $h_str  отсеивает строки, где они меньше той самой высоты. но, если в строке например пару символов и точка (из одного пиксела) и эта точка в одной линии по горизонту с остальными символами, то эта точка определится за символ. а так как высота ее 1 пиксель, то $y2_char-$y1_char = 0, и INT(($y2_char-$y1_char+1)/2) = 0.

простой способ решения - это проверка высоты каждого символа, и если она высотой в один пиксель, то можно прибавить единицу к $y2_char
Code: (clickermann) [Select]
FOR($i_char=0,$i_char<arrsize($x1_char_arr))
   SCANPXL ($pix_temp,$x1_char_arr[$i_char],$y1_line,$x2_char_arr[$i_char],$y2_line,$char_color)
   
   IF($pix_temp[arrsize($pix_temp)-1] - $pix_temp[1] = 0)
      arrpush($y1_char_arr,$pix_temp[1])
      arrpush($y2_char_arr,$pix_temp[arrsize($pix_temp)-1]+1)
   ELSE
      arrpush($y1_char_arr,$pix_temp[1])
      arrpush($y2_char_arr,$pix_temp[arrsize($pix_temp)-1])
   END_IF
         
   UNDEFINE ($pix_temp)
END_CYC
но в этом случае, точка также будет засчитана за символ, а это нам скорее всего не нужно. поэтому второй вариант - это проверка высоты символа непосредственно перед вызовам shape и reader. то есть
Code: (clickermann) [Select]
FOR($char=0,$char<arrsize($x1_char_arr))
     
   IF($y2_char_arr[$char]-$y1_char_arr[$char] > 0)
      shape($x1_char_arr[$char],$y1_char_arr[$char],$x2_char_arr[$char],$y2_char_arr[$char])
      reader($shape_str,$char, $file_name_to_raspoznav_vhod)
   END_IF
   
END_CYC



проверь, если не в этом дело, то будем думать дальше.

и 190 строка, убери ее int(($y2_char-$y1_char+1)/2), хз откуда она взялась  :D.



gsukhado

  • Активный участник
  • ***
  • Posts: 104
    • View Profile
Re: Анализ текста в окне
« Reply #134 on: September 09, 2017, 06:43:52 PM »
Тогда может быть вообще было бы правильней сравнивать с $h_str  ? Чтобы любые символы ниже минимальной высоты строки не учитывались?

Code: (clickermann) [Select]
FOR($char=0,$char<arrsize($x1_char_arr))
 
   IF($y2_char_arr[$char]-$y1_char_arr[$char] > ($h_str-1))
      shape($x1_char_arr[$char],$y1_char_arr[$char],$x2_char_arr[$char],$y2_char_arr[$char])
      reader($shape_str,$char, $file_name_to_raspoznav_vhod)
   END_IF
 
END_CYC