Remove White Background from an Image and Make It Transparent

后端 未结 9 985
一向
一向 2020-11-29 16:01

We\'re trying to do the following in Mathematica - RMagick remove white background from image and make it transparent.

But with actual photos it ends up looking lous

9条回答
  •  被撕碎了的回忆
    2020-11-29 16:31

    Here's a try at implementing Mark Ransom's approach, with some help from belisarius's mask generation:

    Locate the boundary of the object:

    img1 = SetAlphaChannel[img, 1];
    erosionamount=2;
    mb = ColorNegate@ChanVeseBinarize[img, TargetColor -> {1., 1., 1}, 
          "LengthPenalty" -> 10];
    edge = ImageSubtract[Dilation[mb, 2], Erosion[mb, erosionamount]];
    
    ImageApply[{1, 0, 0} &, img, Masking ->edge]
    

    figure edge

    Set the alpha values:

    edgealpha = ImageMultiply[ImageFilter[(1 - Mean[Flatten[#]]^5) &, 
       ColorConvert[img, "GrayScale"], 2, Masking -> edge], edge];
    imagealpha = ImageAdd[edgealpha, Erosion[mb, erosionamount]];
    img2 = SetAlphaChannel[img, imagealpha];
    

    Reverse color blend:

    img3 = ImageApply[Module[{c, \[Alpha], bc, fc},
       bc = {1, 1, 1};
       c = {#[[1]], #[[2]], #[[3]]};
       \[Alpha] = #[[4]];
       If[\[Alpha] > 0, Flatten[{(c - bc (1 - \[Alpha]))/\[Alpha], \[Alpha]}], {0., 0., 
       0., 0}]] &, img2];
    
    Show[img3, Background -> Pink]
    

    pink background

    Notice how some of the edges have white fuzz? Compare that with the red outline in the first image. We need a better edge detector. Increasing the erosion amount helps with the fuzz, but then other sides become too transparent, so there is a tradeoff on the width of the edge mask. It's pretty good, though, considering there is no blur operation, per se.

    It would be instructive to run the algorithm on a variety of images to test its robustness, to see how automatic it is.

提交回复
热议问题