将图像转换为 CSV
Convert image to CSV
如何将图像分解成方形单元格的网格,用每个单元格包含的平均颜色着色,并将生成的平均值导出为 csv 文件?
由于 ppm 是简单的图像格式,因此转换为 ppm 格式可能是一个不错的开始,但接下来呢?
动机:我正在制作游戏世界地图,希望将彩色编码地图(颜色表示生物群系类型)转换为其他源代码文件可读的数据文件(例如csv)。
由于游戏地图会随着游戏的开发而更新,我希望这个过程自动化,所以我觉得基于代码的解决方案是最优的;它是用 C# 编写的。
您可以使用 ImageMagick,它安装在大多数 Linux 发行版上,适用于 macOS 和 Windows。
就在终端(或 Windows 上的命令提示符)中,从这张 500x256 图片开始:
magick start.png -resize 3x2\! -depth 8 -compress none ppm:
P3
3 2
255
189 0 66 189 0 66 189 0 66
66 0 189 66 0 189 66 0 189
已调整图像大小并将颜色平均化为 3x2 图像(如果您愿意,可以选择不同的尺寸)并将输出打印为文本 PPM 文件。
大小为 3x2,第一行是 3 像素 rgb(189,0,66),主要是红色,第二行是 3 像素,rgb(66,0,189) 主要是蓝色。
我会让你格式化为 CSV :-)
在这里您可以将其缩小并按比例放大,以查看对 8x3 块进行平均的效果:
magick start.png -resize 8x3\! -depth 8 -scale 400x result.png
根据您喜欢解析的内容,您可以生成格式略有不同的相同信息:
magick start.png -resize 8x3\! -depth 8 txt:
# ImageMagick pixel enumeration: 8,3,65535,srgb
0,0: (54998,0,10537) #D60029 srgb(214,0,41)
1,0: (54998,0,10537) #D60029 srgb(214,0,41)
2,0: (54998,0,10537) #D60029 srgb(214,0,41)
3,0: (54998,0,10537) #D60029 srgb(214,0,41)
4,0: (54998,0,10537) #D60029 srgb(214,0,41)
5,0: (54998,0,10537) #D60029 srgb(214,0,41)
...
...
3,1: (32896,0,32896) #800080 purple
4,1: (32896,0,32896) #800080 purple
5,1: (32896,0,32896) #800080 purple
6,1: (32896,0,32896) #800080 purple
7,1: (32896,0,32896) #800080 purple
0,2: (10537,0,54998) #2900D6 srgb(41,0,214)
5,2: (10537,0,54998) #2900D6 srgb(41,0,214)
6,2: (10537,0,54998) #2900D6 srgb(41,0,214)
7,2: (10537,0,54998) #2900D6 srgb(41,0,214)
这是一个 bash 脚本循环,使用 Imagemagick 获取图像块的平均颜色并写入 csv 文件
输入 (256x256):
要获得图像块的适当平均值,应该使用 -scale 而不是 -resize。所以在这里我从图像中得到一组 4x4 的 64x64 色块的平均值 (256/4=64)。然后我依次遍历行中的每个块然后列并获取颜色。我将每一行的颜色存储在一个字符串 "rowlist" 中,中间用逗号分隔。收集完每一行颜色后,我将其写入一个文本文件。下一行重复。
convert image.png -scale 4x4! image2.png
for ((j=0; j<4; j++)); do
for ((i=0; i<4; i++)); do
rowcolor=`convert image2.png -crop 1x1+$i+$j +repage -format "rgb(%[fx:round(255*u.r)]_%[fx:round(255*u.g)]_%[fx:round(255*u.b)])" info:`
if [ $i -eq 0 ]; then
rowlist="$rowcolor"
else
rowlist="$rowlist,$rowcolor"
fi
done
echo "$rowlist" >> image_colors.txt
done
生成的文本文件中的数据如下:
rgb(8_0_247),rgb(50_0_205),rgb(50_0_205),rgb(8_0_247)
rgb(50_0_205),rgb(157_0_98),rgb(157_0_98),rgb(50_0_205)
rgb(50_0_205),rgb(157_0_98),rgb(157_0_98),rgb(50_0_205)
rgb(8_0_247),rgb(50_0_205),rgb(50_0_205),rgb(8_0_247)
如果需要,您可以删除 rgb( ),只保留颜色值。我用 _ 来分隔值,这样逗号只会在 rgb(...) 颜色之间使用。但是,您可能更喜欢使用制表符或空格作为文件分隔符,这样颜色值将是 r,g,b 而不是 r_g_b.
为了避免逗号混淆,将颜色写成十六进制值可能会更好。所以要做到这一点,请使用:
convert image.png -scale 4x4! image2.png
for ((j=0; j<4; j++)); do
for ((i=0; i<4; i++)); do
rowcolor=`convert image2.png -depth 8 -crop 1x1+$i+$j +repage -format "#%[hex:u.p]" info:`
if [ $i -eq 0 ]; then
rowlist="$rowcolor"
else
rowlist="$rowlist,$rowcolor"
fi
done
echo "$rowlist" >> image_colors.txt
done
在文本文件中产生以下值。
#0800F7,#3200CD,#3200CD,#0800F7
#3200CD,#9D0062,#9D0062,#3200CD
#3200CD,#9D0062,#9D0062,#3200CD
#0800F7,#3200CD,#3200CD,#0800F7
从 2017-06-01 版本的 Imagemagick 6 和 7 开始,使用 %[hex:] 是 Imagemagick 的新功能。
如何将图像分解成方形单元格的网格,用每个单元格包含的平均颜色着色,并将生成的平均值导出为 csv 文件?
由于 ppm 是简单的图像格式,因此转换为 ppm 格式可能是一个不错的开始,但接下来呢?
动机:我正在制作游戏世界地图,希望将彩色编码地图(颜色表示生物群系类型)转换为其他源代码文件可读的数据文件(例如csv)。
由于游戏地图会随着游戏的开发而更新,我希望这个过程自动化,所以我觉得基于代码的解决方案是最优的;它是用 C# 编写的。
您可以使用 ImageMagick,它安装在大多数 Linux 发行版上,适用于 macOS 和 Windows。
就在终端(或 Windows 上的命令提示符)中,从这张 500x256 图片开始:
magick start.png -resize 3x2\! -depth 8 -compress none ppm:
P3
3 2
255
189 0 66 189 0 66 189 0 66
66 0 189 66 0 189 66 0 189
已调整图像大小并将颜色平均化为 3x2 图像(如果您愿意,可以选择不同的尺寸)并将输出打印为文本 PPM 文件。
大小为 3x2,第一行是 3 像素 rgb(189,0,66),主要是红色,第二行是 3 像素,rgb(66,0,189) 主要是蓝色。
我会让你格式化为 CSV :-)
在这里您可以将其缩小并按比例放大,以查看对 8x3 块进行平均的效果:
magick start.png -resize 8x3\! -depth 8 -scale 400x result.png
根据您喜欢解析的内容,您可以生成格式略有不同的相同信息:
magick start.png -resize 8x3\! -depth 8 txt:
# ImageMagick pixel enumeration: 8,3,65535,srgb
0,0: (54998,0,10537) #D60029 srgb(214,0,41)
1,0: (54998,0,10537) #D60029 srgb(214,0,41)
2,0: (54998,0,10537) #D60029 srgb(214,0,41)
3,0: (54998,0,10537) #D60029 srgb(214,0,41)
4,0: (54998,0,10537) #D60029 srgb(214,0,41)
5,0: (54998,0,10537) #D60029 srgb(214,0,41)
...
...
3,1: (32896,0,32896) #800080 purple
4,1: (32896,0,32896) #800080 purple
5,1: (32896,0,32896) #800080 purple
6,1: (32896,0,32896) #800080 purple
7,1: (32896,0,32896) #800080 purple
0,2: (10537,0,54998) #2900D6 srgb(41,0,214)
5,2: (10537,0,54998) #2900D6 srgb(41,0,214)
6,2: (10537,0,54998) #2900D6 srgb(41,0,214)
7,2: (10537,0,54998) #2900D6 srgb(41,0,214)
这是一个 bash 脚本循环,使用 Imagemagick 获取图像块的平均颜色并写入 csv 文件
输入 (256x256):
要获得图像块的适当平均值,应该使用 -scale 而不是 -resize。所以在这里我从图像中得到一组 4x4 的 64x64 色块的平均值 (256/4=64)。然后我依次遍历行中的每个块然后列并获取颜色。我将每一行的颜色存储在一个字符串 "rowlist" 中,中间用逗号分隔。收集完每一行颜色后,我将其写入一个文本文件。下一行重复。
convert image.png -scale 4x4! image2.png
for ((j=0; j<4; j++)); do
for ((i=0; i<4; i++)); do
rowcolor=`convert image2.png -crop 1x1+$i+$j +repage -format "rgb(%[fx:round(255*u.r)]_%[fx:round(255*u.g)]_%[fx:round(255*u.b)])" info:`
if [ $i -eq 0 ]; then
rowlist="$rowcolor"
else
rowlist="$rowlist,$rowcolor"
fi
done
echo "$rowlist" >> image_colors.txt
done
生成的文本文件中的数据如下:
rgb(8_0_247),rgb(50_0_205),rgb(50_0_205),rgb(8_0_247)
rgb(50_0_205),rgb(157_0_98),rgb(157_0_98),rgb(50_0_205)
rgb(50_0_205),rgb(157_0_98),rgb(157_0_98),rgb(50_0_205)
rgb(8_0_247),rgb(50_0_205),rgb(50_0_205),rgb(8_0_247)
如果需要,您可以删除 rgb( ),只保留颜色值。我用 _ 来分隔值,这样逗号只会在 rgb(...) 颜色之间使用。但是,您可能更喜欢使用制表符或空格作为文件分隔符,这样颜色值将是 r,g,b 而不是 r_g_b.
为了避免逗号混淆,将颜色写成十六进制值可能会更好。所以要做到这一点,请使用:
convert image.png -scale 4x4! image2.png
for ((j=0; j<4; j++)); do
for ((i=0; i<4; i++)); do
rowcolor=`convert image2.png -depth 8 -crop 1x1+$i+$j +repage -format "#%[hex:u.p]" info:`
if [ $i -eq 0 ]; then
rowlist="$rowcolor"
else
rowlist="$rowlist,$rowcolor"
fi
done
echo "$rowlist" >> image_colors.txt
done
在文本文件中产生以下值。
#0800F7,#3200CD,#3200CD,#0800F7
#3200CD,#9D0062,#9D0062,#3200CD
#3200CD,#9D0062,#9D0062,#3200CD
#0800F7,#3200CD,#3200CD,#0800F7
从 2017-06-01 版本的 Imagemagick 6 和 7 开始,使用 %[hex:] 是 Imagemagick 的新功能。