[BufferedImage]optymalizacja operacji graficznych

[BufferedImage]optymalizacja operacji graficznych
0

Jak dotąd wszelkie operacje wykonuję wg schematu:
<code = java>
BufferedImage dana;
int[] rgb=new int[3];
for(int i=0; i<dana.getWidth();i++){
for(int j=0; j<dana.getHeight();j++{
int tmp=dana.getRGB(i,j)&0xffffff; //usuwam alfę
rgb[0]=(tmp>>16)&0xff; //r
rgb[1]=(tmp>>8)&0xff; //g
rgb[2]=tmp&0xff; //b

     //jakieś działania(zmiana jasności/kontrast/gamma/konwersje/obroty/odbicia)

     tmp=rgb[0]<<16|rgb[1]<<8|rgb[2]|0xff<<24;
     dana.setRGB(i,j,tmp);
}

}

Kopiuj
Działa to strasznie powoli szczególnie gdy obrazek jest duży(np 3000x3000) a trzeba z nim zrobić coś wymagającego kilku obliczeń.

Czy da się to przyspieszyć nie używając wyspecjalizowanych klas(nie wolno mi)? 
LN
  • Rejestracja:około 16 lat
  • Ostatnio:około rok
  • Postów:1398
0

Coś nie tak masz z tymi pętlami "for" :> (chyba coś się nie wkleiło).

Możesz to rozbić na wiele wątków, powinno być szybiciej - np dzielisz obrazek na 5 "kolumn" o szerokości szer_obr/5 każda i tworzysz 5 wątków, które działają na poszczególnych kolumnach.
A na końcu dopiero wpisujesz dane do BufferedImage (już po zakończeniu operacji przez wątki).
P.S.
Może użyj tego ? http://download.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html#setRGB%28int,%20int,%20int,%20int,%20int[],%20int,%20int%29

edytowany 1x, ostatnio: [losowa nazwa]
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
0

[losowa]:
+1 tyle, że nie dzielić na kolumny a na rzędy. Dane obrazu z reguły są zapisywane w pamięci wierszami, więc odczyt i zapis powinien być szybszy całymi wierszami.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
0

Czyli tylko wielowątkowo da się to przyspieszyć?
Inaczej mówiąc przy obrazku 3000x3000 suma wykonań pętli(w rdzeniach) musi być równa 9000000 ?

LN
  • Rejestracja:około 16 lat
  • Ostatnio:około rok
  • Postów:1398
0

Jest taka regułka, że wątków powinno być tyle, co rdzeni - 1.

edytowany 2x, ostatnio: [losowa nazwa]
0

Tak, to rozumiem.

Mi chodziło bardziej o to czy da się zmniejszyć ilość obrotów pętli?(wydaje mi się, że się nie da, ale wolę zapytać).
Bo dla obrazka axb wychodzi ab obrotów, a jak rozdzielę na kilka wątków to i tak suma obrotów będzie ab.

lipkerson
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad 2 lata
0

wiesz - ja miałem prace mgr inz. z przetwarzania obrazów i pisałem w javie to. Skupiałem sie na zagadnieniu segmentacji które jest bardzo ale to bardzo czasochłonne. Wielowymiarowe i nieregularne piramidy - owszem mniejsza rozdzielczośc bo z kamerki 640 na 400 i pozyskiwanie wartosci pojedycnzych pikseli sposób taki jak Ty masz. Schodziłem do 80 milisekund na klatkę...na procku pentium celeron 1300 z 378 mb ramu więc...

  1. zdefiniuj co to jest długo u Ciebie
  2. upewnij się że wielokrotnie nie robisz tych samych operacji (pętle for...wywolywane potem kolejne pętle for i kolejne - w przetwarzaniu obrazu bardzo latwo o takie coś)
    3, wrzuć timera i faktycznie podaj ile milisekund to zajmuje
  3. upewnij sie czy po obliczeniach metody wymiarujace/postproceowe przygotowywujace do wyświetlenia w panelu są poprawne i sztucznie nie przetwarzają po raz kolejny całosći obrazu
  4. Rozbicie na wątki daruj sobie - próbowałem to i w javie chyba nie ma optymalizacji do przetwarzania obrazu...watki zastosuj w rozpoznawaniu wzorców bo to fakt - przyspiesza

pozdro


Another jam from the world for the jam from the voices of the world......
lipkerson
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad 2 lata
0

a powiedz mi - jak masz już wartosci pikseli to zapisujesz je w tablicy jakięś dwuwymiarowej by potem coś z nimi robic - jakiś filtr 3x3 np. nakladac albo coś?


Another jam from the world for the jam from the voices of the world......
LN
  • Rejestracja:około 16 lat
  • Ostatnio:około rok
  • Postów:1398
0

Owszem, po rozbiciu na wątki będzie tyle samo obrotów pętli, ale w teorii program wielowątkowy może dane zadanie wykonać szybciej - choćby właśnie przez to, że w danej chwili kilka rdzeni wykonuje operacje ROWNOLEGLE a nie jeden rdzen robi wszystko SEKWENCYJNIE.

edytowany 1x, ostatnio: [losowa nazwa]
lipkerson
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad 2 lata
0

W teorii niestety - przetestowałem na dwóch rdzeniach - z niewiadomych powodów przy przetwarzaniu obrazu zawsze wsio laduje na jednym rdzeniu. Drugi owszem zajmie się innymi rzeczami jak są inne do roboty i to jest to szybciej-ale to są grosze.

Jedynym usprawnieniem jest to by nie zapisywac w tablicach - ktore (sam sprawdziłem ale tez to pierw przeczytałem) są realtywnie wolno do tego typu obliczeń. Wyszły biblioteki to przetwarzania danych w sensie apisywania danych wartości pikseli do konstrukcji tablicopodobnych-potem super szybko mozna przetwarzac dowolne bloki pikseli-oszczednośc 50% w porównaniu z tablicami . Już nie pamiętam nazw ale mogę poszukać jak chcesz.

Fakt jest jeden - sam odczyt wartości z obrazu szybszy nie będzie.


Another jam from the world for the jam from the voices of the world......
edytowany 1x, ostatnio: lipkerson
0

Wolno to dla mnie 3s przy zmianie gammy dla obrazka 3000x3000 kiedy gimp robi to "natychmiastowo".
Myślałem, że różnica wynika z tego, że gimp jakoś zmniejsza liczbę obrotów, ale skoro mówisz, że robi się tak jak mam to zapuszczę profiler i pobawię się poprawą implementacji.

Jak już mam te składowe to trzymam je w tablicy int[3].

Wielkie dzięki za odpowiedzi.

lipkerson
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad 2 lata
0

chyba int[max][maxy][3] ? to jest to co Cię tak spowalnia....tzn oczywiście relatywnie hehe postaram się odkopać nazwy tych struktur archiwizującyh - może Ci to przyspieszy obliczenia.

Gimp to gimp - pewnie wiele rzeczy mają poprogramowanych maszynowo. A nie jak java - nadbudówka nad nadbudówką :) Najlepiej to jeszcze w virtualboxie odpalic:P


Another jam from the world for the jam from the voices of the world......
edytowany 1x, ostatnio: lipkerson
0

Nie, ja w środku pętli na bieżąco liczę co się ma dziać i podmieniam piksel.

W każdym razie wielkie dzięki.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.