我会尽力帮助马克完成任务。我将 ImageMagick 和一些 unix 代码与 Imagemagick 的 Connected Components Labeling (-connected-components) 一起使用,如下所示。
这是图像中所有颜色的简单连接组件结果:
convert in-1.png \
-define connected-components:verbose=true \
-connected-components 4 \
null:
Objects (id: bounding-box centroid area mean-color):
0: 256x256+0+0 133.6,134.1 50820 srgb(255,255,255)
1: 86x40+23+30 65.5,49.5 3440 srgb(0,127,70)
6: 60x40+42+126 71.5,145.5 2400 srgb(0,127,70)
4: 86x27+22+80 64.5,93.0 2322 srgb(0,38,255)
5: 86x27+121+121 163.5,134.0 2322 srgb(0,127,70)
2: 37x40+127+59 145.0,78.5 1480 srgb(0,127,70)
3: 36x40+177+59 194.5,78.5 1440 srgb(0,127,70)
7: 41x32+89+186 109.0,201.5 1312 srgb(255,106,0)
请注意,没有一个绿色,即 srgb(0,127,70) 的高度高于 40。全部为 40,一个为 27。因此,为了演示,让所有大于 30 的框。
对于上面的代码,我先选中所有绿色对象,去掉前导空格,提取边界框,也就是字段2,然后把x改成+。
然后我遍历每个边界框并提取 ht、左上角 xx 和 yy 值。我根据 htval=30 测试 ht,如果通过,我用黑色填充绿色。
htval=30
convert in-1.png in-1_result.png
bboxArr=(`convert in-1.png \
-define connected-components:verbose=true \
-connected-components 4 \
null: | grep "srgb(0,127,70)" | sed 's/^[ ]*//' | cut -d\ -f2 | tr "x" "+"`)
num=${#bboxArr[*]}
for ((i=0; i<num; i++)); do
ht=`echo ${bboxArr[$i]} | cut -d+ -f2`
xx=`echo ${bboxArr[$i]} | cut -d+ -f3`
yy=`echo ${bboxArr[$i]} | cut -d+ -f4`
if [ $ht -gt $htval ]; then
convert in-1_result.png -fill black -draw "color $xx,$yy floodfill" -alpha off in-1_result.png
fi
done
注意上面的行
null: | grep "srgb(0,127,70)" | sed 's/^[ ]*//' | cut -d\ -f2 | tr "x" "+"`)
可以替换为
null: | awk '/srgb\(0,127,70\)/ && sub(/x/, "+") {print $2}'
补充:
这是一种更紧凑的方法,使用 awk 进行所有过滤并将输出保存为颜色 x,y 填充。然后只需要一个绘图命令来进行处理。
convert in-1.png in-1_result.png
floodfill_arr=(`convert in-1.png \
-define connected-components:verbose=true \
-connected-components 4 \
null: | awk '/srgb\(0,127,70\)/ && sub(/[x]/, "+") && split($2, arr, "+") {if (arr[4]>30) {print " color " arr[3] "," arr[4] " floodfill"}}'`)
echo "${floofill_arr[*]}"
color 42,126 floodfill color 121,121 floodfill color 127,59 floodfill color 177,59 floodfill
convert in-1_result.png -fill black -draw "${floodfill_arr[*]}" -alpha off in-1_result.png
awk 首先找到所有绿色的行,然后用+ 替换任何x,然后使用字段分隔符+ 将字段$2 拆分为数组(arr)部分,然后测试第4 个arr 字段(ht)是否为大于 30,如果是,则为每个通过测试的边界框打印 -draw 命令。