Author Topic: Конструкция GETSCREEN - IF_PICTURE_IN. Возможно глюк.  (Read 9719 times)

0 Members and 2 Guests are viewing this topic.

yogukum

  • Зашел в гости
  • *
  • Posts: 6
    • View Profile
Привет!

Есть поток, в нем крутиться постоянно проверка определенной области экрана. Внутри проверка вида:

Code: [Select]
getscreen(671,309, 708,401)
IF_PICTURE_IN(671,309, 708,401, "somepict.bmp")
LOGWRITE("OK")
somesub()
ELSE
LOGWRITE("Not OK")
END_IF
wait(1)

Проблема: при любом состоянии экрана условие срабатывает.

Подробнее:

Искомая картинка однородного цвета, залита полностью. Скрипт к окну не привязан, потоков штук 10, один главный, остальные - контроль. 

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

Code: [Select]
getscreen(671,309, 708,401)
IF_PICTURE_IN(671,309, 708,401, "somepict.bmp")
LOGWRITE("OK")

scanpicture(671,309, 708,401, "somepict.bmp")
while (arrsize($var) > 0)
  $y = arrpop($var)
  $x = arrpop($var)
  print($x,":", $y)
end_cyc

SCREENSHOTEX(671,309, 708,401)
 
somesub()
ELSE
LOGWRITE("Not OK") 
END_IF
wait(1)

Но увы, scanpicture координат картинки не видит. И SCREENSHOTEX сохраняет правильные участки с динамикой, сымпла на них нет.  В конце концов добавил в начало getscreen без координат и проверочный скрипт заработал корректно. Код под спойлером:

[spoiler]
Code: [Select]

getscreen
getscreen(671,309, 708,401)
IF_PICTURE_IN(671,309, 708,401, "somepict.bmp")
LOGWRITE("OK")

scanpicture(671,309, 708,401, "somepict.bmp")
while (arrsize($var) > 0)
  $y = arrpop($var)
  $x = arrpop($var)
  print($x,":", $y)
end_cyc

SCREENSHOTEX(671,309, 708,401)
 
somesub()
ELSE
LOGWRITE("Not OK") 
END_IF
wait(1)

[/spoiler]

Обрадовался. И тут читаю на форуме, что работа из окна редактора не рекомендуется и можно посмотреть, что скрипт видит под курсором мыши :). Громко вздыхаю, загружаю основной скрипт, запускаю НЕ из редактора и... Условие опять срабатывает!. Открываю редактор, нажимаю лупу, навожу на искомую область - ну никак там не может быть сэмпла, все двигается, мерцает и моргает, а сэмпл (я повторюсь) просто прямоугольник залитый одним цветом. Добавил также scanpicture в основной скрипт - не находит сэмпл. А условие все равно срабатывает :). Getscreen без координат в основном уже есть, т.е. постоянно экран обновляется полностью. Размер сэмпла в высоту чуть меньше размера области поиска, да просто глазами видно, что не должно срабатывать условие.

Краткая суть бага: иногда, при определенных условиях, конструкция GETSCREEN(x,y,x1,y1) - IF_PICTURE_IN работает некорректно и может возвращать неправильный результат (человеческим языком - находит картинки там, где их нет)

ЗЫ Расписал все подробно, из уважения к автору :). Классная прога. И вообще, этот баг мне жить не мешает, можно заменить тем же scanpicture и все заработает, но как бы может в натуре баг :)

Oraven

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

Code: (clickermann) [Select]
getscreen(671,309, 709,402)
IF_PICTURE_IN(671,309, 708,401, "somepict.bmp")
   LOGWRITE("OK")
ELSE
   LOGWRITE("Not OK")
END_IF
wait(1)

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

Code: (clickermann) [Select]
getscreen(671,309, 709,402)
LOGWRITE (PXLCOUNT(671,309, 708,401, ЦВЕТ)) // запись в лог количества цвета
IF(PXLCOUNT(671,309, 708,401, ЦВЕТ) = КОЛИЧЕСТВО)
   LOGWRITE("OK")
ELSE
   LOGWRITE("Not OK")
END_IF


« Last Edit: March 28, 2015, 03:19:33 PM by Oraven »

yogukum

  • Зашел в гости
  • *
  • Posts: 6
    • View Profile
Ваша картинка просто "невлазит в область поиска, увеличте область на один пиксель в каждую сторону.

Да, я тоже так думал, проверил сразу, хотя если из-за такого условие срабатывает - это еще хуже, на мой взгляд.. :)

Ни какого глюка, скорее недоработка. Дело в том что для области getscreen вторые два числа нужно указывать на 1 пиксел больше области поиска.


Вообщем, я подготовил архив, в котором сэмплы и кодес :) Короче говоря, if_picture_in находит соответствие сэмплу за пределами указанной области. Т.е. по сути сэмпл выпадает "за экран". Как вариант if_picture_in считает, что совпадение части сэмпла достаточно.. Сразу оговорюсь, это мои предположения.

В архиве несколько файлов:
1. somepic.bmp - эту пикчу надо найти
2. bug.bmp - здесь надо найти п.1
3. shot0019.bmp - эту область создал SCREENSHOTEX(671,309, 708,401), вот по ней и нужно ориентироваться, указывая координаты для bug.bmp
4. bug_with_help_dots.bmp - это для примера, где нужно указать координаты - я там точечки поставил :) Только не ее использовать, а п.2
5. if_picture_in_trouble_f.cms - непосредственно сам скрипт, там комменты есть.

Как я делал - открыл bug.bmp, открыл где нибудь рядом shot0019.bmp, и глядя на  shot0019, приблизительно определил координаты этого места на bug.bmp, вписал их и запустил скрипт.. Вуаля.. У меня условие исполнилось.. Кому вообще в лом - тому видос, http://rghost.ru/private/6mrY7pKYr/20bb050076959d11162d7856e0c561d3, пасс для скачивания - 1379

ЗЫ Кстати, scanpicture также работает, находит за пределами. В первом посте я ошибся и забыл массив указать.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Да, косяк есть. Уж где, где, а в IF_PICTURE_IN я думал всё нормально.

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

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