【问题标题】:imagemagick: Remove all occurrences of a stray pixel surrounded by transparencyimagemagick:删除所有出现的被透明度包围的杂散像素
【发布时间】:2019-11-30 00:45:41
【问题描述】:

您好!我想从透明图像中删除所有出现的杂散像素。

以下是示例图片,为方便起见放大:

以下是同一张图片,但我希望它在处理后看起来如何:

我能想到的描述我想要实现的最佳方式是,应该删除周围像素完全透明的每个像素。将选择器想象成一个 3x3 的网格,网格的中间是操作的像素。

我查看了 IM 手册中的 Morphology,但它似乎没有为此提供足够好的方法。

ImageMagick 可以做到这一点吗?如果没有,还有其他命令行软件可以实现吗?

【问题讨论】:

    标签: image-processing command-line imagemagick


    【解决方案1】:

    在 Imagemagick 中,您可以使用 -connected-components 来移除那些孤立的像素块。它们的一侧似乎是 5x5 像素。所以我们将该区域的阈值保持在 26。我们删除了 Alpha 通道中的那些块,然后在图像中替换它们。 (注意我们需要使用 8-connected 与 4-connected 区域检测来保留您的其他区域)。

    既然你说你的图像被放大了,所以我假设你的孤立区域是 1x1 像素。因此,将 area-threshold 更改为 2,以移除单个像素区域。

    输入:

    Unix 语法:

    convert img.png \
    \( -clone 0 -alpha extract -type bilevel \
    -define connected-components:mean-color=true \
    -define connected-components:area-threshold=26 \
    -connected-components 8 \) \
    -alpha off -compose copy_opacity -composite \
    result.png
    


    Windows 语法:

    convert img.png ^
    ( -clone 0 -alpha extract -type bilevel ^
    -define connected-components:mean-color=true ^
    -define connected-components:area-threshold=26 ^
    -connected-components 8 ) ^
    -alpha off -compose copy_opacity -composite ^
    result.png
    


    -connected-components

    补充:

    如果您只想删除小的孤立彩色像素,而不是彩色像素内的任何透明像素,那么没有简单的方法可以做到这一点。这是我想要的增强功能。但是,这是可以做到的。

    您的图像已修改为左上角的红色块有一个透明的中心像素。我在其右侧添加了一条红线,以确保当中心变为透明时它大于 25 像素,以便您可以看到哪个像素具有透明中心。您必须下载并放大此图像才能看到丢失的像素。

    4 倍缩放:

    方法是在 alpha 通道中找到所有的白色区域,然后列出所有小于 26 像素的区域。然后重新处理图像以按 ID 删除这些区域。

    获取 ID 列表

    id_list=""
    OLDIFS=$IFS
    IFS=$'\n'
    arr=(`convert img2.png -alpha extract -type bilevel \
    -define connected-components:mean-color=true \
    -define connected-components:verbose=true \
    -connected-components 8 null: | grep "gray(255)" | sed 's/^[ ]*//'`)
    echo "${arr[*]}"
    num=${#arr[*]}
    IFS=$OLDIFS
    for ((i=0; i<num; i++)); do
    id=`echo "${arr[$i]}" | cut -d' ' -f1 | sed 's/[:]*$//'`
    count=`echo "${arr[$i]}" | cut -d' ' -f4`
    if [ $count -lt 26 ]; then
    id_list="$id_list $id"
    fi
    done
    echo "$id_list"
    


    这是打印的内容

    12: 5x5+120+70 122.0,72.0 25 gray(255)
    14: 5x5+30+85 32.0,87.0 25 gray(255)
    15: 5x5+110+85 112.0,87.0 25 gray(255)
    16: 5x5+75+90 77.0,92.0 25 gray(255)
    17: 5x5+40+100 42.0,102.0 25 gray(255)
    18: 5x5+110+110 112.0,112.0 25 gray(255)
    19: 5x5+140+110 142.0,112.0 25 gray(255)
    21: 5x5+15+130 17.0,132.0 25 gray(255)
    22: 5x5+40+140 42.0,142.0 25 gray(255)
    23: 5x5+85+140 87.0,142.0 25 gray(255)
    24: 5x5+120+140 122.0,142.0 25 gray(255)
    2: 5x5+55+5 57.0,7.0 25 gray(255)
    5: 5x5+100+20 102.0,22.0 25 gray(255)
    7: 5x5+65+30 67.0,32.0 25 gray(255)
    8: 5x5+125+30 127.0,32.0 25 gray(255)
    9: 5x5+105+50 107.0,52.0 25 gray(255)
    11: 5x5+25+65 27.0,67.0 25 gray(255)
    
    12 14 15 16 17 18 19 21 22 23 24 2 5 7 8 9 11
    

    重新处理以按 ID 删除区域

    convert img2.png \
    \( -clone 0 -alpha extract -type bilevel \
    -define connected-components:mean-color=true \
    -define connected-components:remove="$id_list" \
    -connected-components 8 -background black -flatten +write tmp.png \) \
    -alpha off -compose copy_opacity -composite \
    result2.png
    


    4 倍缩放:

    【讨论】:

    • 感谢您的回复,但是我无法复制您的结果。 result.png 输出为 BW 掩码,可能用于另一个 magick 命令。任何想法为什么会发生这种情况?
    • 您的 Imagemagick 版本和平台是什么?我的代码是 Unix 语法。还要确保 \ 之后没有空格。
    • Windows,恐怕。我相应地调整了语法,只删除了反斜杠和右括号。它执行没有错误,但给出了上述意外结果。我想最坏的情况是我几年来第一次再次双启动 Ubuntu。
    • 查看我对 Windows 语法的回答中的变化。另请参阅有关调整输入大小的说明。还请按照我的要求提供您的 IM 版本。你的版本可能太旧了。它至少需要 6.8.9.10。如果在 Imagemagick 7 上,则将 convert 更改为 magick。还要确保您使用的是 Imagemagick convert 而不是 windows convert。
    • 感谢您更新您的帖子,我使用的是 v7.0.8.56。将立即使用结果编辑此评论。编辑:您为 Windows 更新的语法完美运行,将您的帖子标记为答案并投票赞成。再次感谢!
    【解决方案2】:

    fmw42 的出色答案使用连接区域,但我认为仅使用形态是可能的。使用:

    0 0 0 
    0 1 0 
    0 0 0 
    

    作为具有腐蚀的结构元素,它将检测 8 路连接的孤立像素。现在用你的 alpha 进行 EOR,它会使这些像素完全透明(即移除它们)。

    我不太了解 IM,无法让您执行此操作 :-( 但是使用 libvips 命令行,制作测试图像将是这样的:

    size=256
    
    # sparse speckles for the alpha
    vips gaussnoise t1.v $size $size
    vips relational_const t1.v a.v more 200
    
    # RGB noise 
    vips gaussnoise r.v $size $size
    vips gaussnoise g.v $size $size
    vips gaussnoise b.v $size $size
    
    # assemble and save
    vips bandjoin "r.v g.v b.v a.v" x.png
    

    然后去除你的杂散像素:

    # make mask.mor, a file containing our structuring element
    cat >mask.mor <<EOF
    3 3 
    0   0   0
    0   255 0
    0   0   0
    EOF
    
    # pull out the alpha channel
    vips extract_band x.png a.v 3
    
    # find isolated pixels
    vips morph a.v t1.v mask.mor erode
    
    # EOR with alpha to zap those pixels
    vips boolean t1.v a.v t2.v eor
    
    # extract rgb from original, then attach our modified alpha
    vips extract_band x.png rgb.v 0 --n 3
    vips bandjoin "rgb.v t2.v" x2.png
    

    这是之前和之后:

    libvips CLI 速度很快,但有点笨拙。如果使用 Python 之类的脚本编写它会更整洁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-29
      • 2013-06-03
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多