views:

710

answers:

4

Using images of articles of clothing taken against a consistent background, I would like to make all pixels in the image transparent except for the clothing. What is the best way to go about this? I have researched the algorithms that are common for this and the open source library opencv. Aside from rolling my own or using opencv is there an easy way to do this? I am open to any language or platform.

Thanks

A: 

if you know the exact color intensity of the background and it will never change and the articles of clothing will never coincide with this color, then this is a simple application of background subtraction, that is everything that is not a particular color intensity is considered an "on" pixel, one of interest. You can then use connected component labeling (http://en.wikipedia.org/wiki/Connected%5FComponent%5FLabeling) to figure out seperate groupings of objects.

ldog
Thanks for the advice. The images will be taken by the user though. So I cannot know the exact color.
Joe Cannatti
A: 

for a color image, with the same background on every pictures:

  • convert your image to HSV or HSL
  • determine the Hue value of the background (+/-10): do this step once, using photoshop for example, then use the same value on all your pictures.
  • perform a color threshold: on the hue channel exclude the hue of the background ([0,hue[ + ]hue, 255] typically), for all other channels include the whole value range (0 to 255 typically). this will select pixels which are NOT the background.
  • perform a "fill holes" operation (normally found along blob analysis or labelling functions) to complete the part of the clothes which may have been of the same color than the background.
  • now you have an image which is a "mask" of the clothes: non-zero pixels represents the clothes, 0 pixels represents the background.
  • this step of the processing depends on how you want to make pixels transparent: typically, if you save your image as PNG with an alpha (transparency) channel, use a logical AND (also called "masking") operation between the alpha channel of the original image and the mask build in the previous step.
  • voilà, the background disappeared, save the resulting image.
Adrien Plisson
well, i just read the comment on the all white or all dark background... this algorithm will not fit since background will not be the same on every pictures.
Adrien Plisson
+1  A: 

Basically, find the color of the background and subtract it, but I guess you knew this. It's a little tricky to do this all automatically, but it seems possible.

First, take a look at blob detection with OpenCV and see if this is basically done for you.

To do it yourself:

find the background: There are several options. Probably easiest is to histogram the image, and the large number of pixels with similar values are the background, and if there are two large collections, the background will be the one with a big hole in the middle. Another approach is to take a band around the perimeter as the background color, but this seems inferior as, for example, reflection from a flash could dramatically brighten more centrally located background pixels.

remove the background: a first take at this would be to threshold the image based on the background color, and then run the "open" or "close" algorithms on this, and then use this as a mask to select your clothing article. (The point of open/close is to not remove small background colored items on the clothing, like black buttons on a white blouse, or, say, bright reflections on black clothing.)

OpenCV is a good tool for this.

The trickiest part of this will probably be at the shadow around the object (e.g. a black jacket on a white background will have a continuous gray shadow at some of the edges and where to make this cut?), but if you get this far, post another question.

tom10
+2  A: 

If your background is consistend in an image but inconsistent across images it could get tricky, but here is what I would do:

  1. Separate the image into some intensity/colour form such as YUV or Lab.
  2. Make a histogram over the colour part. Find the most occuring colour, this is (most likely) your background (update) maybe a better trick here would be to find the most occuring colour of all pixels within one or two pixels from the edge of the image.
  3. Starting from the eddges of the image, set all pixels that have that colour and are connected to the edge through pixels of that colour to transparent.
  4. The edge of the piece of clothing is now going to look a bit ugly because it consist of pixels that gain their colour from both the background and the piece of clothing. To combat this you need to do a bit more work:

    1. Find the edge of the piece of clothing through some edge detection mechanism.
    2. Replace the colour of the edge pixels with a blend of the colour just "inside" the edge pixel (i.e. the colour of the clothing in that region) and transparent (if your output image format supports that).
    3. If you want to get really fancy, you increase the transparency depending on how much "like" the background colour the colour of that pixel is.
jilles de wit
something tells me that, if someone takes a picture of a piece of clothing, it will arrange his photo so that it mostly fills the image. the most occurring colour will therefore NOT be the background. also with this algorithm, if by any chance, the clothe is touching the edge, you will remove the whole piece of clothe from the image...
Adrien Plisson
This is a good point. So you should probably look at the colour most prevalent near the edge of the image instead.
jilles de wit