Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизПоиск совпадений на изображении Найти похожие ветки
← →
Витя (2012-02-21 14:16) [0]День добрый! Я озадачился поиском совпадений на изображении, подскажите, плиз, куда копать. Дано: скриншот окна (это окно онлайн игры) размером 1280*768. Необходимо найти совпадение на данном скриншоте с эталонным элементом размером 35х35, чтобы знать, куда эмулировать щелчок мышью, ибо в память лезть нельзя. Я делал попиксельным сравнением двух TBitmap через scanline, но это слишком медленно. Даже если считать изображения не совпавшими с несовпадения первой же точки, то это всё равно 983040 итераций цикла, который выполняется непомерно долго. А если встанет задача определить степень соответствия, то ещё дольше.
Подскажите, пожалуйста, более быстрый способ поиска эталонного изображения на моём скриншоте? Мой код приведу чуть позже, пока делфи под рукой нет.
← →
Омлет © (2012-02-21 15:12) [1]
> Я делал попиксельным сравнением двух TBitmap через scanline,
> но это слишком медленно.
Медленно относительно чего?
Думаю, максимум 50 мс без оптимизаций.
← →
AV © (2012-02-21 15:47) [2]а что за игра?
Просто если браузерная - лучше искать ссылки на странице. Проверено лично, пару лет назад на Travian :)
← →
Витя (2012-02-21 15:50) [3]
> Медленно относительно чего?
> Думаю, максимум 50 мс без оптимизаций.
Вообще медленно. Вот мой код:var
NkspWindow: THandle;
bmp, xmp: TBitmap;
x, y: Integer;
function FindEqPix(X, Y: Integer): Boolean;
const FBreak = 0; //Не более FBreak несовпадений
var
m, n: Integer;
EqCount: Integer; //Счётчик совпавших точек
BrCount: Integer; //Счётчик не совпавших точек
c1, c2: PByte;
begin
Result := False;
EqCount := 0;
BrCount := 0;
for m := 0 to xmp.Width do
begin
c1 := xmp.ScanLine[m];
c2 := bmp.ScanLine[X + m];
for n := 0 to xmp.Height do
begin
//Увеличиваем счётчики
if (c1^ = c2^) then Inc(EqCount) else Inc(BrCount);
//Если несовпадений больше FBreak, то выйдем из цикла
if BrCount > FBreak then Break;
ShowMessage(IntToStr(EqCount));
Inc(c1);
Inc(c2)
end;
if BrCount > FBreak then Break;
end; //----------------------
if EqCount > 612 then
begin
//более половины совпадений
//...
ShowMessage("Bingo!");
end;
end;
begin
//Тут ищем окно игры
NkspWindow := FindWindow("Nksp", nil);
if NkspWindow = 0 then Exit;
//Получаем снимок окна игры
bmp := GetWindowCanvas(NkspWindow);
xmp := TBitmap.Create;
//img1 - TImage с искомым изображением
xmp.Width := img1.Width;
xmp.Height := img1.Height;
xmp.Canvas.Draw(0, 0, img1.Picture.Graphic);
with bmp.Canvas do
for x := 0 to bmp.Width do
for y := 0 to bmp.Height do
FindEqPix(x, y);
end;
У меня выполняется долго - более 10 секунд, дальше не считал. Петли нет. Что не так?
← →
Витя (2012-02-21 15:51) [4]
> а что за игра?
> Просто если браузерная - лучше искать ссылки на странице.
> Проверено лично, пару лет назад на Travian :)
Нет, простая РПГ онлайн. С браузерными как-то не сложилось :)
← →
Омлет © (2012-02-21 16:21) [5]
> Витя (21.02.12 15:50) [3]
http://not-doing.ru/some/www.png
Всё неправильно.
← →
Витя (2012-02-21 16:46) [6]Педобир плачет, знач, всё ужасно :) А как правильно?
← →
QAZ (2012-02-21 17:58) [7]
> простая РПГ онлайн.
хочеш стать задротом 100го левела,а времени не хватает?
← →
Витя (2012-02-21 18:10) [8]Ну зачем же оскорблять людей? Задротом я никогда не был, ибо мне уже 43 годика и работаю инженером-технологом пищевого производства. Изучать делфи - моё хобби, не более. Я не программист. Я просто учусь, чтобы мозги не засохли. А вам, молодой человек, я бы посоветовал уважительнее относиться к людям, чтобы они отвечали тем же.
Итак, ввиду вышесказанного, прошу вас, профи, подсказать мне, что неправильно в моём коде и почему так медленно? ЗЫ. Про Free и другие непринципиальные вещи знаю и помню, просто кое-что из кода опустил, когда писал сюда.
← →
Витя (2012-02-21 18:11) [9]
> другие непринципиальные вещи
принципиальные то есть, описАлся
← →
QAZ (2012-02-21 18:21) [10]
> ибо мне уже 43 годика
кстати, самый возраст стать, это я знаю по своим знакомым
> Изучать делфи - моё хобби, не более
нуда, и именно с рпг
← →
brother © (2012-02-21 18:51) [11]http://sourceforge.net/projects/graphics32/
Попробуй это... и не надо изващаться со сканлайном...
← →
Витя (2012-02-21 19:23) [12]Брат, спасибо! :) Посмотрю, что там. Мне, в общем говоря, важна сама реализация, чтобы было, куда глянуть и где научиться. А то как учиться, если нет исходника? Имхо, так быстрее и лучше.
> кстати, самый возраст стать, это я знаю по своим знакомым
По знакомым меня судить решили? Ну да ладно, прощаю =)
> нуда, и именно с рпг
А почему бы и нет? Если задача стала мне интересна, а как решить - не знаю, то почему бы и не взяться? Кстати, если думаете, что я бота пишу, то ошибаетесь, батенька :) Всё куда прозаичнее.
← →
Sapersky (2012-02-21 19:37) [13]А как правильно?
Всем битмапам установить PixelFormat := pf24bit. Иначе работаем C DDB, у которых доступ к пикселям очень медленный.
Цикл по Y должен быть внешним, по X - внутренним. Все циклы до Width-1/Height-1, в FindEqPix до Width*3-1, поскольку 3 байта на пиксель, или сравнивать по 3 сразу.
Можно также попробовать 32-битные картинки (pf32bit), при этом с пикселем можно работать как с PInteger и без особых извращений сравнивать по 1 пикселю одной командой. Возможно, будет быстрее.
← →
brother © (2012-02-21 19:57) [14]> Мне, в общем говоря, важна сама реализация,
зачем изобретать велосипед? библиотек для быстрой работы с битампами - завались...
← →
Витя (2012-02-22 00:14) [15]
> Sapersky
Спасибо огромное! Именно этой информации мне и не хватало! Завтра сяду, обмозгую и, возможно, напишу что-то лучшее. Не хватало, в общем, теории. Как сделаю, напишу здесь.
> библиотек для быстрой работы с битампами - завались...
Согласен. Однако, библиотеки не научат писать самостоятельно. А у меня с этим, как видите, проблемы :)
← →
QAZ (2012-02-22 11:16) [16]а собственно, эталон может вращаться?
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.661 c