Здравствуйте господа форумчане. Заинтересовался HiAsm-ом . Вроде перспективный такой инструмент, если сравнивать с Autoit - раньше на нем кодил. Но вот совершенно простую задачку которую Autoit решает в одну строку кода "Быстро найти пиксель красного цвета" ну ни как не удается реализовать. Может есть знающие люди на форуме , кто ставил перед собой подобную задачу в этой среде? Сразу оговорюсь в Delphi не силен по этому написать IC - Сканлайн думаю не смогу , перелопатил весь инет вдоль и поперек причем разными поисковиками. Результат - 0. Попадаются разные решения типа "Найти часть картинки и т.д" но все не то. Буду благодарен за любые полезные советы.
PS: Картинка 1024x768 Постоянно обновляется (скриншоты с экрана).
Редактировалось 1 раз(а), последний 2017-05-26 03:25:44
Этот топик читают: Гость
Этот топик был перемещен из раздела "Помощь по среде"
Ответов: 35
Рейтинг: -1
|
|||
карма: -4 |
|
Google
vip
|
#1.1контекстная реклама от партнеров
|
Ответов: 632
Рейтинг: 4
|
|||
Держите
http://lunnyy1svet.hopto.org/Загрузка/Project8.sha Редактировалось 1 раз(а), последний 2017-05-26 12:56:16 |
|||
карма: 0 |
|
Ответов: 35
Рейтинг: -1
|
|||
Vadimluk1 писал(а): Держите http://lunnyy1svet.hopto.org/Загрузка/Project8.sha Редактировалось 1 раз(а), последний 2017-05-26 12:56:16 Спасибо большое ищет бесконечно долго) Тестировал вот на этом Ваша схема на HiAsm: Результат Хаясма - Неизвестен А вот Быстрый поиск! но нужно что то типа этого на Hiasm. Код Autoit для быстрого поиска #include "FastFind.au3" ; подключаем библиотеку быстрого поиска HotKeySet("{F2}", "FindSpot") ; Горячая клавиша - начать поиск HotKeySet("{ESC}", "End") ;Горячая клавиша - остановить поиск Global $color = "0xFF0000"; 0xFF0000 - цвет который ищем (ПРИМЕР) $hwnd = WinGetHandle("тэст.bmp - Paint") ; окно в котором ищем WinSetState($hwnd, "",@SW_RESTORE) ; развернуть если свернуто FFSnapShot(0, 0, 0, 0, 0, $hwnd) ; скрин opt("MouseCoordMode", 2) ; Устанавливает способ отсчёта координат используемый в функциях мыши, - ; -или абсолютные координаты или координаты относительно текущего активного окна While 1 ; цикл Sleep(10) ; ждем в цикле нажатие F2 чтобы начать или ESC чтобы закончить WEnd Func FindSpot() ; функция которая ищет пиксель(и) указанного цвета $Timer = @MSEC ; засекаем время WinActivate($hwnd) ; Активирует указанное окно (передаёт ему фокус). В нашем случае - Безымянный - Paint $aCoords = FFNearestSpot(10 , 10, 254, 382, $color, 0 ,False,0,146,522,665) ;ищем темно-красный пиксель и заносим найденные в архив $aCoords If Not @error Then ; если нет ошибки то....... $Timer1 = @MSEC ; смотрим время по окончании поиска $Timer2 = ($Timer1 - $Timer) ; вычисляем разницу - выводим время затраченное на поиск ConsoleWrite("Время поиска = "&$Timer&"-ms " &" Координата пикселя = "&$aCoords[0]&", "&$aCoords[1]&", Количество найденных = "&$aCoords[2]&@CRLF) ; пишем в консоль сколько нашли пикселей и в каких координатах MouseMove($aCoords[0], $aCoords[1], 5) ; Ставим курсор мыши на найденный пиксель Else ; в противном случае ConsoleWrite("Ничего не нашли."&@CRLF) ; пишем в консоль что не нашли EndIf ; закончили EndFunc Func End() ; функция для остановки и выхода Exit EndFunc Результат Автоита - Время поиска = 494-ms Координата пикселя = 442, 602, Количество найденных = 24 Кому интересны подробности по Автоиту пишите спрашивайте. В свою очередь надеюсь на взаимную помощь по Хаясму. Нужели в таком мощном инструменте HiAsm для разработки приложений нет ничего подобного? Редактировалось 16 раз(а), последний 2017-05-26 17:05:13 |
|||
карма: -4 |
|
Ответов: 632
Рейтинг: 4
|
|||
Сейчас туже ссылку загрузите, я ускорил программу в 4 раза!
|
|||
карма: 0 |
|
Ответов: 35
Рейтинг: -1
|
|||
Vadimluk1 писал(а): Сейчас туже ссылку загрузите, я ускорил программу в 4 раза! Уточню... так как писал торопясь... А теперь представим что я ищу пиксель в картинке, в цикле изменяя картинку со скоростью 1 раз в миллисекунду, Как думаете успеет ваша программа находить хаотично перемещающийся по картинке пиксель? В реале картинка 1024X768.. В наших примерах разница просто колоссальная! Меньше пол секунды против бесконечности. Но все же спасибо за попытку и за то что поделились Редактировалось 4 раз(а), последний 2017-05-26 18:27:37 |
|||
карма: -4 |
|
Ответов: 871
Рейтинг: 322
|
|||
какая то галиматья.
Редактировалось 2 раз(а), последний 2017-05-26 17:36:56 |
|||
карма: 1 |
|
Ответов: 35
Рейтинг: -1
|
|||
карма: -4 |
|
Ответов: 871
Рейтинг: 322
|
|||
Схему почему то не смог вставить. https://cloud.mail.ru/public/DMva/CgwX9b3YD
|
|||
карма: 1 |
|
Ответов: 632
Рейтинг: 4
|
|||
Красный нашёл быстро, а жёлтый 10-20~ секунд искал.
|
|||
карма: 0 |
|
Ответов: 35
Рейтинг: -1
|
|||
kamakama писал(а): Схему почему то не смог вставить. https://cloud.mail.ru/public/DMva/CgwX9b3YDНу да) Этот поиск работает гораздо быстрее чем у Vadimluk1 но все же очень медленный. Есть возможность прикрутить AutoItx3.dll так как Delphi умеет использовать сторонние dll. Даже делал небольшие эксперименты - работает.. Подключаем dll Autoit к Delphi пользуемся unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} uses ComObj; //Import Source\Rtl\Common\ComObj.pas procedure TForm1.Button1Click(Sender: TObject); var A: Variant; X,Y: Integer; begin A:= CreateOleObject('AutoItX3.Control'); A.PixelSearch(0, 0, 1280, 1024, 16711680, 5, 2); A.MouseMove(155, 93, 20); A.MouseClick('left', 156, 92, 2); end; end. Если бы удалось создать IC с прикрученным к нему AutoItX3.dll Чтобы на вход подавать команды , а на выходе иметь действия , это был бы адский комбайн.. Жаль с библиотекой Владимира Кладова не знаком вообще... --- Добавлено в 2017-05-26 18:14:58 Vadimluk1 писал(а): Красный нашёл быстро, а жёлтый 10-20~ секунд искал.Дело в том что этот поиск ищет по всем пикселям изображения проверяя каждый по отдельности, а это очень долгий процесс, гораздо быстрее бы справился IC со ScanLine , но в данный момент не хватает познаний.. --- Добавлено в 2017-05-26 18:20:40 Что вы имеете в виду под словом ? Уточните. kamakama писал(а): какая то галиматья.Пиксель в окне игы.. Там все очень быстро движется , исчезает, появляется... Нужно найти этот пиксель за сотые доли секунды. Вот и вся задачка. На языке Autoit она решена результат - Время поиска от 0.0001 до 0.09 Очень нужно решение на HiAsm-е Редактировалось 7 раз(а), последний 2017-05-26 18:35:06 |
|||
карма: -4 |
|
Ответов: 5227
Рейтинг: 586
|
|||
Всем здрасьте.
Чего Вы над человеком то глумитесь? Проблему выразил по человечески, нужно ведь путь указать. Serfer78, IC со ScanLine, забудь, там всё равно два цикла. Для быстродействия тебе нужен DIB, вот пример быстродействия картинки с твоим разрешением http://forum.hiasm.com/topic/66225 (но с учётом сравнения а не присваивания будет в ~2-3 раза помедленнее) Короче писать IC всё равно придётся если на скорость расчитываеш или смирись и рисуй дальше Твой IC требует 20-30 строк в сегменте реализации кода с учётом твоих требований. з.ы ни чего не меняется прям как в басне Крылова "Лебедь, Рак и Щука" |
|||
карма: 4 |
|
Ответов: 35
Рейтинг: -1
|
|||
andrestudio писал(а): DIBА вот это уже интересно! Сейчас ознакомлюсь поближе и сразу отпишусь.. Нашел немного информации по этой теме.. http://www.delphigfx.narod.ru/2d/007/2d_7.htm#8 В конце интересный пункт : Выводы... Единственный его минус - обращение к отдельным пикселам. Но написав некоторое количество кода можно обойти это затруднение использовав свойство - ScanLine. А в целом считаю что направление правильное. Что Ж буду экспериментировать, возможно это единственное более менее правильное решение. PS: Если получится достойный код , обязательно поделюсь выложив в этой теме. А кому интересно можете побаловаться с Автоитовским вариантом (Интерфейс как у kamakama) только что на коленке сваял..(ищет в перекрытых и задвинутых за пределы экрана окнах так как работает напрямую с памятью, если поиск в цикле, повторно находит за 0,001 ms) Исходник прилагается Открыть и посмотреть можно в Notepad++. https://cloud.mail.ru/public/6mj7/CBNE95gNP Цвета в таком формате: 0xFFFF00 (желтый) 0x00FF00 (зеленый) 0x00FFFF (голубой) 0x0000FF (синий) 0xFF0000 (красный) можно и в DEC (Десятичном) Офтоп.. Тему не закрываю жду ваших вариантов. И чтобы не быть голословным что в Autoit можно быстро найти пиксель любого цвета в одну строку , напишу пример, работает без подключения доп библиотек Всего 1 строчка: $pixel = PixelSearch(0,0,1024,768,0xFF0000,4,1,$hwnd)
PixelSearch - сама функция поиска 0,0, - верхний угол окна 1024,768, - нижний угол 0xFF0000 - искомый цвет 4, - допустимое отклонения от цвета по всем 3м диапазонам (R,G,B) 1, - шаг поиска в данном случае каждый пиксель $hwnd - заголовок окна в котором ищем Редактировалось 14 раз(а), последний 2017-05-27 01:47:11 |
|||
карма: -4 |
|
Ответов: 35
Рейтинг: -1
|
|||
Vadimluk1 писал(а): Красный нашёл быстро, а жёлтый 10-20~ секунд искал.Можно ускорить если искомый цвет не один пиксель а группа, Просто в циклах поставить шаг скажем 2 вместо одного и будет гораздо быстрее, думаю повожусь пока с этим вариантом. --- Добавлено в 2017-05-26 23:35:33 kamakama Благодарю за отличный пример , буду пока использовать его.. После небольших доработок он показал неплохие результаты. Думаю сделать расширяющийся от центра поиск в указанном регионе экрана.. (можно указать области где вероятность нахождения пикселя более высока). Так же для ускорения можно центр поиска смещать в сторону первого найденного пикселя , (чтобы если вдруг этот пиксель исчезнет и появится снова), не проверять лишние регионы изображения. Вообщем есть над чем подумать... Ну и параллельно буду изучать "DIB и IC" по совету andrestudio . Спасибо от души ребята. Редактировалось 2 раз(а), последний 2017-05-26 23:36:39 |
|||
карма: -4 |
|
Ответов: 537
Рейтинг: 14
|
|||
карма: 4 |
|
Ответов: 35
Рейтинг: -1
|
|||
Sersey писал(а): А если сначала уменьшить исходную картинку, быстро найти приблизительное местоположение пикселя, а потом искать на большой картинке в маленьком квадрате. На все эти действия уходит много времени. Приходится бороться за сотые доли секунд. Преобразование размеров и пересчет координат требуют дополнительных операций, как следствие теряем время в циклах и приходим к тому же результату. Тем более при изменении размера можно потерять часть уникальных пикселей. Лучший вариант это прямой доступ к области памяти, в которой хранится изображение. Как посоветовал andrestudio на данный момент считаю что лучший выход из положения это работа с DIB форматом. Но все же не покидают мысли о ScanLine , даже нарыл кое что.. Но не могу сообразить как впихнуть это в IC. Вариант со ScanLine function GetColorXY(Graphic: TGraphic; Color: TColor; var X, Y: Integer): Boolean; var Bmp: TBitmap; i, j: Integer; Pixel, CmpColor: Cardinal; Scan: Pointer; R, G, B: Byte; begin Result:=false; CmpColor:=ColorToRGB(Color); Bmp:=TBitmap.Create; try Bmp.Assign(Graphic); Bmp.PixelFormat:=pf24bit; for i:=0 to Bmp.Height - 1 do begin Scan:=Bmp.ScanLine[i]; for j:=0 to Bmp.Width - 1 do begin Pixel:=PCardinal(Integer(Scan) + j*3)^; R:=GetBValue(Pixel); G:=GetGValue(Pixel); B:=GetRValue(Pixel); if RGB(R, G, B) = CmpColor then begin Result:=true; X:=j + 1; Y:=i + 1; Exit; end; end; end; finally Bmp.Free; end; end; Кстати с поиском получилось использовал код с форума решил искать кусочек изображения, но возникла проблема с курсором мыши Поиск https://cloud.mail.ru/public/8S5M/CHsf2diR7 Редактировалось 4 раз(а), последний 2017-05-27 23:20:21 |
|||
карма: -4 |
|