用高度imagemagick替换区域的颜色

Replace color of region by height imagemagick

使用命令 "convert" 我知道如何替换具有坐标和大小的区域的颜色,但是有没有办法在图像中替换所有高度为 40 像素的区域?谢谢

这将是一个输入图像示例,其中有 4 个高度为 40 像素的绿色矩形。

Input.png

这将是输出,其中 4 个绿色矩形被替换为黑色,知道它们的高度但不知道它们的坐标,如果可能的话。

Out.png

您可以使用 ImageMagick"连通分量分析: 来查找图像中的所有斑点,如下所示:

convert blobs.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)

有一条 header 行告诉您所有字段是什么,然后每个找到的 blob 一行,请忽略第一行 non-header 行,因为它是白色背景 - 请参阅最后一个字段srgb(255,255,255).

查看 second-to-last 行,它宽 36 像素,高 40 像素,平均颜色为 srgb(0,127,70)。我想那是你想要 fill-in 或改变颜色的斑点。

如果您想找到 40 像素高的斑点,请像这样通过 grep 传递:

convert blobs.png \
   -define connected-components:verbose=true \
   -connected-components 4 null: | grep "x40+"

你会得到所有 40 高的斑点:

  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)
  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)

如果你看不出如何完成它,我明天会再添加一些 - 这里已经晚了。

我会尽力帮助 Mark 完成。我使用 ImageMagick 和一些 unix 代码,如下所示与 Imagemagick 的连接组件标签 (-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)


请注意,none 的绿色,即 srgb(0,127,70) 的高度高于 40。所有都是 40,一个是 27。所以为了演示,让我们得到所有大于 30 的框。

对于上面的代码,我先select所有的绿色对象,去掉前导space,提取bounding box,也就是字段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 }'

添加:

这是一个更紧凑的方法,使用 awk 进行所有过滤并将输出保存为颜色 x,y floodfill。那么只需要一个绘图命令就可以完成处理。

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(, 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 命令。