Porównywanie plików graficznych

Porównywanie plików graficznych
0

Planuję zrobić pewien programik, tylko nie wiem jak zrobić jedną rzecz. Otóż muszę porównać dwa pliki graficzne. Program robi zrzut ekranu (obraz np 1000px na 500px) i szuka na nim obrazu mniejszego (np. 40px na 10px), a po znalezieniu klika na współrzędne pkt o 15px wyżej niż współrzędne miejsca gdzie znalazł mniejszy obraz na większym. Bardzo proszę o pomoc.

0

Sądząc po ilości odpowiedzi widzę, że może być z tym problem, więc może chociaż ktoś wie jak sprawdzać kolor pikseli na ekranie. Np piksel (90, 100) jest biały to robi coś a jak zielony to coś innego.

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Po zrzucie ekranu dostajesz BufferedImage, poczytaj dokumentację http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html (metoda getRGB).


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
airborn
  • Rejestracja:ponad 15 lat
  • Ostatnio:prawie 7 lat
  • Postów:274
0

Widziałem rozwiązania pierwotnego problemu (wyszukiwanie mniejszego obrazu w większym) dość łatwo implementowane w OpenCV. Skoro teraz OpenCV ma bindini do Javy to możesz spróbować pod tym kątem poszukać.

0

Może to też być szukanie małego obrazu na ekranie, niekoniecznie na większym obrazie.

airborn
  • Rejestracja:ponad 15 lat
  • Ostatnio:prawie 7 lat
  • Postów:274
0

'Na ekranie' niczego nie znajdziesz, musisz zrobić printscreena, a wtedy to już nie jest ekran tylko de facto duży obrazek.

0

Dzięki wielkie za propozycje rozwiązania problemu, ale jakoś nie mogę do tego dojść

airborn
  • Rejestracja:ponad 15 lat
  • Ostatnio:prawie 7 lat
  • Postów:274
0

Kurcze, mi to zajęło nie całe 5 minut http://stackoverflow.com/a/17516753
Jeżeli chcesz kompleksowego rozwiązania które będzie screenshoty robić, znajdywać obrazki i klikać to możesz też na Sikuli popatrzeć.

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Przecież robienie screenshotów jest trywialne. Metoda createScreenCapture w klasie Robot.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
0

Mówię o szukaniu obrazka mniejszego na większym, screeny umiem ;)

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Ten mniejszy w większym to musi się dokładnie zgadzać (identyczne składowe RGB), czy też dopuszczalne są pewne różnice? Tak czy owak możesz porównywać punkt po punkcie każdy podprostokąt większego obrazka mający odpowiedni rozmiar z małym obrazkiem.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
0

Dobra już wiem, bardzo dziękuję, jak będą jakieś problemy z programem to jeszcze się Was poradzę.

0

Tło obrazka się zmienia :/

0

OpenCv i fraza w google "find smaller image in bigger image" ewentualnie "find feature in image". Na pewno znajdziesz jakiegoś gotowca, na którym możesz się oprzeć.

0

Mam taki kod:

Kopiuj
import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

class MatchingDemo {
    public void run(String inFile, String templateFile, String outFile, int match_method) {
        System.out.println("\nRunning Template Matching");

        Mat img = Highgui.imread(inFile);
        Mat templ = Highgui.imread(templateFile);

        // / Create the result matrix
        int result_cols = img.cols() - templ.cols() + 1;
        int result_rows = img.rows() - templ.rows() + 1;
        Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);

        // / Do the Matching and Normalize
        Imgproc.matchTemplate(img, templ, result, match_method);
        Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());

        // / Localizing the best match with minMaxLoc
        MinMaxLocResult mmr = Core.minMaxLoc(result);

        Point matchLoc;
        if (match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED) {
            matchLoc = mmr.minLoc;
        } else {
            matchLoc = mmr.maxLoc;
        }

        // / Show me what you got
        Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),
                matchLoc.y + templ.rows()), new Scalar(0, 255, 0));

        // Save the visualized detection.
        System.out.println("Writing "+ outFile);
        Highgui.imwrite(outFile, img);

    }
}

public class TemplateMatching {
	public static void main(String[] args) {
        new MatchingDemo().run("lena.png", "template.png", "templatematch.png", Imgproc.TM_CCOEFF);
    }
}

tylko nie wiem czemu nie działa, błąd:

Kopiuj
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.opencv.highgui.Highgui.imread_1(Ljava/lang/String;)J
	at org.opencv.highgui.Highgui.imread_1(Native Method)
	at org.opencv.highgui.Highgui.imread(Highgui.java:359)
	at bot.MatchingDemo.run(Bot.java:16)
	at bot.Bot.main(Bot.java:51)

wszystko stąd: http://stackoverflow.com/questions/17001083/opencv-template-matching-example-in-android/17516753#17516753

0

Tam w błędzie zamiast Bot.java jest TemplateMatching.java

Olamagato
  • Rejestracja:ponad 16 lat
  • Ostatnio:11 dni
  • Lokalizacja:Polska, Warszawa
  • Postów:1058
0

Tak naprawdę, to wcale nie chcesz porównywać plików graficznych, a obrazy, które są w nich zawarte. Plik graficzny zawiera nagłówek i dodatkowe informacje, które wcale nie muszą Cię interesować, albo są wręcz zbędne. Tak więc najpierw musisz pokonać problem wczytania do pamięci obrazów (mapy bitowej) z tych plików, żeby w ogóle mówić o szukaniu jednych obrazów w innych. Na szczęście w przypadku typowych plików Java robi to za Ciebie.

Najprostsza metoda wyszukiwania to porównywanie pikseli prostokąta wycinka. Działa jeżeli szukany obraz jest co do bita/piksela zgodny z obrazem większym. To znaczy w przypadku gdy szukany obrazek jest faktycznie wycinkiem oryginalnego obrazu. Wtedy iterujesz przez kolejne współrzędne x oraz y szukając dopasowania piksela np. lewego górnego rogu, a następnie pozostałych pikseli dla potwierdzenia lub odrzucenia znalezienia wycinka. Jako optymalizację można najpierw porównywać wartości pikseli wszystkich rogów oraz ewentualnie wybranego piksela ze środka (sprawdzenie 4-5 pikseli jest dość tanie, a pozwala szybko wykluczyć).
Kwestia rozłożenia iteracji - najpierw wierszami lub kolumnami, albo skanowanie najpierw co którąś linię pikseli - jest kwestią optymalizacji i dominującej zawartości obrazów. Na przykład jeżeli jest bardziej prawdopodobne znalezienie wycinka w środku obrazu, a nie na jego brzegach, to najpierw zaczyna się skanowanie od środka obrazu (np. podziel każdą współrzędną obrazu na 4 i zacznij przeszukiwanie od 2. i 3. ćwiartki). Ważne że trzeba przeskanować w taki sposób, aby matematycznie wykluczyć możliwość pominięcia.

W praktyce wyszukiwanie elementów obrazów nie jest nigdy tak proste ponieważ choćby użycie kompresji powoduje niewielkie zaburzenie chrominacji lub luminacji. W efekcie wycinki przestają być zgodne co do pikseli i wycinek nie zostanie znaleziony. Mimo iż człowiek bez problemu go zauważy. Żeby to pominąć można użyć dwóch sposobów:

Pierwszy polega na osłabianiu jakości pikseli. Na przykład przez zmniejszenie dokładności porównywania pikseli. Najprościej mówiąc każda składowa piksela RGB posiada przeznaczoną pewną ilość bitów na składową - typowo 8, 6, 5 lub 4 bitów zależnie od tego czy kolor piksela zakodowany jest w 32, 24, 16 czy 12 bitach. Można łatwo zmniejszyć jakość i tym samym dokładność porównywania przez przekodowanie każdego piksela obrazu i wycinka do celowo zmniejszonej jakości - np. po 4 bity na składową, co daje 12 bitów RGB. Przekodowanie jest dość proste ponieważ każda składowa, to po prostu liczba 0-255 (8-bitów), którą można proporcjonalnie zmniejszyć do zakresu 0-15 (4-bity). Wtedy tak zredukowany piksel wycinka można już porównywać z podobnie zredukowanym pikselem obrazu. Metoda ta załatwia problem nie tylko artefaktów, ale również różnej jakości obrazów ponieważ dolną granicą dokładności jest redukcja do zakresu 0-1, czyli 1-bit na składową, a cały piksel sprowadza się wtedy do 3 bitów. W ten sposób można znaleźć wycinki "prawdopodobne", które będą trudne do szybkiego wyszukania nawet przez człowieka.

Drugą, alternatywną metodą - która jest jednak obliczeniowo bardziej wymagająca - jest konwersja wszystkich pikseli obrazu (oraz wycinka) do modelu HSL. Następnie porównywanie nie całych pikseli, lecz wyłącznie składowych barwy (hue) oraz nasycenia barwy (saturation) pomijając jasność (lightness). Można też do określenia zgodności użyć dobranych arbitralnie wag barwy, nasycenia i jasności, dzięki czemu można znaleźć kolorowy wycinek na zdjęciu w sepii, monochromatyczny wycinek na zdjęciu kolorowym lub wycinki będące napisami, albo jakąś uproszczoną grafiką. Ewentualnie można użyć zupełnie innej kombinacji aby wyszukać celowo ukryte przed człowiekiem wycinki obrazu (można na przykład użyć samej luminacji do wyszukiwania w teście podobnym jak ten na daltonizm). Możliwości kombinowania w wyszukiwaniu obrazów są całkiem spore.

Co do Twojego ostatniego elementu zadania - jeżeli znajdziesz współrzędne na przykład lewego górnego wycinka w obrazie, to określenie współrzędnej do kliknięcia jest zwykłym dodawaniem lub odejmowaniem współrzędnej pionowej np. lewego górnego rogu lub środka górnej krawędzi znalezionego wycinka.

ps. Jakoś nie zauważyłem, że wątek ma już dwie strony. To co napisałem jest mniej więcej "automagicznie" robione w tym kodzie, który już masz.


Jeżeli ktoś komuś coś, ewentualnie nikt nikomu nic, to właściwie po co...?
edytowany 2x, ostatnio: Olamagato
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)