Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Поиск изображения в изображении???  (Прочитано 6685 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
abdruxa
Интересующийся

ua
Offline Offline

« : 26-12-2013 21:12 » 

Всем привет. Подскажите как сделать поиск изображения в изображении. Есть два изображения: большое, и маленькое. На большом надо найти маленькое. Например: чтоб на робочем столе программа знала место расположения папок? кто-нибудь сталкивался с такой проблемой?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 26-12-2013 21:37 » 

Ключевое слово "свертка". И приготовься к тому, что инфа будет на английском.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 26-12-2013 23:23 » 

Ну если речь о поиске стандартной иконки без полупрозрачностей, то это и тупым циклом можно сделать. По алгоритму, примерно похожему на поиск подстроки. Берёшь иконку и последовательно прикладываешь к каждому пикселю рабочего стола так, чтобы левый верхний угол иконки попадал на этот пиксель. Дальше начинаешь обходить иконку и сравнивать с фоном. Если на фоне найден отличающийся от иконки пиксель - не найдено, переходишь к следующему пикселю фона. Если все пиксели иконки совпали с фоном, то вот тут на фоне и есть искомая иконка.
« Последнее редактирование: 26-12-2013 23:25 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 27-12-2013 08:58 » 

Чтобы предотвратить возможное изобретение велосипеда, скажу, что существует вот такой инструмент: http://ru.wikipedia.org/wiki/Sikuli
Вопрос только: зачем программе знать расположение папок, если она может открыть папку "Рабочий стол" и найти в ней нужный подкаталог, зная его имя?
Записан
abdruxa
Интересующийся

ua
Offline Offline

« Ответ #4 : 27-12-2013 11:02 » 

От нашол код который мне нада но он очень медленный. Может ктото знает как можна его ускорить?
Код:
Код:
import java.awt.image.BufferedImage;


public class Motor {

 
        int[] findSubimage(BufferedImage im1, BufferedImage im2){
           int w1 = im1.getWidth(); int h1 = im1.getHeight();
           int w2 = im2.getWidth(); int h2 = im2.getHeight();
           assert(w2 <= w1 && h2 <= h1);
           // will keep track of best position found
           int bestX = 0; int bestY = 0; double lowestDiff = Double.POSITIVE_INFINITY;
           // brute-force search through whole image (slow...)
           for(int x = 0;x < w1-w2;x++){
             for(int y = 0;y < h1-h2;y++){
               double comp = compareImages(im1.getSubimage(x,y,w2,h2),im2);
               if(comp < lowestDiff){
                 bestX = x; bestY = y; lowestDiff = comp;
               }
             }
           }
           // output similarity measure from 0 to 1, with 0 being identical
           System.out.println(lowestDiff);
           System.out.println(bestX+" "+bestY);
           // return best location
           return new int[]{bestX,bestY};
           
        }

       

/**
* Determines how different two identically sized regions are.
*/
private double compareImages(BufferedImage im1, BufferedImage im2) {
assert(im1.getHeight() == im2.getHeight() && im1.getWidth() == im2.getWidth());
     double variation = 0.0;
     for(int x = 0;x < im1.getWidth();x++){
       for(int y = 0;y < im1.getHeight();y++){
          variation += compareARGB(im1.getRGB(x,y),im2.getRGB(x,y))/Math.sqrt(3);
       }
     }
     return variation/(im1.getWidth()*im1.getHeight());

}
/**
* Calculates the difference between two ARGB colours (BufferedImage.TYPE_INT_ARGB).
*/
private double compareARGB(int rgb1, int rgb2) {
double r1 = ((rgb1 >> 16) & 0xFF)/255.0; double r2 = ((rgb2 >> 16) & 0xFF)/255.0;
     double g1 = ((rgb1 >> 8) & 0xFF)/255.0;  double g2 = ((rgb2 >> 8) & 0xFF)/255.0;
     double b1 = (rgb1 & 0xFF)/255.0;         double b2 = (rgb2 & 0xFF)/255.0;
     double a1 = ((rgb1 >> 24) & 0xFF)/255.0; double a2 = ((rgb2 >> 24) & 0xFF)/255.0;
     // if there is transparency, the alpha values will make difference smaller
     return a1*a2*Math.sqrt((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2));
}

}

Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 27-12-2013 12:05 » 

abdruxa, "нашёл код" - это мне неинтересно, а особенно неинтересно за безвестного автора заниматься оптимизацией его кода на Java. Где нашёл, там и разбирайся.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 27-12-2013 12:10 » 

abdruxa, а каков размер исходного изображения и фрагмента? Скорее всего, медленно потому, что эти размеры большие (сам перемножь: площадь малого на площадь большого - вот тебе количество итераций по пикселям картинки).
Основных способа три с половиной:
1. Уменьшить (отмасштабировать) оба изображения в нужное число раз (с сохранением уверенного узнавания фрагмента)
1.5 Возможно, getRGB - не самый эффективный способ доступа к изображению, попробовать вариант getRGB, который возвращает массив для работы.
1.5.+ Каждый раз вычислять корень из трёх - не лучшая идея (а учитывая, что он тут вообще во все слагаемые входит - не вижу смысла это делать в принципе, как и некоторые другие действия)
2. Распараллелить код (запускать несколько потоков, каждым обрабатывать свою область)
3. Использовать GPGPU (CUDA, OpenCL)
« Последнее редактирование: 27-12-2013 12:12 от Вад » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines