2013-09-24 6 views
8

Pracuję z bardzo dużymi obrazami TIF, które komponuję w duży pojedynczy obraz. Mam bibliotekę, która została stworzona przez mojego kolegę, który generuje piramidę obrazu i zapewnia bardzo przydatne narzędzie do wizualizacji piramidy obrazu. Wizualizator świetnie nadaje się do osiągania szczytów na dużym obrazie i identyfikacji wizualnej punktów szczególnych, ale klienci są bardziej zainteresowani analizą obrazu na tych dużych obrazach.Java - Jak napisać bardzo duży (20 000 x 20 000 pikseli lub większy) obraz TIF

Dlatego konieczne jest wyeksportowanie bardzo dużego obrazu do jednego pliku. Uważam, że jest to kłopotliwe, biorąc pod uwagę, że obrazy te mogą mieć rozmiar od 800 MB do wielu GB. A zadanie ładowania tego pojedynczego obrazu do pamięci jest trudne, szczególnie podczas analizy obrazu.

Zastanawiam się, czy w java było możliwe zapisanie tego dużego obrazu tiff w sposób blokowy lub liniowy. Obecnie w mojej aplikacji brakuje pamięci na małych (8 GB RAM) komputerach.

Obecna metoda tworzenia tych obrazów jest:

  1. przechowywać wartości pikseli w BufferedImage wykorzystujące WritableRaster

    short[][]pixels = ... 
    BufferedImage image = new BufferedImage(width, height, type); 
    WritableRaster = image.getRaster(); 
    for (int row = 0; row < height; row++) 
    { 
        for (int col = 0; col < width; col++) 
        { 
         raster.setSample(col, row, 0, pixel[row][col]); 
        } 
    } 
    
  2. A potem napisać buforowany obraz na dysku. Do tej części używam ImageJ, aby zapisać obraz jako TIF. Jeśli istnieją lepsze sposoby, które obsługują 16-bitowej skali szarości tif obrazów, wtedy będę szczęśliwy spojrzeć

    // BufferedImage image; from above 
    ... 
    ImagePlus img = new ImagePlus(); 
    img.setImage(image); 
    FileSaver fs = new FileSaver(img); 
    fs.saveAsTiff(file.getAbsolutePath()); 
    

Problem z tej metody jest, że ma zbyt dużego ślad pamięci do 8GB z maszyny RAM.

Idealnie chciałbym mieć tylko jeden singiel short[][]pixels. Dzieje się tak głównie dlatego, że muszę obliczyć średnią funkcję mieszania, więc będzie trochę śladu pamięci. Również w przyszłości dodaję liniową mieszankę. short[][]pixels powinien zająć tylko 765 MB pamięci RAM dla danych o wielkości 20k x 20k pikseli, co moim zdaniem jest obecnie nieuniknione, więc w przypadku większych obrazów, na przykład 100k x 100k pikseli, mam nadzieję, że biolodzy nie będą chcieli eksportować tego obrazu jako wymagałoby to 18 GB pamięci RAM.

Później zmienię kod w celu obsługi eksportu bardzo dużych obrazów, takich jak 100k x 100k. Na razie nie przeszkadza mi założenie jednej pamięci do przechowywania początkowych wartości pikseli.

Co to jest dobra metoda do zapisywania fragmentów obrazu TIF na dysk, więc mogę obsługiwać zapisywanie podstawowych obrazów, takich jak obrazy 100k x 100k.

widziałem tego posta: Write tiled output of TIFF, using ImageIO in Java

Ale to właśnie omawia TIFF 6.0 spec. Ale zajrzę do ImageOutputStreams. Tif jest bestią, więc mogę po prostu odgryźć kulę i zachęcić biologów do eksportowania tylko regionów zainteresowania.

Edycja: Znaleziono opłacalne rozwiązanie:

PISARZ: https://github.com/openmicroscopy/bioformats/blob/v4.4.8/components/scifio/src/loci/formats/out/TiffWriter.java

i

Czytnik: https://github.com/openmicroscopy/bioformats/blob/v4.4.8/components/scifio/src/loci/formats/in/TiffReader.java

strony głównej grupy: https://github.com/openmicroscopy/bioformats

+0

Czy możesz pracować z obrazem w sekcjach, powiedzmy, kwadraty o wielkości kwadratów 10 k pikseli, a następnie scalić je wszystkie razem? –

+0

Nie mam problemu z obsługą kwadratów o wielkości 10k px, problemem jest jak je zapisać do pliku TIF. – Jameshobbs

+0

Powinieneś prawdopodobnie podzielić problem. 1. Napisz duży plik danych obrazu surowego. 2. Przeczytaj to i zapisz jako TIFF. Gdy to zadziała, możesz spojrzeć na to w 1 przebiegu. – hyde

Odpowiedz

2

Ok Znalazłem dobre rozwiązanie, aby zrobić to w Javie.

Dzięki @bdares za wskazanie BigTiff.

Ale w pakiecie z FIJI, istnieje grupa bioformats, która zaimplementowała scifio.

Zapewniają one liczbę obsługiwanych czytników/pisarzy, w którym bycie TiffReader/Writer

https://github.com/openmicroscopy/bioformats/blob/v4.4.8/components/scifio/src/loci/formats/in/TiffReader.java

i

https://github.com/openmicroscopy/bioformats/blob/v4.4.8/components/scifio/src/loci/formats/out/TiffWriter.java

Mam edytowane mój oryginalny komentarz. Dziękuję wszystkim za komentarze, pomogło mi to spojrzeć we właściwym kierunku.

0

Masz podwójną tablicę skrótów. Zamiast przechowywać go w pamięci, należy go przechowywać na dysku i manipulować nim na dysku. BufferedImage nie pomoże. Potrzebujesz biblioteki (lub do napisania biblioteki), która umożliwia manipulowanie obrazem na dysku bez konieczności pełnego wczytywania obrazu do pamięci.

Nie chcesz mieć dostępu do każdej wartości osobno. Zamiast tego będziesz chciał zrobić coś takiego:

  1. odczytać blok (może 4k, 8k lub 40k, co ma sens).
  2. przetwarzać cały blok.
  3. Zapisz blok na dysku.
  4. Goto krok 1 do końca.
+0

Głównym problemem jest tutaj, jak pisać blok po bloku dla obrazu tif. Już teraz zajmuję się pisaniem własnego pisarza tif, ale Tif nie jest najprostszym protokołem, z którego można zrobić pisarza. – Jameshobbs

+0

należy rozważyć utworzenie obrazu w prostszym formacie, a następnie za pomocą narzędzia do konwersji, aby stał się tiff. – DwB

2

W przeciwieństwie do komentarza, nie jest to naprawdę trudne wdrożenie własnego pisarza TIFF.

Specyfikacja jest do pobrania here. W szczególności strony 13-14 są (prawie) wszystkim, czego potrzebujesz, aby zrozumieć, czym jest TIFF i jak go napisać.

Należy wziąć pod uwagę, że zgodnie ze specyfikacją 6.0 (aktualny stan na wrzesień 2013 r.) Maksymalny rozmiar obrazu to 4 GB. Sugerowałbym przejście na numer BigTiff. Różnice w specyfikacji podano na drugim łączu.

+0

To naprawdę bardzo interesujące. Nie wiedziałem, że nagłówek jest ograniczony do 32-bitowych (4GB) rozmiarów. Wygląda na to, że będę musiał przełączyć się z pisania ImageJ do używania pisarza Fidżi (lub po prostu użyć libtiff). – Jameshobbs

3

Dzięki projektowi SCIFIO, generalizujemy obrazowe ramy we/wy systemu Bio-Formats, aby w naturalny sposób kierować obrazowanie naukowe, poza samą mikroskopię i nauki o życiu. Interfejs API SCIFIO znajduje się teraz w wersji beta i może mieć postać includes TIFF, która może oczywiście mieć kafelki w postaci read i write. Opinie na temat API i błędów na SCIFIO mailing list są zawsze mile widziane!

Powiązane problemy