How do I programmatically remove the background of an image by making it transparent in ruby?

I have a bunch of product images and I would like to remove the background of each ruby ​​code. Here are some sample images I put on imgur.

enter image description here

I'll give an example here so you can see, but I didn't want to post a bunch of images. This is the simplest one. It only has a white background, but some of the products have more complex backgrounds. I know I'm doing something similar on this image probably won't work, so I would like to figure it out and gracefully discard it by actually removing the background and kind of notifying me.

I am using ruby ​​on rails 3 and carrierwave as my upload handler.

Is this possible, or will I actually be able to remove the white backgrounds?

+3


source to share


4 answers


To remove white images from images, execute a bash script using imagemagick:

#!/bin/bash

# pass the image path, image name and threshold(used as a fuzz factor) to the bash script
IMGPATH=$1
IMGNAME=$2
THRESHOLD=$3

# start real
convert ${IMGPATH}${IMGNAME} \( +clone -fx 'p{0,0}' \)  -compose Difference  -composite   -modulate 100,0  +matte  ${IMGPATH}${IMGNAME}_difference.png

# remove the black, replace with transparency
convert ${IMGPATH}${IMGNAME}_difference.png -bordercolor white -border 1x1 -matte -fill none -fuzz 7% -draw 'matte 1,1 floodfill' -shave 1x1 ${IMGPATH}${IMGNAME}_removed_black.png
composite  -compose Dst_Over -tile pattern:checkerboard ${IMGPATH}${IMGNAME}_removed_black.png ${IMGPATH}${IMGNAME}_removed_black_check.png

# create the matte 
convert ${IMGPATH}${IMGNAME}_removed_black.png -channel matte -separate  +matte ${IMGPATH}${IMGNAME}_matte.png

# negate the colors
convert ${IMGPATH}${IMGNAME}_matte.png -negate -blur 0x1 ${IMGPATH}${IMGNAME}_matte-negated.png

# eroding matte(to remove remaining white border pixels from clipped foreground)
convert ${IMGPATH}${IMGNAME}_matte.png -morphology Erode Diamond ${IMGPATH}${IMGNAME}_erode_matte.png

# you are going for: white interior, black exterior
composite -compose CopyOpacity ${IMGPATH}${IMGNAME}_erode_matte.png ${IMGPATH}${IMGNAME} ${IMGPATH}${IMGNAME}_finished.png

#remove white border pixels
convert ${IMGPATH}${IMGNAME}_finished.png -bordercolor white -border 1x1 -matte -fill none -fuzz  ${THRESHOLD}% -draw 'matte 1,1 floodfill' -shave 1x1 ${IMGPATH}${IMGNAME}_final.png

#deleting extra files
rm ${IMGPATH}${IMGNAME}_difference.png
rm ${IMGPATH}${IMGNAME}_removed_black.png
rm ${IMGPATH}${IMGNAME}_removed_black_check.png
rm ${IMGPATH}${IMGNAME}_matte.png
rm ${IMGPATH}${IMGNAME}_matte-negated.png
rm ${IMGPATH}${IMGNAME}_finished.png

      

I am having a problem removing white border pixels from the resulting image. The evolution of the binary mask and shaving the remaining pixels solves the problem.




Source: convert white to transparent

+4


source


Take a look at http://www.imagemagick.org/Usage/masking/#bg_remove



You may be quite good at handling solid backgrounds, but non-solid backgrounds (like the one you linked to an image) are pretty tricky and I doubt you can think of a single method that will work for all images.

+1


source


ImageMagick is the most likely solution here (perhaps with a mini magic stone for the rails), but as you think it is unlikely that you will get a good result in some cases. Simply turning all white pixels transparent is likely to leave jagged edges that will be quite obvious against a non-white background. But there are a surprising number of options that give you a lot of control, which you might have in PhotoShop or elsewhere - you create a mask that finds the outline of a shape within a certain tolerance of hue, color, or the like, rather than changing all the corresponding pixels to transparent. I think you will have to change the PNG format as well, since I don't believe JPEG supports alpha transparency.

CarrierWave is the right tool for this kind of processing - you can use its capabilities to store the original file and make multiple automatic attempts using different parameters (which will save different files without touching the original).

http://www.imagemagick.org/Usage/masking/#two_background might get you started.

+1


source


Assuming you want to process a batch of unrelated files. As far as I understand, you cannot, as removing the background (pulling matte) is a serious underused issue and necessarily requires user input. A consistent background color such as a blue or green screen will free you from doing a good job with free programs like gimp, but nothing can do a great job unless you want to read fresh scientific journals bleeding by example

Poisson matting

http://research.microsoft.com/apps/pubs/default.aspx?id=69117

OR

Closed form solution for natural matte appearance

www.wisdom.weizmann.ac.il/~levina/papers/Matting-Levin-Lischinski-Weiss-CVPR06.pdf

The later language has MATLAB code for academic purposes. But these are all serious lenders and can use all your system resources for large files, as can be installed from the pullmatt trial app from http://PixelFeather.com/download , which by the way does the best job for the natural image problem of any proprietary software, including photoshop.

-1


source







All Articles