ImageJ 命名处理
大模型暂时没有回答正确,特此记录。
将 raw 文件拖进 ImageJ 的时候,需要在弹窗输入对应的参数,非常的麻烦。好在 ImageJ 中会尝试自动解析,如果我们重命名 raw 文件为合适的名字,可以让 ImageJ 试图自动解析时能解析正确的尺寸和类型信息。
ImageJ (https://github.com/imagej/ImageJ) 自动解析,即猜测图片信息的代码在 ij/io/ImportDialog.java
文件的 getDimensionsFromName
和 guessFormat
函数中:
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')