OpenIMAJ 库无法读取 tiff 文件?

OpenIMAJ library cannot read tiff files?

我正在使用 OpenIMAJ 库,它在 "JPEG" 和 "PNG" 文件上运行良好,但在 tiff 文件上它给我一个错误。这是代码:

import org.openimaj.image.ImageUtilities;
import org.openimaj.image.MBFImage;

....

File file = new File("/home/mosab/Desktop/input/tif.tif");
MBFImage input = ImageUtilities.readMBF(file);

这里是错误:

Exception in thread "main" java.io.IOException: org.apache.sanselan.ImageReadException: Tiff: unknown compression: 7
    at org.openimaj.image.ExtendedImageIO.read(ExtendedImageIO.java:189)
    at org.openimaj.image.ExtendedImageIO.read(ExtendedImageIO.java:126)
    at org.openimaj.image.ImageUtilities.readMBF(ImageUtilities.java:355)
    at org.mosab.TestOpenIMAJ.TestKmeans.main(TestKmeans.java:49)
Caused by: org.apache.sanselan.ImageReadException: Tiff: unknown compression: 7
    at org.apache.sanselan.formats.tiff.datareaders.DataReader.decompress(DataReader.java:135)
    at org.apache.sanselan.formats.tiff.datareaders.DataReaderStrips.readImageData(DataReaderStrips.java:96)
    at org.apache.sanselan.formats.tiff.TiffImageParser.getBufferedImage(TiffImageParser.java:505)
    at org.apache.sanselan.formats.tiff.TiffDirectory.getTiffImage(TiffDirectory.java:163)
    at org.apache.sanselan.formats.tiff.TiffImageParser.getBufferedImage(TiffImageParser.java:441)
    at org.apache.sanselan.Sanselan.getBufferedImage(Sanselan.java:1264)
    at org.apache.sanselan.Sanselan.getBufferedImage(Sanselan.java:1163)
    at org.apache.sanselan.Sanselan.getBufferedImage(Sanselan.java:1136)
    at org.openimaj.image.ExtendedImageIO.read(ExtendedImageIO.java:187)
    ... 3 more

这是我正在使用的 tiff 文件(特别是 GeoTiff):

"https://drive.google.com/file/d/0ByKaCojxzNa9MWxPTUJjZURHR1E/view?usp=sharing"

这是否意味着 OpenIMAJ 库不支持 tiff format/GeoTiff?

我认为 OpenIMAJ 不支持 tiff,所以我尝试 "TwelveMonkeys" 库来读取该文件。 "TwelveMonkeys" 库 separately/alone 能够读取文件。因此,我导入了 TwelveMonkeys 库以与 OpenIMAJ 一起工作,因此支持 tiff 文件,这适用于一些 tiff 文件,但对于那个文件它不起作用(尽管 "TwelveMonkeys" 能够在单独的项目中单独读取它)我得到了这个例外:

Exception in thread "main" java.io.IOException: Resetting to invalid mark
at java.io.BufferedInputStream.reset(BufferedInputStream.java:448)
at org.openimaj.image.ExtendedImageIO.read(ExtendedImageIO.java:185)
at org.openimaj.image.ExtendedImageIO.read(ExtendedImageIO.java:126)
at org.openimaj.image.ImageUtilities.readMBF(ImageUtilities.java:355)
at org.mosab.TestOpenIMAJ.TestKmeans.main(TestKmeans.java:49)

稍后,当我跟踪错误消息时,我发现某些东西可能与文件大小有关,因为它大约是 26mb,我注意到错误源自方法 "read" 的 class "org.openimaj.image.ExtendedImageIO" 我认为它使用最大 10mb:

public static BufferedImage read(InputStream input) throws IOException {
    if (input == null) {
        throw new IllegalArgumentException("input == null!");
    }

    final NonClosableInputStream buffer = new NonClosableInputStream(input);
    buffer.mark(10 * 1024 * 1024); // 10mb I think here is the problem

    BufferedImage bi;
    try {
        bi = readInternal(buffer);
    } catch (final Exception ex) {
        bi = null;
    }

    if (bi == null) {
        buffer.reset();
        try {
            bi = Sanselan.getBufferedImage(buffer);
        } catch (final Throwable e) {
            throw new IOException(e);
        }
    }

    return bi;
}

那么我该如何解决这个问题并在 OpenIMAJ 中读取该 tiff 文件(为了进一步应用工具,OpenIMAJ 提供了类似 clustering/segmentation 的功能)?

TIFF 是一种可怕的格式,因为它有许多图书馆并不总是支持的自定义扩展。 OpenIMAJ 试图通过使用一批不同的库来读取各种不同的图像来解决其中的一些问题,但是在这种情况下它失败了。正如您所注意到的,有一个 10mb 的缓冲区限制导致了一个问题 - 将其增加到 100mb 允许加载您 linked 的图像。我将更新代码来解决这个问题(因为它只是一个限制,看起来底层缓冲区要小得多,所以这应该不会引起任何问题)。

作为部署新快照之前的快速解决方法,您可以加载您 link 编辑的图像:

MBFImage img = ImageUtilities.
    createMBFImage(Sanselan.getBufferedImage(new File("tif.tif")), false);

这似乎是一个单独的问题,即 Sanselan 似乎无法加载您的所有图像(基于引用未知图像压缩的堆栈跟踪)。如果您可以在 GitHub 错误报告 (https://github.com/openimaj/openimaj/issues/119) 中为此类图像提供 link,那么可能可以编写一个使用 TwelveMonkeys 处理此类图像的回退代码,或者我们可以看到如果较新版本的 Sanselan 解决了该问题。同样,与此同时,您可以将 TwelveMonkeys 直接用于代码中的那些图像,并使用上述 ImageUtilities 转换为 MBFImage