2013-09-24 103 views
8

Tôi đang làm việc với hình ảnh tif cực lớn mà tôi đang sáng tác thành một hình ảnh đơn lớn. Tôi có một thư viện được tạo ra bởi một đồng nghiệp của tôi tạo ra kim tự tháp hình ảnh và cung cấp một công cụ rất tiện dụng để hình dung kim tự tháp hình ảnh. Trình hiển thị này rất tuyệt vời khi chụp ảnh cao điểm ở hình ảnh lớn và xác định các điểm quan tâm trực quan, nhưng khách hàng quan tâm nhiều hơn đến việc phân tích hình ảnh trên những hình ảnh lớn này.Java - Cách viết hình ảnh tif rất lớn (20.000x20.000 px hoặc lớn hơn)

Do đó, cần phải xuất hình ảnh rất lớn thành một tệp. Tôi thấy điều này là phiền hà khi xem xét những hình ảnh này có thể ở bất kỳ đâu từ 800 MB đến nhiều GB. Và chỉ nhiệm vụ tải hình ảnh này vào bộ nhớ là khó khăn, đặc biệt khi phân tích hình ảnh đang được thực hiện.

Tôi đã tự hỏi, nếu nó có thể trong java để viết hình ảnh tiff lớn này trong một khối hoặc line-by-line thời trang. Hiện tại, ứng dụng của tôi đang hết bộ nhớ trên các máy nhỏ (8 GB RAM).

Phương pháp hiện hành đối với sáng tác những hình ảnh này là:

  1. Store giá trị pixel thành một BufferedImage sử dụng một 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. Và sau đó viết hình ảnh đệm vào đĩa. Đối với phần này tôi đang sử dụng ImageJ để viết hình ảnh dưới dạng tif. Nếu có những cách tốt hơn để hỗ trợ 16-bit hình ảnh tif màu xám, sau đó tôi sẽ được hạnh phúc để có một cái nhìn

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

Vấn đề với phương pháp này là nó có quá lớn của một bộ nhớ cho một 8GB của máy RAM.

Lý tưởng nhất những gì tôi muốn là chỉ cần có một đơn short[][]pixels. Điều này chủ yếu là vì tôi cần tính toán một hàm pha trộn trung bình, do đó một số dấu vết bộ nhớ sẽ xuất hiện ở đó. Cũng trong tương lai tôi sẽ thêm một hỗn hợp tuyến tính. short[][]pixels chỉ mất ~ 765 MB RAM cho dữ liệu pixel 20k x 20k, mà tôi nghĩ hiện không thể tránh khỏi, vì vậy đối với hình ảnh lớn hơn ví dụ 100k x 100k pixel, tôi hy vọng rằng các nhà sinh học sẽ không muốn xuất hình ảnh này nó sẽ chiếm 18GB RAM.

Sau đó, tôi sẽ sửa đổi mã để hỗ trợ xuất các hình ảnh cực lớn như 100k x 100k. Bây giờ tôi ổn với giả sử một phần của bộ nhớ để lưu trữ các giá trị pixel ban đầu.

Vì vậy, một phương pháp tốt để viết các phần của hình ảnh tif vào đĩa là gì để tôi có thể hỗ trợ viết ra các hình ảnh cốt lõi như hình ảnh 100k x 100k.

tôi đã xem bài này: Write tiled output of TIFF, using ImageIO in Java

Nhưng nó chỉ thảo luận về TIFF 6.0 spec. Nhưng tôi sẽ xem xét ImageOutputStreams. Tif là một con thú mặc dù vậy tôi có thể chỉ cần cắn viên đạn và khuyến khích các nhà sinh học chỉ xuất khẩu các khu vực quan tâm.

EDIT: tìm thấy một giải pháp khả thi:

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

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

trang nhóm chính: https://github.com/openmicroscopy/bioformats

+0

Bạn có thể làm việc với hình ảnh trong các phần, giả sử 10k ô vuông px sau đó hợp nhất chúng lại với nhau không? –

+0

Tôi không có vấn đề khi làm việc với hình vuông 10k px, vấn đề là cách viết chúng vào một tệp tif. – Jameshobbs

+0

Bạn có lẽ nên phân chia vấn đề. 1. Viết một tệp dữ liệu hình ảnh thô lớn. 2. Đọc và lưu dưới dạng tiff. Khi công trình đó hoạt động, bạn có thể xem xét việc thực hiện nó trong 1 lần. – hyde

Trả lời

2

Ok tôi đã tìm thấy một giải pháp tốt để làm điều này trong Java.

Nhờ @bdares chỉ ra BigTiff.

Nhưng được đóng gói với FIJI, có nhóm bioformats đã triển khai scifio.

Họ cung cấp một số hỗ trợ đọc/nhà văn, một trong đó là một TiffReader/Writer

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

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

Tôi đã chỉnh sửa niêm yết ban đầu của tôi. Cảm ơn tất cả các ý kiến, nó đã giúp tôi tìm đúng hướng.

0

Bạn có một mảng kép ngắn. Thay vì lưu trữ nó trong bộ nhớ, bạn cần lưu trữ nó trên đĩa và thao tác nó trên đĩa. BufferedImage sẽ không giúp ích gì. Bạn cần một thư viện (hoặc để viết một thư viện) cho phép thao tác của một hình ảnh trên đĩa mà không cần phải tải đầy đủ hình ảnh vào bộ nhớ.

Bạn không muốn truy cập từng giá trị riêng lẻ. Thay vào đó, bạn sẽ muốn thực hiện một việc như sau:

  1. đọc một khối (có thể 4k, 8k hoặc 40k có ý nghĩa gì).
  2. xử lý toàn bộ khối.
  3. ghi khối vào đĩa.
  4. goto bước 1 cho đến khi hoàn tất.
+0

Vấn đề chính ở đây là làm thế nào để viết block-by-block cho một hình ảnh tif. Tôi đã xem xét việc viết nhà văn tif của riêng mình, nhưng tif không phải là giao thức đơn giản nhất để tạo ra một nhà văn. – Jameshobbs

+0

xem xét việc tạo hình ảnh ở định dạng đơn giản hơn, sau đó sử dụng công cụ chuyển đổi để biến nó thành hình chữ nhật. – DwB

2

Trái với nhận xét của bạn, thực sự không khó để triển khai tác giả TIFF của riêng bạn.

Thông số kỹ thuật có thể tải xuống here. Cụ thể, các trang 13-14 (gần như) tất cả những gì bạn cần để hiểu TIFF là gì và cách viết nó.

Hãy xem xét theo thông số 6.0 (hiện tại là tháng 9 năm 2013), kích thước hình ảnh tối đa là 4GB. Tôi muốn đề nghị chuyển sang BigTiff. Sự khác biệt về thông số được liệt kê trên liên kết thứ hai.

+0

Điều này thực sự rất thú vị. Tôi không biết rằng tiêu đề được giới hạn ở kích thước 32 bit (4GB). Có vẻ như tôi sẽ phải chuyển từ viết ImageJ sang sử dụng nhà văn của Fiji (hoặc chỉ sử dụng libtiff). – Jameshobbs

3

Với dự án SCIFIO, chúng tôi đang khái quát hóa khung hình I/O hình ảnh Bio-Formats để nhắm mục tiêu hình ảnh khoa học nói chung, ngoài chỉ là kính hiển vi và khoa học đời sống. API SCIFIO hiện đang trong giai đoạn thử nghiệm và includes TIFF có thể là tất nhiên readwrite trong ô. Phản hồi về API và lỗi trên SCIFIO mailing list luôn được chào đón!