Search code examples
computer-visionimagemagickimagemagick-convert

How to get rid of small image artifacts (threshold by size) using ImageMagick?


I am trying to automate image conversion using ImageMagick CLI. One of the biggest problems with my image set is with tiny artifacts that should be cut out.

My images are generally consistent, with big objects (c.a. 50% of image space) on a white background. Unfortunately, sometimes tiny artifacts may just look bad and make trimming less efficient.

E.g. something like that:

Example

In reality, the big object is not a solid color, it's just a simplified example. It is not necessarily a circle either, it can be a square, rectangle, or something irregular.

I cannot also use any morphology like opening, closing, or erosion. Filters like gaussian or median also are out of the question. I need to keep the big object untouched since the highest possible quality is required.

An ideal solution would be something similar to Contours known for example from OpenCV, where I could find all the uniform objects and if they don't meet certain rules (e.g. threshold of size greater than 5% of the whole image) - fill them with white color.

Is there any similar mechanism in ImageMagick CLI? I've gone through the docs and haven't found a suitable solution to my problem.

Thanks in advance!

EDIT (ImageMagick version):

Version: ImageMagick 7.1.0-47 Q16-HDRI x86_64 20393 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP(5.0) 
Delegates (built-in): bzlib fontconfig freetype gslib heic jng jp2 jpeg lcms lqr ltdl lzma openexr png ps raw tiff webp xml zlib
Compiler: gcc (4.2)

EDIT (Real-life example):

As requested, here is a real-life example. A picture of a coin on a white background, but with some artifacts:

  • noise under the coin (slightly on the left)
  • dot under the coin (slightly on the right)
  • gray irregular shape in the top right corner

The objects might not be necessarily circles like coins but we may assume that there always will be one object with a strong border (no white spaces on the border, like here) and the rest is noise.

enter image description here


Solution

  • Here is one way to do that im Imagemagick 7. First threshold the image so the background is white and the object(s) is black. That will likely be image dependent. NOTE: that JPG is a lousy format, since solid colors are not really truly solid due to the compression. If you can save your images in some non-lossy compressed or uncompress format, that would be better. Then decide on the largest area you need to remove. Use that with connected components processing so that you have only two regions, one white background and one black object. This will be a mask. If you have several objects that is fine also, but they need to be black. I show the textual output showing the two regions. The mask is just the object with the noise removed. So now use the original input, a white image and the mask to composite the first two images so that where the mask is black, the object is used and where the mask is white, the white image will be used. Note, I create the white image by making a copy (clone) of the input and colorizing it 100% with white. The following is in Unix syntax.

    Input:

    enter image description here

    magick coin.jpg -negate -threshold 2% -negate -type bilevel \
    -define connected-components:verbose=true \
    -define connected-components:area-threshold=1000 \
    -define connected-components:mean-color=true \
    -connected-components 4 mask.png
    
    Objects (id: bounding-box centroid area mean-color):
      0: 1000x1000+0+0 525.8,555.7 594824 gray(255)
      44: 722x720+101+58 460.9,417.0 405176 gray(0)
    
    magick coin.jpg \
    \( +clone -fill white -colorize 100 \) \
    mask.png \
    -compose over -composite \
    coin_result.png
    

    Mask

    enter image description here

    Result:

    enter image description here

    See https://imagemagick.org/script/connected-components.php and https://imagemagick.org/Usage/compose/#compose and Composite Operator of Convert (-composite, -geometry) at https://imagemagick.org/Usage/layers/#convert