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:
przechowywać wartości pikseli w
BufferedImage
wykorzystująceWritableRaster
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]); } }
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:
i
strony głównej grupy: https://github.com/openmicroscopy/bioformats
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? –
Nie mam problemu z obsługą kwadratów o wielkości 10k px, problemem jest jak je zapisać do pliku TIF. – Jameshobbs
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