Author Topic: Распознование одинковых элементов в картинке  (Read 2343 times)

0 Members and 1 Guest are viewing this topic.

Otlichnii_paren

  • Освоившийся
  • **
  • Posts: 25
    • View Profile
Добрый день. Озадачился таким вопросом анализирования и распознования одинковых элементов в картинке и действовать исходя из количества элементов друг от друга, ну или количества на один взятый участок. Проще говоря что-то вроде шариков ромбов квадратов расположенных по разному (на картинке будет видно). Да понятно можно решить этот вопрос просто сделав снимки нужных элементов (на данный момент так у меня и работает бот). Но это как то долго вариантов уж слишком много и вообще решения вопроса в лоб. Трудности возникают именно с тем чтоб про анализировать картинку. Пробовал анализировать через расстояние, пробовал разбивать картинку на части, но код получался в 500 строк и то не работал. На чем вообще основано исчезновение шариков в таких играх как цветные линии.
Нужно именно чтоб скрипт проанализировав картинку кликал по одному из тех элементов которые в большем количестве идут друг за другом по горизонтали или вертикали, как зеленые квадратики на второй картинке. Если лень заморачиваться хотя бы подскажите в какую сторону капать.
Не надо не двигать их ниче, просто клик.... Возможно решение лежит на поверхности но в школе информатику я плохо учил...
« Last Edit: March 14, 2020, 11:52:55 PM by Otlichnii_paren »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Хм, интересная задача, и скорее всего решается просто. Но я где-то час разбирал различные алгоритмы в голове, так ничего и не придумал  :( .

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Если элементы точные копии (проверить 100% совпадение), то можно через хэши.
Пробегаешься по всем ячейкам решётки и берёшь хэши центров, к примеру 5х5.
А дальше придумывай алгоритм как определять большУю скученность или что там нужно.


dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
А дальше придумывай алгоритм как определять большУю скученность или что там нужно.

Вот с этим то и проблема, возможно есть какойто спец. алгоритм. Я даже немного пытался гуглить, но не знал как сформулировать запрос.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Продолжим.
Собрали мы массив с хэшами. Считаем сколько всего вариантов нашли.
Дальше цикл по этим хэшам, чтоб перебрать все виды предметов.
А дальше... я пока не придумал.


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Вот с этим то и проблема, возможно есть какойто спец. алгоритм. Я даже немного пытался гуглить, но не знал как сформулировать запрос.
Может Дейкстры? Как раз поиск во всех направлениях. Может и можно прикрутить, только тяжеловато кликеру.

Можно проще. В лоб. Берём первый хэш и обрабатываем только эти элементы. Будем искать все группы разнося по своим массивам. Пробегаем по элементам подряд. Каждый проверяем с элементами уже отобранных в группы. Если отличие по одной из координат <2 добавляем к группе. НЕ  прерываем! Запомнили флаг, что уже прикрепились к группе. Если подходит ещё к одной сливаем вторую с первой и т.д.
Осталось придумать как задать любое количество групп-массивов. Можно и назначаемое имя, только я его не люблю. Можно создать ещё массив с номерами/именами уже созданных для обращения к ним.

Товарищ скинь скриншот не сжатый в png


Otlichnii_paren

  • Освоившийся
  • **
  • Posts: 25
    • View Profile
https://yadi.sk/d/r9wgOd6gd9ZgyA
не сжатые, если слишком часто обращаться к сожалению кликер начинает тормозить и на мертво зависает. Нужна обработка с минимальным количеством обращений к картинке. Я пробовал извартиться по всякому даже оптимизация не дает результатов.



« Last Edit: March 17, 2020, 12:57:24 AM by Otlichnii_paren »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
не сжатые
Как же не сжатые, если jpeg-и
Только не нужно пересохранять jpeg в png, а то уже сталкивались.

если слишком часто обращаться к сожалению кликер начинает тормозить и на мертво зависает. Нужна обработка с минимальным количеством обращений к картинке
Глупости какие. Где здесь тормозить? Тормоза только из-за неправильно сделанного скрипта.

Я пробовал извартиться по всякому даже оптимизация не дает результатов
Показывай как пробовал. скрипт, картинки.
А то вдруг не алгоритм тебе нужно подсказывать


Otlichnii_paren

  • Освоившийся
  • **
  • Posts: 25
    • View Profile
ну как пробовал делал куски готовые из картинки, потом делал разделения на части и сканирование картинки. нужен алгоритм именно я его даже мысленно не многу представить каким образом можно обнаружить рядом находящие такие же элементы и кликнуть по наиболее большему.

https://yadi.sk/d/r9wgOd6gd9ZgyA
не сжатый вариант картинок
« Last Edit: March 17, 2020, 06:26:40 PM by Otlichnii_paren »

JacsoN

  • Активный участник
  • ***
  • Posts: 152
  • извините но мне нужны полнейшие обяснения
    • View Profile
 ну  а если сделать как в  шахматах дать имя каждому  квадратику  и  анализировать..... тоесть  есть "строка 5" 4  подряд  зеленых
а строка  4  столбец 3   также  есть   зеленый .  и  скрипту  нужно  передвинуть или нажать  чтобы  совместить   с  одной  строки  на  другую .....
PS
 поправте  сели  бред   мысль  такая )))  но я я талантлив )
если  есть  возможность  объясни  по  скайпу  что  да  как

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Вроде чтото получилось, немного замороченно, но работает  :D , через графический буфер  :-\ . Написал именно алгорит подсчета скоплений.
Для примера взял подсчет зеленых камушков из примера выше, но можно подсунуть любую комбинацию.

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

Code: (clickermann) [Select]


PXLREPLACE (-1, -1, 6, 7, -1, 0) //красим верхний левый участок в черный

//наша матрица найденных элементов одного цвета (зеленые камни)
//для наглядности и тестов так проще
STRSEPARATE ("1 1 0 0 0 0"," ", $arr1)
STRSEPARATE ("1 0 0 1 1 0"," ", $arr2)
STRSEPARATE ("0 0 0 0 0 0"," ", $arr3)
STRSEPARATE ("0 0 0 0 1 1"," ", $arr4)
STRSEPARATE ("0 1 1 1 1 0"," ", $arr5)

//пишем в графический буфер
ARRCONCAT ($arr, $arr1, $arr2, $arr3, $arr4, $arr5)
FOR($y=0,$y<5)
   FOR($x=0,$x<6)
      PXLREPLACE ($x, $y, $x, $y, -1, $arr[$i])
      inc($i)
   END_CYC
END_CYC

//смотрим начальные данные
print("начальные данные:")
FOR($y1=0,$y1<5)
   print(pxl(0,$y1), " ", pxl(1,$y1), " ", pxl(2,$y1), " ", pxl(3,$y1), " ", pxl(4,$y1), " ", pxl(5,$y1))
END_CYC
print(" ")


FOR($a=0,$a<15) // максимальное количество скоплений - 15
   
   //ищем в поле единицу
   FOR($y=0,$y<5)
      FOR($x=0,$x<6)
         IF(pxl($x, $y) = 1)
            //как только нашли, пишем в массив
            //заодно меняем на порядковый номер, начиная с 2
            $arrs[$a] = 1
            PXLREPLACE ($x, $y, $x, $y, -1, $a+2)
            $y = 5 //после найденной первой единицы, выходим из цикла
         END_IF
         
      END_CYC
   END_CYC
   
     
   IF($y ! 5)   // если единицы не закончились     
      FOR($w=0,$w<5)  //повторяем 5 раз, чтобы засчитать единицы с права на лево       
         FOR($y=0,$y<5)
            FOR($x=0,$x<6)
               
               IF(pxl($x, $y) = $a+2)
                 
                  IF(pxl($x+1, $y) = 1)
                     PXLREPLACE ($x+1, $y, $x+1, $y, -1, $a+2)
                     $arrs[$a] = $arrs[$a]+1
                  END_IF
                  IF(pxl($x, $y+1) = 1)
                     PXLREPLACE ($x, $y+1, $x, $y+1, -1, $a+2)
                     $arrs[$a] = $arrs[$a]+1
                  END_IF
                  IF(pxl($x-1, $y) = 1)
                     PXLREPLACE ($x-1, $y, $x-1, $y, -1, $a+2)
                     $arrs[$a] = $arrs[$a]+1
                  END_IF
                  IF(pxl($x, $y-1) = 1)
                     PXLREPLACE ($x, $y-1, $x, $y-1, -1, $a+2)
                     $arrs[$a] = $arrs[$a]+1
                  END_IF
                 
               END_IF
                             
            END_CYC
         END_CYC       
      END_CYC
   else
      $a = 15  //  ЗАКОНЧИЛИ , единиц нету в поле
   END_IF
   
END_CYC


//смотрим результат
print("результат:")
FOR($y1=0,$y1<5)
   print(pxl(0,$y1), " ", pxl(1,$y1), " ", pxl(2,$y1), " ", pxl(3,$y1), " ", pxl(4,$y1), " ", pxl(5,$y1))
END_CYC

FOR($a=0,$a<arrsize($arrs))
   print("Скопление под номером ",$a+2," - ",$arrs[$a]," элементов")
END_CYC
print(" ")

halt


Лог:
Code: (текст) [Select]
22:34:25 начальные данные:
22:34:25 1 1 0 0 0 0
22:34:25 1 0 0 1 1 0
22:34:25 0 0 0 0 0 0
22:34:25 0 0 0 0 1 1
22:34:25 0 1 1 1 1 0
22:34:26 
22:34:26 результат:
22:34:26 2 2 0 0 0 0
22:34:26 2 0 0 3 3 0
22:34:26 0 0 0 0 0 0
22:34:26 0 0 0 0 4 4
22:34:26 0 4 4 4 4 0
22:34:26 Скопление под номером 2 - 3 элементов
22:34:26 Скопление под номером 3 - 2 элементов
22:34:26 Скопление под номером 4 - 6 элементов
22:34:26 

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

Можно изначальные данные вручную менять как угодно, для теста.


Немного упростил код.
« Last Edit: March 17, 2020, 11:37:18 PM by dramster »

Otlichnii_paren

  • Освоившийся
  • **
  • Posts: 25
    • View Profile
ARRCONCAT()
А что это за подпрограмма?
И каким методом нахождения количества зеленых камней лучше пользоваться чтоб получить данные их наличия и расположения для создания матрицы?
Примерно понял каким методом вести подсчет скоплений, надо будет вечерок по сидеть, под разобраться. вспомнить начальные классы математики))

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Вот что по итогу у меня вышло, переделал всю обработку через массивы. На коментарии пока не хватило времени, поздно уже.
Все что требуется, это ввести верные координаты игрового поля.
Code: (clickermann) [Select]
GETSCREEN

$x1 = 811   //координаты игрового поля
$y1 = 433
$x2 = 1110
$y2 = 684

$x_step = int(($x2 - $x1)/6)
$y_step = int(($y2 - $y1)/5)

COLORMODE (7)

FOR($y=$y1,$y<$y2-$y_step,$y_step)
   FOR($x=$x1,$x<$x2-$x_step,$x_step)
      $color[0] = PXLCOUNT($x, $y, $x+$x_step, $y+$y_step, 8388607) //желт
      $color[1] = PXLCOUNT($x, $y, $x+$x_step, $y+$y_step, 16744319)//син
      $color[2] = PXLCOUNT($x, $y, $x+$x_step, $y+$y_step, 8355839) //кр
      $color[3] = PXLCOUNT($x, $y, $x+$x_step, $y+$y_step, 16777215)//сер
      $color[4] = PXLCOUNT($x, $y, $x+$x_step, $y+$y_step, 8388479)//зел
      $max = $color[0]
      $i_max = 0
      FOR($a=1,$a<5)
         IF($color[$a] > $max)
            $max = $color[$a]
            $i_max = $a
         END_IF
      END_CYC
      arrpush($matrix, $i_max+1)
   END_CYC
END_CYC




STRSEPARATE ("0 0 0 0 0 0 0"," ", $arr0)
ARRCONCAT ($arr1, $arr0, $matrix)
FOR($a=0,$a<37)
   arrpush($arr2,$arr1[$a])
   IF($b = 6)
      arrpush($arr2,0)
      arrpush($arr2,0)
      $b = 0
   END_IF
   inc($b)
END_CYC




FOR($color=1,$color<6)
   ARRCONCAT ($arr, $arr2, $arr0)
   FOR($a=0,$a<15) // максимальное количество скоплений - 15
     
     
      FOR($i=9,$i<arrsize($arr)-9)
         IF($arr[$i] = $color)
            $arrs[$a] = 1
            $arr[$i] = $a+6
            $i = arrsize($arr)-9
         END_IF
      END_CYC
     
      IF($i ! arrsize($arr)-9) //если нашли
         
         FOR($w=0,$w<5)  //повторяем 5 раз, чтобы засчитать единицы с права на лево
           
            FOR($i=9,$i<arrsize($arr)-9)
               
               IF($arr[$i] = $a+6)
                 
                  IF($arr[$i-1] = $color)
                     $arrs[$a] = $arrs[$a] + 1
                     $arr[$i-1] = $a+6
                  END_IF
                  IF($arr[$i-8] = $color)
                     $arrs[$a] = $arrs[$a] + 1
                     $arr[$i-8] = $a+6
                  END_IF
                  IF($arr[$i+1] = $color)
                     $arrs[$a] = $arrs[$a] + 1
                     $arr[$i+1] = $a+6
                  END_IF
                  IF($arr[$i+8] = $color)
                     $arrs[$a] = $arrs[$a] + 1
                     $arr[$i+8] = $a+6
                  END_IF
               END_IF
               
            END_CYC
           
         END_CYC
      else
         $a = 15  //  ЗАКОНЧИЛИ , единиц нету в поле
      END_IF
   END_CYC
   
   
   //смотрим результат
   SWITCH($color)
      CASE(1)
         print("желтый:")
      CASE(2)
         print("синий:")
      CASE(3)
         print("красный:")
      CASE(4)
         print("серый:")
      CASE(5)
         print("зеленый:")
   END_SWITCH
   
   print("всего скоплений - ", arrsize($arrs))
   $max = $arrs[0]
   $i_max = 0
   FOR($a=1,$a<arrsize($arrs))
      IF($arrs[$a] > $max)
         $max = $arrs[$a]
         $i_max = $a
      END_IF
   END_CYC
   print("максимальное скопление - ", $max, " элементов")
   arrpush($finish_max, $max)
   
   FOR($a=0,$a<arrsize($arr))
      IF($arr[$a] > 0)
         arrpush($old_arr,$arr[$a])
      END_IF           
   END_CYC
   
     
   FOR($a=0,$a<arrsize($old_arr))
      IF($old_arr[$a] = $i_max+6)
         $result_y = $y1 + int($a/6)*$y_step + int($y_step/2)
         $result_x = $x1 + ($a - int($a/6)*6)*$x_step + int($x_step/2)
         $a = arrsize($old_arr)
      END_IF
   END_CYC
   print("координаты этого скопления - ", $result_x, " x ", $result_y)
   arrpush($finish_coord, $result_x)
   arrpush($finish_coord, $result_y)
   print(" ")
   undefine($arr)
   undefine($arrs)
   undefine($old_arr)
END_CYC


$max = $finish_max[0]
$result_x = $finish_coord[0]
$result_y = $finish_coord[1]
FOR($a=1,$a<arrsize($finish_max))
   IF($finish_max[$a] > $max)
      $max = $finish_max[$a]
      $result_x = $finish_coord[$a*2]
      $result_y = $finish_coord[$a*2+1]
   END_IF
END_CYC


print("Наибольшее скопление из всех - ", $max, " элементов")
print("В координатах - ", $result_x, " Х ", $result_y)
print(" ")


halt


Результат примера:



Лог:
Code: (текст) [Select]
01:45:43 желтый:
01:45:43 всего скоплений - 4
01:45:43 максимальное скопление - 3 элементов
01:45:43 координаты этого скопления - 1031 x 458
01:45:43 
01:45:44 синий:
01:45:44 всего скоплений - 5
01:45:44 максимальное скопление - 6 элементов
01:45:44 координаты этого скопления - 982 x 558
01:45:44 
01:45:45 красный:
01:45:45 всего скоплений - 2
01:45:45 максимальное скопление - 3 элементов
01:45:45 координаты этого скопления - 835 x 458
01:45:45 
01:45:45 серый:
01:45:45 всего скоплений - 3
01:45:45 максимальное скопление - 2 элементов
01:45:45 координаты этого скопления - 933 x 558
01:45:46 
01:45:46 зеленый:
01:45:46 всего скоплений - 4
01:45:46 максимальное скопление - 2 элементов
01:45:46 координаты этого скопления - 884 x 658
01:45:46 
01:45:46 Наибольшее скопление из всех - 6 элементов
01:45:47 В координатах - 982 Х 558