[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);
}

}

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)? 
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

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.

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 ?

0

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

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.

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

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ś?

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.

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.

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.

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

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1