【问题标题】:How to compile tiff images into xyz coordinates in a single text file?如何将 tiff 图像编译为单个文本文件中的 xyz 坐标?
【发布时间】:2015-09-09 22:44:53
【问题描述】:

我的编程经验有限,需要您的帮助。

我现在的情况是,我有一堆黑白 .tiff 图像(每个 10 Mb 的大约 400 个),我需要将其转换为 xyz 坐标加上灰度值,并将所有这些图像编译成具有 x、y、z、灰度的单个文本文件(z 坐标,这样:文件夹的第一张图像 z=0000,第二张图像 0001...与文件夹中的图像一样多的 z 坐标)。

我有一个脚本(我很不熟悉,但我认为它是用 Image Magick 完成的)它可以做到,但一次只能处理一个图像,并且只添加 x、y 坐标和一个值灰度,但没有 z。

脚本,从我在这里发布的上一个版本修改而来(因为现在它使用灰度并且只存储我需要的值)是:

## The exact format of the TXT image is defined by the convert command, then 'tail' is used to junk the header, 
## 'tr' to character replace every non-number character with a single space, so that the later 'while' can read 
## it easily, junking any comment numbers that may have been left.

convert -depth 8 -colorspace RGB $1 txt:- |
    tail -n +2 | tr -cs '0-9.\n'  ' ' |
    while read x y Gray junk; 
    do
    if [ "$Gray" -eq 0 ]; then
        echo "$x,$y $Gray"
        done

为了运行它,我把它放在了 linux 终端中:

chmod +x img.sh

然后(我选择了与图像相同的名称,但使用 .txt 作为文件名):

./img.sh pic0000.tif > pic0000.txt

我也尝试将其更改为一次完成所有操作,替换行:

convert -depth 8 -colorspace RGB $1 txt:- |

convert -depth 8 -colorspace RGB $* txt:- |

并将其放入终端

chmod +x ./img.sh
./img.sh *.tif > *.txt

现在它将所有文件与 x y 灰度放在一个中,但我无法添加 z 值。

顺便说一句,创建txt文件需要很长时间。

最终的 XYZ 文件的第一行必须是,例如:

0 0 0 value in greyscale 
1 0 0 value in greyscale
...
and the last: 
3095 2951 400 value in greyscale

你能给我任何线索、想法或解决方案吗?任何帮助将不胜感激。

【问题讨论】:

  • 脚本是fortran吗?
  • 如果你做了什么,也添加一些源代码?
  • 您的雇主内部是否有任何 Fortran 专业知识?他们将紧急的编程工作交给没有编程经验的生物学家似乎是不合理的。
  • 您好。我故意删除了关于截止日期的注释,因为它们有时会产生阻止人们回答的意想不到的效果 - 请记住,这里的帮助者是志愿者,他们在空闲时间回答,主要是为了好玩。我看到你已经回滚了。另请记住,截止日期/紧迫性的注释对于在截止日期过去后会看到您的问题的数百名读者来说并不是很有趣,这也是我们喜欢将它们删除的另一个原因。
  • 您能否在您的帖子中添加 1. 将 Image0003 转换为 XY 文件的命令,2. XY 文件的前几行和最后几行,3. 文件名XY 文件,以及 4. XYZ 文件的对应行应该是什么?

标签: linux bash terminal tiff cartesian-coordinates


【解决方案1】:

虽然也可以使用 Fortran,但 shell (bash) 脚本可以直接执行此操作。例如,假设“conv.sh”有以下内容

allout="alldata.out"   # name of a combined XYZ file
[ -f $allout ] && rm -i $allout

for inpfile in image*.txt ; do

    echo "processing $inpfile"
    z=$( echo $inpfile | sed -e 's/image\([0-9]*\)\.txt/\1/' )
    echo "z = $z"

    outfile=data${z}.out    # name of each XYZ file

    awk -F'[, ]' -v z=$z '{ printf( "%5d,%5d,%5d %16.6f\n", $1, $2, z, 0.2989 * $3 + 0.5870 * $4 + 0.1140 * $5 ) }' $inpfile > $outfile

    cat $outfile >> $allout
done

我们在数据文件(image*.txt)所在的目录下运行:

$ chmod +x ./conv.sh
$ ./conv.sh

然后我们获得一组输出文件 (data0000.out, ..., data0400.out) 以及它们的组合文件 (alldata.out)。请注意,我假设输入文件中的 "x,y" 和 "r,g,b" 仅由一个空格分隔,并且灰度定义为

0.2989 * R + 0.5870 * G + 0.1140 * B

但定义似乎不是唯一的(例如,Wiki page 显示 0.2126 * R + 0.7152 * G + 0.0722 * B)所以请选择您想要的定义。


编辑:您也可以直接使用 for 循环添加 z 值,如下所示:

output="output.txt"
rm -f $output   # combined XYZ file

for (( z=0 ; z <= 400; z++ )); do
    inpfile=pic${z}.tif
    convert -depth 8 -colorspace RGB $inpfile txt:- | tail -n +2 | tr -cs '0-9.\n' ' ' | while read x y Gray junk; do if [ "$Gray" -eq 0 ]; then echo "$x,$y,$z $Gray" done >> $output
done

如果输入名称类似于“pic0000.tif”到“pic0400.tif”,您可能需要在 z 值前面填充零,例如,

for (( z=0 ; z <= 400; z++ )); do

    if (( z < 10 ))   ; then n=000$z ; fi
    if (( z < 100 ))  ; then n=00$z  ; fi
    if (( z < 1000 )) ; then n=0$z   ; fi

    inpfile=pic${n}.tif    # "n" is the file index from 0000 to 0400

    convert ....  # same as above
done

【讨论】:

  • 更多信息, printf() 中的 "%5d,%5d,%5d %16.6f\n" 指定输出 xyz + 灰度数据的格式,其中 5 表示整数输出的宽度, 16.6 表示 6 位有效数字的浮点数的宽度。如果您不需要在 x,y,z 之间使用逗号,请将其更改为“%5d %5d %5d %16.6f\n”,例如。
  • 我更喜欢 0.2989 * R + 0.5870 * G + 0.1140 * B,我没有回复,因为我正在处理它,但看起来非常好,非常感谢!.
  • 如果您希望 x、y 和 z 之间没有空格(即逗号分隔),请尝试使用 "%0d,%0d,%0d %16.6f\n"(其中 0 表示“零”)。如果不工作,请告诉我(我们也可以写 Fortran 对应的,但它会变得有点长......)干杯:)
  • 谢谢。我打算写基本相同的脚本(虽然可能在perl),但你打败了我。
  • 嗯,一个简单的 "%d,%d,%d %16.6f\n" 对于后一个目的可能就足够了... plz google for "printf format" etc :) @Lorehead 没问题:)
猜你喜欢
  • 2023-03-27
  • 2010-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多