Author Topic: возможно ли както ускорить поиск картинок?  (Read 6685 times)

0 Members and 1 Guest are viewing this topic.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
 вобщем задача такова. в окне вопрос и 3 варианта ответов. нужно распознать вопрос и кликнуть на правильный ответ, и кликнуть на кнопочку "ответ". у меня мозгов хватило только на вот это :
Code: (clickermann) [Select]
skip:
WAITMS(300)

getscreen
COLORMODE(8 , 384,290, 759,444) // делаем изоброжение в 2 цвета, т.к. окно полупрозрачное

IF_PICTURE_IN (384,290, 569,307, "1.bmp", -1 , 99)//смотрим, этот вопрос, или ни этот, если нет, то идем дальше
   IF_PICTURE_IN (408,344, 474,444, "1.2.bmp", -1 , 98)// если он, находим праильный ответ, кликаем на него, на "ответить" и в начало. в окне новый вопрос
      LCLICK($_return1, ($_return2 - 24))// ($_return2 - 24) т.к. окно привязано
      WAITMS(100)
      LCLICK(442,500)
      GOTO(skip)
   END_IF
END_IF

IF_PICTURE_IN (384,290, 569,307, "2.bmp", -1 , 99)//проверяем этот ли вопрс... нет, идем дальше
   IF_PICTURE_IN (408,344, 474,444, "2.2.bmp", -1 , 98)
      LCLICK($_return1, ($_return2 - 24))
      WAITMS(100)
      LCLICK(442,500)
      GOTO(skip)
   END_IF
END_IF
//............и так по анологии...пока 30 вопрсов, но будет больше
//............

LCLICK(395,409) // если неподошло ниодно изображение вопроса, то кликаем на любой ответ и отвечаем(навсякий случай, если вдруг добавят новый вопрос)
LCLICK(432,497)
пример вопроса:
1.bmp
ответа:
1.2.bmp

вопросов покачто 30, недавно было 20, постоянно добавляют новые. появляются рандомно. пока скорость меня устраивае, примерно 3-4сек если в скрипте он 30-тый (но хотелось бы еще быстрее), но что будет если их будет 100 - 200. тоесть проверяет на совподения 10 изображений в 1сек(примерно).

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

жду совета поглобальнее. может это все както подругому можно реализовать? у меня ничего другого в голову не пришло.

спасибо за будущие ответы :)

« Last Edit: April 18, 2014, 12:19:47 AM by dramster »

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Код оптимален и ускориться можно только уменьшив картинки.
На самом деле достаточно картинки в 1 пиксел по высоте хотя и широкой. Попробуй обрезать их по серидине слова.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Код оптимален и ускориться можно только уменьшив картинки.
На самом деле достаточно картинки в 1 пиксел по высоте хотя и широкой. Попробуй обрезать их по серидине слова.
кстати да, одной строки пикселей должно хватить, попробую, по идее скорость должна увеличиться в разы.

Johnny

  • Создатель
  • Герой форума
  • *
  • Posts: 593
    • View Profile
Подсказка дня:

в случае если место где "висит" картинка заранее известно и проблема упирается лишь в ее однозначную идентификацию, то более рационально (по быстродействию и объему кода) было бы использовать всеми игнорируемую функцию подсчета контрольной суммы для области экрана pxlcrc.
вместо того что бы искать по экрану каждый из 30 элементов набора (вызывая для каждого отдельное сканирование; и так 30 раз) достаточно один раз посчитать сумму для области и сопоставить ее (через тот же красивый switch) с посчитанными заранее данными.

но увы эта красота не сработает если искомые элементы плящут хотя бы на пиксель в сторону

это едва ли относится к данной теме, просто напоминаю, как можно иной раз посутпить. а то if_picture_in являетя ядром наверное 99% скриптов... даже скучно...
« Last Edit: April 18, 2014, 10:42:56 AM by Johnny »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Я применял pxlcrc всего 2 раза. В остальное время или "пляшет" или рендерится иначе. Если возникает необходимость использовать % в поиске, то pxlcrc однозначно не вариант.


dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
сменил картинки вопросов одной строкой пикселей, сменил координаты поиска картинки вопроса. несколько вопросов перестало находить, пришлось процент совпадения до 98% уменьшить. добавили еще 10 вопросов(сейчас всего 40). иииии урааа - на поиск картинок почти неуходит время. уменьшил задержку перед гетскрином до 150мс и за 1 сек овечает на 3-4 вопроса. основная задержка сейчас - это ожидание нового вопроса.


pxlcrc врядли подойдет, т.к. на изображении текст, без COLORMODE он сглаженый. плюс окно полупрозрачное. и в этоге при COLORMODE в букве гденибудь скраю может появиться белый пиксель, а может и непоявиться.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
в случае если место где "висит" картинка заранее известно и проблема упирается лишь в ее однозначную идентификацию, то более рационально (по быстродействию и объему кода) было бы использовать всеми игнорируемую функцию подсчета контрольной суммы для области экрана pxlcrc.
это навело меня на идею с подсчетом пикселей PXLCOUNT и дальнейшей работой только с числами с возможными погрешностями +-1. отсканировал(белый цвет) и записал все сорок переменных. как оказалось , цифры стабильны на каждый вопрос :o, тоесть не меняются как это было с процентом совпадения с картинками :o.
вот что вышло, а главное что это  работает
свич пока неиспользовал, т.к. изменял старый скрипт
Code: (clickermann) [Select]
$1 =  756
$2 =  733
$3 =  507
$4 =  181
//.......
//.......

skip:
WAITMS(150)

getscreen
COLORMODE(8 , 384,290, 836,444)
$COUNT = PXLCOUNT (384,290, 836,323, 16777215)

IF($1 = $COUNT)
   IF_PICTURE_IN (408,344, 474,444, "1.2.bmp", -1 , 98)
      lclick($_return1, ($_return2 - 24))
      WAITMS(100)
      LCLICK(442,500)
      GOTO(skip)
   END_IF
END_IF

IF($2 = $COUNT)
   IF_PICTURE_IN (408,344, 474,444, "2.2.bmp", -1 , 98)
      lclick($_return1, ($_return2 - 24))
      WAITMS(100)
      LCLICK(442,500)
      GOTO(skip)
   END_IF
END_IF
//.....
//.....


print("no")
wait(10)
LCLICK(395,409)
LCLICK(432,497)

значит и с функцией подсчета контрольной суммы PXLCRC тоже будет работать. но я думаю разницы нет , что PXLCOUNT, что PXLCRC (в данном случае)







через 15 минут:

эээ нееет. перешел в игре в другое место. сменилась картинка заднего фона(та что за полупрозрачным окном с вопросами). и всё, всё перестало работать. придется добавлять погрешности типа IF(($1 = $COUNT) | ($1 = $COUNT-1) | ($1 = $COUNT+1)) . а если эти погрешности большие, то вообще ничего невыйдет. какнибуть проверю.


еще через 30мин:

вышел из положения. подставил под окно с вопросами другое окно с белым фоном.переписал все значения переменных. сейчас всё, всё работает отлично.
« Last Edit: April 18, 2014, 03:18:47 PM by dramster »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Как то странно ты диапазон задаёшь...
Code: (clickermann) [Select]
IF(($1+3 > $COUNT) & ($1-3 < $COUNT))
« Last Edit: April 18, 2014, 03:20:31 PM by Vint »


dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
здрасти всем.

решил я воспользаваться сваим скриптом через некоторое время. да вот беда, все вопросы поменяли, и вроде как их стало намного больше :(

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

Code: (clickermann) [Select]
GETSCREEN
$y = 1
$x = 0
$i =  PXLCRC (391,293, 811,320)  //контрольная сумма пикс в облости вопроса
$n = TFCOUNT ("quest.txt")         //кол-во строк в файле
print($n/2)
WHILE($x < $n)                     //пока непроверит все строки, будет сверять с вопросом на экране
   IF(TFREAD ("quest.txt", ($x+1)) ! $i)
      if(($x+1) = $n)
         $y = PXLXOR (412,353, 656,359)//если в списке нету такого вопроса, запоминает сумму пикс первого ответа
         LCLICK(415,329)//кликает на первый ответ
         LCLICK(421,501)
         waitms(1500)
         GETSCREEN
         IF(PXL(411,473)=3274545)    //и проверяет, правильно или нет(красный или зеленый)
            TFWrite("quest.txt", $i)//если правильно, записывает вопрос и ответ с индексом "а"
            TFWrite("quest.txt",STRCONCAT("a",$y))
         else
            TFWrite("quest.txt", $i)
            TFWrite("quest.txt",STRCONCAT("n",$y))//если неправильно, то вопрос и ответ с индексом "н"
         END_IF
      END_if
      INC($x,1)
   else
      if(strfilter(TFREAD ("quest.txt",($x+2)),"a",1) = "a")//если такой вопрос имеется
         $s = strfilter(TFREAD ("quest.txt",($x+2)),"a",0)//и ответ под ним с индексом "а"
         
         SWITCH($s)
         CASE(PXLXOR (412,353, 656,359))//находим ответ и кликаем по нему
            LCLICK(415,329)
         case(PXLXOR (412,393, 656,399))
            LCLICK(415,369)
         case(PXLXOR (412,433, 656,439))
            LCLICK(415,409)
         DEFAULT
         END_SWITCH
         LCLICK(421,501)
         waitms(1500)
         $x = $n// и начинаем с начала
         print("ok")
      else
         //если же ответ с индексом "н", то дальше у меня просто мозг кипит
         $s = strfilter(TFREAD ("quest.txt",($x+2)),"n",0)//считываем из списка сумму, которая прямо под вопросом
         if($n > ($x+3)//тут я расчитывал, что если ответ в конце списка, то в условии появляется ошибка(ошибка всеравно вылазит)
            if(strfilter(TFREAD ("quest.txt",($x+3)),"n",1) = "n")// если под первым неправильным есть еще один такой
               $s1 = strfilter(TFREAD ("quest.txt",($x+3)),"n",0)// то также его считываем
               if(($s!PXLXOR(412,353,656,359)&($s1!PXLXOR(412,353,656,359)))//свеирем с первым вариантом ответа
                  $y = PXLXOR(412,353, 656,359)//если несовпадает, то это правильный ответ
                  LCLICK(415,329)
               else
                  if(($s!PXLXOR(412,393, 656,399)&($s1!PXLXOR(412,393, 656,399)))//если же нет, то сверяем с втарым
                     $y = PXLXOR (412,393, 656,399)
                     LCLICK(415,369)
                  else
                     $y = PXLXOR (412,433, 656,439)//если же и там неправильный,то третий ответ должен быть правильным
                     LCLICK(415,409)
                  end_if
               end_if
            else//если же под вопросом только один вариант ответа(неверного)
               if($s = PXLXOR (412,353, 656,359))//то свераем его с первым на экране
                  $y = PXLXOR (412,393, 656,399)//если это он, то запоминаем вторрой вариант и кликам
                  LCLICK(415,369)
               else
                  $y = PXLXOR (412,353, 656,359)// если не он, то кликаем по первому и запоминаем его
                  LCLICK(415,329)
               end_if
            end_if
         else//тут я расчитывал, что если вопрос и ответ в конце списка, дабы невылазила ошибка(тоесть в списке только один вариант неправильного ответа)
            if($s = PXLXOR (412,353, 656,359))//если совпадает,
               $y = PXLXOR (412,393, 656,399)//то запоминаем второй вариант, и кликаем по нему
               LCLICK(415,369)
            else
               $y = PXLXOR (412,353, 656,359)//иначе запоминаем первый вариант и кликаем по нему
               LCLICK(415,329)
            end_if
         end_if
         LCLICK(421,501)//нажимем на кнопку "ответ"
         waitms(1500)
         GETSCREEN
         IF(PXL(411,473)=3274545) //и проверям, правильно мы ответили или нет
            print("zamena")
            TFDelete("quest.txt", ($x+2))//если правильно, то заменям строку с индексом "н" на "а"
            TFWrite("quest.txt",STRCONCAT("a",$y),($x+2))
            if(strfilter(TFREAD ("quest.txt",($x+3)),"n",1) = "n")//если после это строки есть еще один неправильный вариант, то и его удаляем
               TFDelete("quest.txt", ($x+3))
            end_if
         else
            TFWrite("quest.txt",STRCONCAT("n",$y),($x+2))//если же ответ неверный, то добавляем его под строку с вопроосом, с индексом "н"
         END_IF
         $x = $n//НАЧИНАЕМ С НАЧАЛА
      END_IF
   END_IF
END_CYC

ПОМОЕМУ всё должно работать. какиеже ошибки появляются!?
первая - иногда (но не всегда)неможет прочитать TFREAD ("quest.txt",($x+3)) в  if(strfilter(TFREAD ("quest.txt",($x+3)),"n",1), тоесть ошибка интерпритации или чтото типа того
вторая - под строкой суммы пикс вопроса должно быть по идее не более двух неправильных вариантв(с индексом "н"), так как ответов всего 3. но в списке почемуто иногда появляются одинаковые строки
Code: [Select]
1515959475
n8753810
n8753810
n9734794
и третья - это вообще я дагнать немогу,
Code: [Select]
1515959475
n1
n1
n9734794
если комуто не лень(а комуто и возможно интересно), гляньте в чем могут быть ошибки, мой интелект  мне больше помоч не может.


конечно, можно обойтись без проверки неверных вариантов, так всё работает, но вопросов около трёхсот, а при неверном ответе я ухожу в минус, таккчто нужно как можно быстрее обучить скрипт.
вот рабочий скрипт, который учится очень долго
Code: (clickermann) [Select]
GETSCREEN
$y = 1
$x = 0
$i =  PXLCRC (391,293, 811,320)
$n = TFCOUNT ("quest.txt")
print($n/2)
WHILE($x < $n)
   IF(TFREAD ("quest.txt", ($x+1)) ! $i)
      if(($x+1) = $n)
         $y = PXLXOR (412,353, 656,359)
         LCLICK(425,328)
         LCLICK(421,501)
         waitms(1500)
         GETSCREEN
         IF(PXL(411,473)=3274545) 
           TFWrite("quest.txt", $i)
           TFWrite("quest.txt",STRCONCAT("a",$y))   
         END_IF
      END_if
      INC($x,1)
   else
      $s = strfilter(TFREAD ("quest.txt",($x+2)),"a",0)     
      SWITCH($s)
      CASE(PXLXOR (412,353, 656,359))
         LCLICK(415,331)
      case(PXLXOR (412,393, 656,399))
         LCLICK(415,369)
      case(PXLXOR (412,433, 656,439))
         LCLICK(421,409)
      DEFAULT
         LCLICK(415,368)       
      END_SWITCH
      LCLICK(421,501)
      waitms(1500)
      $x = $n
      print("ok")
   END_IF   
END_CYC



примерно так выглядит окно с вопросом
« Last Edit: October 01, 2014, 10:54:27 PM by dramster »

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Вот там где (ошибка все равно вылазит) недоставало скобки. Или скорее твои вездесущие ($x+1) не нужно заключать в скобки.
GETSCREEN в цикле всего один это нормально? Просто там полно анализов экрана.

Code: (clickermann) [Select]
GETSCREEN
$y = 1
$x = 0
$i =  PXLCRC (391,293, 811,320)  //контрольная сумма пикс в облости вопроса
$n = TFCOUNT ("quest.txt")         //кол-во строк в файле
print($n/2)
WHILE($x < $n)                     //пока непроверит все строки, будет сверять с вопросом на экране
   IF(TFREAD ("quest.txt", $x+1) ! $i)
      if($x+1 = $n)
         
         $y = PXLXOR (412,353, 656,359)//если в списке нету такого вопроса, запоминает сумму пикс первого ответа
         LCLICK(415,329)//кликает на первый ответ
         LCLICK(421,501)
         waitms(1500)
         GETSCREEN
         IF(PXL(411,473)=3274545)    //и проверяет, правильно или нет(красный или зеленый)
            TFWrite("quest.txt", $i)//если правильно, записывает вопрос и ответ с индексом "а"
            TFWrite("quest.txt",STRCONCAT("a",$y))
         else
            TFWrite("quest.txt", $i)
            TFWrite("quest.txt",STRCONCAT("n",$y))//если неправильно, то вопрос и ответ с индексом "н"
         END_IF
      END_if
      INC($x,1)
   else
      if(strfilter(TFREAD ("quest.txt",$x+2),"a",1) = "a")//если такой вопрос имеется
         $s = strfilter(TFREAD ("quest.txt",$x+2),"a",0)//и ответ под ним с индексом "а"
         
         SWITCH($s)
         CASE(PXLXOR (412,353, 656,359))//находим ответ и кликаем по нему
            LCLICK(415,329)
         case(PXLXOR (412,393, 656,399))
            LCLICK(415,369)
         case(PXLXOR (412,433, 656,439))
            LCLICK(415,409)
         DEFAULT
         END_SWITCH
         LCLICK(421,501)
         waitms(1500)
         $x = $n// и начинаем с начала
         print("ok")
      else
         //если же ответ с индексом "н", то дальше у меня просто мозг кипит
         
         $s = strfilter(TFREAD ("quest.txt",$x+2),"n",0)//считываем из списка сумму, которая прямо под вопросом
         if($n > $x+3)//тут я расчитывал, что если ответ в конце списка, то в условии появляется ошибка(ошибка всеравно вылазит)
            if(strfilter(TFREAD ("quest.txt",$x+3),"n",1) = "n")// если под первым неправильным есть еще один такой
               $s1 = strfilter(TFREAD ("quest.txt",$x+3),"n",0)// то также его считываем
               if(($s!PXLXOR(412,353,656,359)&($s1!PXLXOR(412,353,656,359)))//свеирем с первым вариантом ответа
                  $y = PXLXOR(412,353, 656,359)//если несовпадает, то это правильный ответ
                  LCLICK(415,329)
               else
                  if(($s!PXLXOR(412,393, 656,399)&($s1!PXLXOR(412,393, 656,399)))//если же нет, то сверяем с втарым
                     $y = PXLXOR (412,433, 656,439)
                     LCLICK(415,409)
                  else
                     $y = PXLXOR (412,433, 656,439)//если же и там неправильный,то третий ответ должен быть правильным
                     LCLICK(415,409)
                  end_if
               end_if
            else//если же под вопросом только один вариант ответа(неверного)
               if($s = PXLXOR (412,353, 656,359))//то свераем его с первым на экране
                  $y = PXLXOR (412,393, 656,399)//если это он, то запоминаем вторрой вариант и кликам
                  LCLICK(415,369)
               else
                  $y = PXLXOR (412,353, 656,359)// если не он, то кликаем по первому и запоминаем его
                  LCLICK(415,329)
               end_if
            end_if
         else//тут я расчитывал, что если вопрос и ответ в конце списка, дабы невылазила ошибка(тоесть в списке только один вариант неправильного ответа)
            if($s = PXLXOR (412,353, 656,359))//если совпадает,
               $y = PXLXOR (412,393, 656,399)//то запоминаем второй вариант, и кликаем по нему
               LCLICK(415,369)
            else
               $y = PXLXOR (412,353, 656,359)//иначе запоминаем первый вариант и кликаем по нему
               LCLICK(415,329)
            end_if
         end_if
         LCLICK(421,501)//нажимем на кнопку "ответ"
         waitms(1500)
         GETSCREEN
         IF(PXL(411,473)=3274545) //и проверям, правильно мы ответили или нет
            print("zamena")
            TFDelete("quest.txt", $x+2)//если правильно, то заменям строку с индексом "н" на "а"
            TFWrite("quest.txt",STRCONCAT("a",$y),$x+2)
            if(strfilter(TFREAD ("quest.txt",$x+3),"n",1) = "n")//если после это строки есть еще один неправильный вариант, то и его удаляем
               TFDelete("quest.txt", $x+3)
            end_if
         else
            TFWrite("quest.txt",STRCONCAT("n",$y),$x+2)//если же ответ неверный, то добавляем его под строку с вопроосом, с индексом "н"
         END_IF
         $x = $n//НАЧИНАЕМ С НАЧАЛА
      END_IF
   END_IF
END_CYC

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
да, насчет скобочки спасибо (в голове одни циферки и скобочки уже) :D
а как быть с
Code: [Select]
532667843
n13560297
n13560297
n13560297
n1648166
n13560297

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
GETSCREEN в цикле всего один это нормально? Просто там полно анализов экрана.
в процессе работы, картинка меняется один раз. в начале скрипта мы выбираем что делать, на какой вариант выбрать, а кагда выбрали, нажали на "ответить", картинка сменилась, там и следующий GETSCREEN(проверка на правильность ответа). такчто с гетскрином все нормально.

просмотрел я еще пару десятков раз свой код, и всеже нашел ошибки. в if(($s!PXLXOR(412,353,656,359)&($s1!PXLXOR(412,353,656,359))) нехватает скобки(и в первом и во втором случае), отсюда и повторы строк. и исправить ошибку в if($n > $x+3) (опятьже скобочка) мало было, ошибка вылазила всеравно. вопервых не $x+3 а $x+2, а во вторых , в конце кода
Code: (clickermann) [Select]
if(strfilter(TFREAD ("quest.txt",$x+3),"n",1) = "n")
TFDelete("quest.txt", $x+3)
end_if
также надо было всунуть в if($n > $x+2), так как этой строки может несуществовать.



вобщем всё заработало :D. конечно недочеты остались, но это мелочи. иногда записывается в файл чтото типа
Code: [Select]
532667843
a13560297
n13560297
n1648166
n13560297
но я так понял, что дело в одинаковом начале текста ответов. скорее всего нужно расширить зону PXLXOR ответов.
« Last Edit: October 02, 2014, 01:51:18 AM by dramster »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Приятно смотреть. Вот это нормальный код и подход. Сотня строк и сутки мучений.
Не то что... "2800 строк быстренько добавил до 3400, но не хватает функций в кликере для использования переменной в качестве метки GOTO...". Вот что им на это ответить? Только предложить всё переделать с начала.

Тоже приходил к идее самообучения и реализовывал. В основном чтобы в код не прописывать начальные (или изменяемые) параметры. Хочется ещё дальше развить чего нибудь этакое.