Click here to Skip to main content
15,891,372 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am working on a project, in which i have to clear the background of photo on the fly.
we will put an object of specific color (i.e. yellow) on the back of the person who's photo is required and when the camera Take Photo event is called, the code will automaticaly clear the yellow background and merge the picture on another background image.

The code is given as under:
<code>
Image i = Crop(pictureBox1.Image, rectWidth, rectHeight, rectX, rectY);
Bitmap img1 = new Bitmap(i);
Bitmap img2 = new Bitmap(pictureBox2.Image);

Color transparencyColor = img1.GetPixel(0, 0);
img1.MakeTransparent(img1.GetPixel(1, 1)); 
using (Graphics g = Graphics.FromImage(img2))
{
     using (Image skinImage = (Image)img1)
     {
          // draw image         
          g.DrawImage(skinImage, (img2.Width - img1.Width)/2,(img2.Height- img1.Height)/2,img1.Width, img1.Height);
     }
}
pictureBox2.Image = (Image)img2;
</code>


The function MakeTransparent is not the only way i have tried, I have experimented almost everything i found related to make background transparent including running a loop on every pixel and changing its colour if required.

The code is doing the job to make background color transparent and merge is also ok but the main problem which i am facing is that the curves of the photo are still showing yellow dots and solid lines which is very bad. I am not sure if i can place an image in this question area.

Can any one tell me how to completely clear the background colour and make background fully transparent with smooth edges and deep curves are also transparent.
Posted
Updated 24-Jan-11 23:26pm
v2

The way you call the DrawImage:
g.DrawImage(skinImage, (img2.Width - img1.Width)/2,(img2.Height- img1.Height)/2,img1.Width, img1.Height);


It also looks like image is resized (or whatever you're doing with it. I can image this means that some colors are pressed together and become a "new" color that is not the transparent color. I would suggest first just make it transparent while keeping width and height unchanged and see what happens then.

Meaning... first just try the exact example ;-) :
http://msdn.microsoft.com/en-us/library/4zzst10b.aspx[^]

Good luck!
 
Share this answer
 
v2
Comments
mabpak 25-Jan-11 6:11am    
No, i am not resizing the image just placing the image in the center of background image and the disturbing yellow color i mentioned in my question is not because of any chemical reaction but the makeTransparent event is not clearing the yellow color completely. the Procedure works fine when the middle content is in good shape (like round or rectangle). but in my case, the photo contains picture of a girl whose hairs are scattered and the inner side of two bundles of hairs are still yellow and area near ears is also yello.
E.F. Nijboer 25-Jan-11 6:23am    
Check this:
Open the image with a tool like mspaint and use the pipette to select a color from the image. You can double click the selected color (under the tool buttons) to view the color select form and have a look at the rgb values. Check a few different pixels to make sure that they are exactly the same rgb value. If that is not the case then that is the reason why it isn't working. It only works with exactly that specific color you entered as transparent color.
You can also check it by opening the image in paint and using a color (like purple) and flood fill a yellow area. If there are still yellow pixels showing than they are just a little different than the yelow color you just clicked on.
This method isn't going to work. If you open your yellow image in a picture viewer and zoom in close, you'll see that not every Yellow pixel is identical in color to every other Yellow pixel. Your code assumes that every Yellow pixel is identical. You have to have a Yellow pixel +/- a percentage to establish a threshold of what a Yellow pixel should be. You're making a range of colors be treated as Yellow.

One you have that threshold, you can scan the image, pixel-by-pixel, and replace them with your true background color pixel, say Magenta, then set that as the transparent key.

Search the articles for "Image processing for dummies" (no, serisouly!) for examples on how to do something like this in C#.
 
Share this answer
 
v2
What you are trying to do is generally called chromakeying ("green screen" or "blue screen"). Rounded edges are always a problem because of antialiasing. Most programs used to do this have various sorts of "feathering" options to tone down the edge effects, and even the expensive ones can't always get it to work nicely.

Basically, what I'm saying is don't make yourself crazy trying to get it perfect with an automatic process...nearly impossible. Look for "feathering" edges or "antialiasing" functions to get you close. But: this has to be done after the background has been replaced, not before. It won't work as you want if done before the new background is in place.

Hints to make the whole thing easier: use a chromakey background, not yellow. Have the background as far back from the subject as you can manage. Evenly (and brightly) light the background. Use a rim light on the subject (a backlight to get rid of edge shadowing--even better if you can use a complementary color for the rimlight).
 
Share this answer
 
Comments
mabpak 26-Jan-11 2:30am    
Thanks, I think I have got alot to test by all the ideas given by Mr. GenJerDan, Mr. Dave Kreskowiak and Mr. E. F. Nijbor. Thanks to all of you and I am now working on the ideas given by all of you and I will definately let you people know about my progress in the evening.
I thank you all for all the help, I have tried to give a range and the results are not perfect, but near to acceptional range, i hope the client will accept the results but that is another story. For the timer, I have used the looping technique and provided a colour range to check. The code is given below for review and betterment:

C#
for (int x = 0; x < img1.Width; x++)
for (int y = 0; y < img1.Height; y++)
{
    Color pixel = img1.GetPixel(x, y);
    if (pixel.R >= transparencyColor.R - 30
    && pixel.R <= transparencyColor.R + 30
    && pixel.G >= transparencyColor.G - 30
    && pixel.G <= transparencyColor.G + 30
    && pixel.B >= transparencyColor.B - 30
    && pixel.B <= transparencyColor.B + 30)// >= lowColor && pixel<=highColor)
        img1.SetPixel(x, y, Color.Transparent);
}


Waiting for more suggestions.
Thanks again and Take Care.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900