Поиск картинки в картинке

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Alloc22, 12 Oct 2015.

  1. Alloc22

    Alloc22 New Member

    Joined:
    12 Oct 2015
    Messages:
    16
    Likes Received:
    0
    Reputations:
    0
    Привет здешним обитателям!

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

    Есть игра. Пытаюсь сделать для нее некое подобие бота. Выглядит она следующим образом:

    [​IMG]

    каждые 1.5-2.0 секунды, на экране появляются стрелочки которые необходимо нажать. Появляются по нарастающей, сначала одна (нажимаем), потом сразу две, потом сразу три и т.д.

    Какой алгоритм лучше всего подойдет в данной ситуации?

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

    Слышал про способ распознавания картинок. как вы думаете, он уместен в данном случае? Или существует еще более логичный вариант? Как бы вы сделали?

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

    Буду вам очень признателен за идеи
     
  2. #colorblind

    #colorblind Moderator

    Joined:
    31 Jan 2014
    Messages:
    634
    Likes Received:
    246
    Reputations:
    42
    Найти массив этих самых стрелочек в памяти программы и ReadProcessMemory
     
    avin and Alloc22 like this.
  3. Alloc22

    Alloc22 New Member

    Joined:
    12 Oct 2015
    Messages:
    16
    Likes Received:
    0
    Reputations:
    0
    исключено, программа не дает рыться у нее в памяти, программы типа артмани не работают, игра тупо убивает редакторы памяти, стоит отдельно зашита (программа)
     
  4. avin

    avin Member

    Joined:
    4 Jul 2011
    Messages:
    103
    Likes Received:
    41
    Reputations:
    2
    Анализ памяти конечно идеальное решение. Но анализ графики тоже не плохой способ.
    В свое время писать автоматизатор для покера, что то типа того что описал ТС. Считывал текущие карты по нескольким точкам. Если у тебя там смещение, можешь попробовать анализировать все пиксели в строке (высота то не меняется). Посоветую также отличную статью как можно написать бота для браузерных игр на примере питона, там анализ тоже по пикселям.
    http://code.tutsplus.com/tutorials/how-to-build-a-python-bot-that-can-play-web-games--active-11117
    Удачи!
     
    makag and Alloc22 like this.
  5. Alloc22

    Alloc22 New Member

    Joined:
    12 Oct 2015
    Messages:
    16
    Likes Received:
    0
    Reputations:
    0
    Спасибо за ответы. Avin, отдельное спасибо за статью, обязательно прочитаю.

    Если позволите, еще один вопрос. Я вот думаю проще было бы для начала определить, сколько этих стрелок в данный момент. Думаю сделать снимок небольшого участка где собственно и появляются стрелки, и пробежать for Х=0 to bmp.width-1 do... и в этом цикле как то определить где цвет стрелки и цвет фона (примерный).. если на пути цвет стрелки тогда записываем в переменную Count:=1, цвет фона идем дальше.. ну вот как то так.. проблема в том, что я в силу своей неопытности в программирование никак не соображу как это сделать.. я уверен для вас это не составит труда. Будьте добры, покажите пожалуйста на примере как это реализовать, буду вам очень блпгодарен
     
  6. avin

    avin Member

    Joined:
    4 Jul 2011
    Messages:
    103
    Likes Received:
    41
    Reputations:
    2
    а на каком конкрентно этапе проблема?? в съёме картинки или получение цвета пикселей?
     
  7. Alloc22

    Alloc22 New Member

    Joined:
    12 Oct 2015
    Messages:
    16
    Likes Received:
    0
    Reputations:
    0
    собственно проблема в том, не могу понять как это сделать. Хочу определить для начала сколько стрелок вышло. Т.е. в цикле пробежать по X-у до конца картинки (for X:=0 to bmp.width do) читая цвет каждого пикселя, и как то посчитать количество стрелок, я думаю сколько раз нам встретиться цвет стрелки в этом цикле столько собственно их и есть. При этом не меняя высоты. вот как то так..
     
  8. Alloc22

    Alloc22 New Member

    Joined:
    12 Oct 2015
    Messages:
    16
    Likes Received:
    0
    Reputations:
    0
    Пытаюсь реализовать задуманное... Поправьте пожалуйста меня если не сложно, идея такая, если во время сканирования мы наткнулись на определенный цвет - перепрыгиваем на 15 пикселей дальше и продолжаем и дальше в том же духе. Я пытался изобразить нечто подобное, но не вышло. Будьте добры, помогите. Заранее спасибо.

    Code:
    var
     delta: Variant;
    begin
    delta:= 160;
    dstPixel := Bmp1.ScanLine[Y];
    for X := 0 to Width - 1 do
    begin
     with dstPixel^ do
     begin
     rgbRed := dstPixel^.rgbRed;
     rgbGreen := dstPixel^.rgbGreen;
     rgbBlue := dstPixel^.rgbBlue;
     Inc(srcPixel);
     end;
     if Abs(GetRValue(dstPixel^.rgbRed) - 160) < delta and
     Abs(GetGValue(dstPixel^.rgbGreen) - 170) < delta and
     Abs(GetBValue(dstPixel^.rgbBlue) - 170) < delta then
     x:=x+15; // Тут выдает ошибку "Assignment to FOR-Loop variable 'X'"
    
     Inc(dstPixel);
    end;
    end;
    
     
  9. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    А стрелочки одинаковые? расположение стрелочек одинаковое? С графикой не работал, но логика была бы у меня такая.
    1. вырезать ТОЛЬКО область в которой появляются стрелочки
    2. обесцветить картинку и повысить контрастность (если нужно)
    3. Подготовить шаблон стрелочки (массив данных)
    4. Искать заданный массив передвигаясь по оси x (слева направо допустим) мол совпала первая строчка. y+1 совпала вторая y+1 и тд... не совпала первая строчка x+1

    Уверен если покопать по этой теме найдется куча интересных алгоритмов.
    Не знаю насколько в данной задаче уместно упоминать про библиотеку OpenCV

    http://robocraft.ru/blog/computervision/3046.html - первое что выдал великий гугл
     
    _________________________
    Alloc22 likes this.
  10. Alloc22

    Alloc22 New Member

    Joined:
    12 Oct 2015
    Messages:
    16
    Likes Received:
    0
    Reputations:
    0
    спасибо за подсказку. В принципе я примерно так и делаю, только немного проще.

    1. Вырезаю область в которой появляются стрелки при помощи BitBlt.
    2. При помощи ScanLine беру определенную высоту и пробегаюсь в цикле по горизонтали (ось X)
    3. Дальше сравниваю в процессе этого цикла цвет пикселей, допустим если встретился нужный цвет значит нажимаю кнопку Влево, еще один нужный цвет - Вправо и так далее..
    Кстати все это сидит в таймере с интервалом 500

    Сам по себе способ устраивает, сравнивает и нажимает кнопки мгновенно. Но есть большая проблема.
    Помимо стрелок которые нужно нажать в игре выше бегает желтая точка, которую тоже нужно нажать когда она попадет в светящуюся зону (можете видеть на картинке). Т.е. нужно нажать стрелки после чего нажать Пробел когда желтая точка будет в нужном месте.

    Точку я проверяю другим методом:

    Code:
    PointColor:= GetPixel(DC,Point.X,Point.Y);
      r:=GetRValue(PointColor);
      g:=GetGValue(PointColor);
      b:=GetBValue(PointColor);
    
    if (r>250) and ((g>200) and (g<235)) and ((b>5) and (b<44)) then EmulateKey(h1, VK_SPACE); 
    и это сидит уже в другом таймере с интервалом 30.

    По отдельности стрелки нажимаются замечательно. Да и желтый круг определяется и жмется хорошо. Но стоит запустить все это вместе, то стрелки не успевают жаться сами, то жмется с опозданием Пробел (для желтой точки)... Игра начинает тормозить.. При этом сама программа совсем не грузит процессор...

    Собственно вопрос в этом. Как лучше сделать, что бы все это работало ДРУЖНО вместе?
    Буду очень вам благодарен за совет и идеи.