Skip to content

ImageJ 命名处理

大模型暂时没有回答正确,特此记录。

将 raw 文件拖进 ImageJ 的时候,需要在弹窗输入对应的参数,非常的麻烦。好在 ImageJ 中会尝试自动解析,如果我们重命名 raw 文件为合适的名字,可以让 ImageJ 试图自动解析时能解析正确的尺寸和类型信息。

ImageJ (https://github.com/imagej/ImageJ) 自动解析,即猜测图片信息的代码在 ij/io/ImportDialog.java 文件的 getDimensionsFromNameguessFormat 函数中:

private void getDimensionsFromName(String name) {
    if (name==null)
        return;
    if (!name.matches(".*[0-9]+x[0-9]+.*"))
        return; // must have 'x' seperator
    int lastUnderscore = name.lastIndexOf("_");
    String name2 = name;
    if (lastUnderscore>=0)
        name2 = name.substring(lastUnderscore);
    char[] chars = new char[name2.length()];
    for (int i=0; i<name2.length(); i++)  // change non-digits to spaces
        chars[i] = Character.isDigit(name2.charAt(i))?name2.charAt(i):' ';
    name2 = new String(chars);
    String[] numbers = Tools.split(name2);
    int n = numbers.length;
    if (n<2) return;
    int w = (int)Tools.parseDouble(numbers[0],0);
    if (w<1) return;
    int h = (int)Tools.parseDouble(numbers[1],0);
    if (h<1) return;
    width = w;
    height = h;
    nImages = 1;
    if (n>2) {
        int d = (int)Tools.parseDouble(numbers[2],0);
        if (d>0)
            nImages = d;
    }
    guessFormat(directory, name);
}

private void guessFormat(String dir, String name) {
    if (dir==null) return;
    File file = new File(dir+name);
    long imageSize = (long)width*height*nImages;
    long fileSize = file.length();
    if (fileSize==4*imageSize)
        choiceSelection = 5; // 32-bit real
    else if (fileSize==2*imageSize)
        choiceSelection = 2;    // 16-bit unsigned
    else if (fileSize==3*imageSize)
        choiceSelection = 7;    // 24-bit RGB
    else if (fileSize==imageSize)
        choiceSelection = 0;    // 8-bit
    if (name.endsWith("be.raw"))  // big-endian
        intelByteOrder = false;
    else if (name.endsWith("le.raw"))  // little-endian
        intelByteOrder = true;
}

getDimensionsFromName 可以看出,我们应该在名字中带上 width x height x nframes 这种格式,这样可以解析出帧数和长宽,注意顺序不要颠倒了。

解析完尺寸后,ImageJ 会使用 guessFormat 来猜测类型,逻辑是根据像素大小。因为上面已经解析完了尺寸,所以用文件大小除以像素数目,这样得到一个像素的大小。然后根据像素大小来推断。具体对应看上面的代码,比如像素大小是 32bit 时,它会认为是 32bit-real,而不是 32bit-unsigned。

最后几句话中也可以知道大小端是根据名字的结尾来判断的,比如结尾是 be.raw 结果就是 big-endian。

guessFormat 看出,保存 Raw 文件的时候,对于非 8bit 的黑白图,最好保存 32bit-real 和 16bit-unsigned,而不是 32bit-unsigned 和 64bit-real。这样如果尺寸信息也在名字中,Imagej 能正确解析出格式,从而不用每次导入 raw 文件时都要选择格式。所以我一般保存最后 raw 文件都是下面这种格式:

# 格式为 32bit-float
result = np.array(result).astype(np.float32)
# 重命名为 width x height x nframe
result.tofile(f'result_{result.shape[2]}x{result.shape[1]}x{result.shape[0]}.raw')

Comments