Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск картинок на экране, Распознавание образов 
V
    Опции темы
Anyone
Дата 23.11.2010, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Работаю с Веб-приложением и всю монотонную работу хочу переложить на плечи процессора.
Требуется найти определенные кнопки на экране и по алгоритму выполнять их нажатие в нужный момент.
Проблема в том, что поиск заданной картинки по образцу происходит очень медленно.
Все картинки-образцы я храню как массив типа байт, а вот скриншот в массив записать не удалось - программа загружает процессор на 50% и работает оч длительное время (не могу дождаться даже). 
Есть какая-нить другая идея, кроме поиск подмассива в массиве и использования функции: robot.getPixelColor(x,y).getRGB()?

Вот кусок кода, на котором зависает приложение (2я строка):
Код

        BufferedImage bufferedImage = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
        byte [] t = ((DataBufferByte)(bufferedImage).getRaster().getDataBuffer()).getData();

PM MAIL   Вверх
Temdegon
Дата 23.11.2010, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 429
Регистрация: 11.10.2008
Где: Minsk

Репутация: 7
Всего: 9



Если нужно покликать кнопки в веб-приложении, может не нужно и городить этот огород с распознаванием и роботом? 
Вот к примеру эта либа http://htmlunit.sourceforge.net/ вполне неплохо выполняет функции браузера. Можно без проблем найти кнопку по id и вызвать на ней button.click()
вот пример сабмита формы из их getting started:
Код

public void submittingForm() throws Exception {
    final WebClient webClient = new WebClient();

    // Get the first page
    final HtmlPage page1 = webClient.getPage("http://some_url");

    // Get the form that we are dealing with and within that form, 
    // find the submit button and the field that we want to change.
    final HtmlForm form = page1.getFormByName("myform");

    final HtmlSubmitInput button = form.getInputByName("submitbutton");
    final HtmlTextInput textField = form.getInputByName("userid");

    // Change the value of the text field
    textField.setValueAttribute("root");

    // Now submit the form by clicking the button and get back the second page.
    final HtmlPage page2 = button.click();

    webClient.closeAllWindows();
}

PM MAIL   Вверх
Anyone
Дата 24.11.2010, 01:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Спасибо за пример, может пригодится для другой задачи, но не этой.
Единственный вопрос: возможно ли с помощью этой либы получить доступ к таблице, которая является отдельной компонентой, используемой в JSF и полистать странички, покликать по ячейкам? 

По поводу сабжа. Я думал о написании своего браузера, но проблем 3:
1. Протокол не http, a https, в браузер необходимо импортировать сертификаты;
2. Кнопочки (они выгружают файлы) находятся в колонке многостраничной таблицы, причем на каждой странице может быть разное их ко-во а потому и расположение тоже разное (пустые строки имеют меньшую высоту и в этом вся проблема, иначе задачу б давно решил);
3. Все кнопки имеют одинаковое название.

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

PM MAIL   Вверх
Temdegon
Дата 24.11.2010, 01:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 429
Регистрация: 11.10.2008
Где: Minsk

Репутация: 7
Всего: 9



Мммда. Какие-то непонятные у вас желания - браузеры писать, образы распознавать...
Напишите конкретно, для чего вам это нужно. Нужно скачать все файлы с какого-то сайта? или вы хотите написать браузер, что бы тестировать свое веб-приложение?
Вот там же пример обхода таблицы
http://htmlunit.sourceforge.net/table-howto.html
Я с этой либой работал очень поверхностно, в дебри не влезал. Что она может и что не может разбирайтесь уж сами. Ну или пишите браузер или распознаватель образов  smile 
PM MAIL   Вверх
Anyone
Дата 24.11.2010, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Цитата(Temdegon @  24.11.2010,  01:40 Найти цитируемый пост)
Нужно скачать все файлы с какого-то сайта?

Да, именно это.
Если либа умеет работать с протоколом https и можно импортировать сертификаты - можно ее попробывать.
PM MAIL   Вверх
Anyone
Дата 24.11.2010, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Все рисунки, в том числе скрин экрана, представляю как массив байтов с помощью функции:
Код

    public byte [] ImageToBytesArray(BufferedImage bufferedImage, String type){
        byte[] t=null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try{
            ImageIO.write(bufferedImage, type, baos );
            baos.flush();
            t = baos.toByteArray();
            baos.close();
        }catch(Exception e){
            System.out.println(e);
        }
        return t;
    }

Для поиска координат изображения ищу подмассив в массиве. Работает очень быстро, но ничего не нахожу. Может так вообще делать нельзя?
Код

private boolean FindNextButton(){
...
                boolean result=false;
        BufferedImage bufferedImage = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
        byte [] t = ImageToBytesArray(bufferedImage,"bmp");
        for (int i=0;i<t.length;i++){
            if (isImageOnScreen(i,t,pixelArrayNext, biNext.getWidth(), biNext.getHeight())){
                result=true;
                                ...
            }
  return result;
}

    private boolean isImageOnScreen(int index, byte [] arrayScreenPixels, byte [] arrayImagePixels, int width, int height){
        for (int i=0; i<arrayImagePixels.length; i++){
            if (arrayImagePixels[i]!=arrayScreenPixels[i+index])
                return false;
        }
        return true;
    }


Это сообщение отредактировал(а) Anyone - 24.11.2010, 13:39
PM MAIL   Вверх
jk1
Дата 24.11.2010, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Откуда берется pixelArrayNext и что он из себя представляет?


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
Anyone
Дата 24.11.2010, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Цитата(jk1 @  24.11.2010,  14:27 Найти цитируемый пост)
Откуда берется pixelArrayNext и что он из себя представляет? 


Это искомая картинка, представленна как массив байов:

Код

BufferedImage biNext;
byte[] pixelArrayNext;
...
file = new File(PATH_NEXT_IMAGE);
if (file.exists())
  biNext = ImageIO.read(file);
else return;
//pixelArrayNext = ((DataBufferByte)(biNext).getRaster().getDataBuffer()).getData();
pixelArrayNext = ImageToBytesArray(biNext,"bmp");



Очевидно, что функция ImageToBytesArray() возвращает массив байтов не самой картинки, а объекта типа BufferedImage.
Как получить необходимый массив?
Тот способ, что в ремарках - очень медленный для всего разрешения экрана и потому не подходит:
//pixelArrayNext = ((DataBufferByte)(biNext).getRaster().getDataBuffer()).getData();


Это сообщение отредактировал(а) Anyone - 24.11.2010, 14:51
PM MAIL   Вверх
jk1
Дата 24.11.2010, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Формат BMP помимо прочего содержит заголовок и палитру, может даже быть сжат (RLE), поэтому искать подмассив в массиве просто считав два файла бессмысленно. Небольшой пример:

Полное изображение: Заголовок + некоторая часть изображения + то, что мы пытаемся распознать + еще что-то

Ваш шаблон, который вы пытаетесь обнаружить: Заголовок + то, что мы пытаемся распознать.

Очевидно, что второго в первом Вы не найдете.

Это сообщение отредактировал(а) jk1 - 24.11.2010, 15:10


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
Temdegon
Дата 24.11.2010, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 429
Регистрация: 11.10.2008
Где: Minsk

Репутация: 7
Всего: 9



Цитата

Да, именно это.
Если либа умеет работать с протоколом https и можно импортировать сертификаты - можно ее попробывать. 

Я на 99% уверен, что умеет. Но лично за вас искать не буду. Если вам кажется, что написать свой браузер будет проще и надежнее, чем рассмотреть другие варианты - ваше дело.
Кроме этого, есть масса других способов. Можно внимательно посмотреть html и javascript страницы, и понять, как он устроен. Я знаю десятки примеров, когда люди на PHP+curl делали клоны очень сложных сайтов. И это при том, что курлу до htmlUnit как до луны пешком.
Вот еще вам пища для размышлений:
Код

javascript:allLinks=document.getElementsByTagName('a'); str=""; for (i=0; i<allLinks.length; i++) {str+=allLinks[i]+"\n";}; alert(str);

вставьте в строку браузера, нажмите enter и получите все ссылки с открытой страницы . Очевидно, что даже таким убогим способом можно выдрать с любой страницы любые данные. А если поставить к браузеру FireBug, то возможности вообще безграничны
PM MAIL   Вверх
Anyone
Дата 25.11.2010, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Нашел решение похожей задачи. Попробую и отпишусь.
PM MAIL   Вверх
Anyone
Дата 25.11.2010, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Поиск происходит мгновенно, всем спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0547 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.