Traitée how to remove shadow from depth image?

  • jeudi 29 septembre 2011 09:18
     
     

    Hi every one

    how can I remove shadow of objects from depth image?

    I need your help please,,,

    Best Regards

    Saleh

     


    Best Regards

Toutes les réponses

  • jeudi 29 septembre 2011 17:00
     
     Traitée
    To the extent they can be removed (since by definition the shadow is where there is no data available), I have previously suggested and demonstrated that you can fill in much of the shadows by doing in-filling from adjacent cells.
    Basically, for each pixel, if the value is 0,0,0 (i.e. no data), then calculate a new value for that cell based on the values of the adjacent pixels.  Find the average of the non-zero pixels surrounding that pixel, and populate it.  This, for me, at least, reduces most or all of the shadows.
    Here's my original post:
    http://mattharvest.com/?p=27
  • vendredi 30 septembre 2011 10:43
     
     

    Hi mattharvest,

    Thats good. could you tell me how do you do in-filling? please

    Regards

    Saleh 


    Best Regards
  • vendredi 30 septembre 2011 13:10
     
      A du code

    Well, I described the technique above.  That said, here's my method.  It relies on my own ColoredPixel class, which is basically a class that stores info for a particular pixel (x,y,r,g,b,a, etc.).

     

    private byte[] inFill(byte[] returnBytes, int width, int height)
            {
                const int BlueIndex = 0;
                const int GreenIndex = 1;
                const int RedIndex = 2;
    
                var index=0;
                for (int y = 0; y<height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        index = (x + (y * width)) * 4;
                        byte red = returnBytes[index + RedIndex];
                        byte green = returnBytes[index + GreenIndex];
                        byte blue = returnBytes[index + BlueIndex];
    
                        ColoredPixel currentPixel = new ColoredPixel(red, green, blue); //this cannot fail
                        if (currentPixel.NeedsFill()) //it's white, so it needs filling
                        {
                            try
                            {
                                var topIndex = (x + ((y - 1) * width)) * 4;
                                var bottomIndex = (x + ((y + 1) * width)) * 4;
                                var rightIndex = ((x + 1) + (y * width)) * 4;
                                var leftIndex = ((x - 1) + (y * width)) * 4;
    
                                ColoredPixel topPixel, bottomPixel, rightPixel, leftPixel;
    
                                topPixel = new ColoredPixel(returnBytes[index + 2], returnBytes[index + 1], returnBytes[index]);
                                bottomPixel = new ColoredPixel(returnBytes[bottomIndex + 2], returnBytes[bottomIndex + 1], returnBytes[bottomIndex]);
                                rightPixel = new ColoredPixel(returnBytes[rightIndex + 2], returnBytes[rightIndex + 1], returnBytes[rightIndex]);
                                leftPixel = new ColoredPixel(returnBytes[leftIndex + 2], returnBytes[leftIndex + 1], returnBytes[leftIndex]);
    
                                var topRightIndex = ((x + 1) + ((y - 1) * width)) * 4;
                                var topLeftIndex = ((x - 1) + ((y - 1) * width)) * 4;
                                var bottomRightIndex = ((x + 1) + ((y + 1) * width)) * 4;
                                var bottomLeftIndex = ((x - 1) + ((y + 1) * width)) * 4;
    
                                ColoredPixel topRightPixel, topLeftPixel, bottomRightPixel, bottomLeftPixel;
    
                                topRightPixel = new ColoredPixel(returnBytes[topRightIndex + 2], returnBytes[topRightIndex + 1], returnBytes[topRightIndex]);
                                topLeftPixel = new ColoredPixel(returnBytes[topLeftIndex + 2], returnBytes[topLeftIndex + 1], returnBytes[topLeftIndex]);
                                bottomRightPixel = new ColoredPixel(returnBytes[bottomRightIndex + 2], returnBytes[bottomRightIndex + 1], returnBytes[bottomRightIndex]);
                                bottomLeftPixel = new ColoredPixel(returnBytes[bottomLeftIndex + 2], returnBytes[bottomLeftIndex + 1], returnBytes[bottomLeftIndex]);
    
                                //if we get here without an exception, we have pixels on all four sides, so we can try to infill
    
                                ColoredPixel averagePixel = new ColoredPixel();
                                int AverageCount = 0;
                                if(!topPixel.NeedsFill()) 
                                {
                                    averagePixel.R += topPixel.R;
                                    averagePixel.G += topPixel.G;
                                    averagePixel.B += topPixel.B;
                                    AverageCount++;
                                }
                                if (!bottomPixel.NeedsFill())
                                {
                                    averagePixel.R += bottomPixel.R;
                                    averagePixel.G += bottomPixel.G;
                                    averagePixel.B += bottomPixel.B;
                                    AverageCount++;
                                }
                                if (!rightPixel.NeedsFill())
                                {
                                    averagePixel.R += rightPixel.R;
                                    averagePixel.G += rightPixel.G;
                                    averagePixel.B += rightPixel.B;
                                    AverageCount++;
                                }
                                if (!leftPixel.NeedsFill())
                                {
                                    averagePixel.R += leftPixel.R;
                                    averagePixel.G += leftPixel.G;
                                    averagePixel.B += leftPixel.B;
                                    AverageCount++;
                                }
    
                                if (!topRightPixel.NeedsFill())
                                {
                                    averagePixel.R += (byte)(topRightPixel.R / 3);
                                    averagePixel.G += (byte)(topRightPixel.G / 3);
                                    averagePixel.B += (byte)(topRightPixel.B / 3);
                                    AverageCount++;
                                }
                                if (!topLeftPixel.NeedsFill())
                                {
                                    averagePixel.R += (byte)(topLeftPixel.R / 3);
                                    averagePixel.G += (byte)(topLeftPixel.G / 3);
                                    averagePixel.B += (byte)(topLeftPixel.B / 3);
                                    AverageCount++;
                                }
                                if (!bottomRightPixel.NeedsFill())
                                {
                                    averagePixel.R += (byte)(bottomRightPixel.R / 3);
                                    averagePixel.G += (byte)(bottomRightPixel.G / 3);
                                    averagePixel.B += (byte)(bottomRightPixel.B / 3);
                                    AverageCount++;
                                }
                                if (!bottomLeftPixel.NeedsFill())
                                {
                                    averagePixel.R += (byte)(bottomLeftPixel.R / 3);
                                    averagePixel.G += (byte)(bottomLeftPixel.G / 3);
                                    averagePixel.B += (byte)(bottomLeftPixel.B / 3);
                                    AverageCount++;
                                }
    
                                if (AverageCount > 0)
                                {
                                    currentPixel.R = (byte)(averagePixel.R / AverageCount);
                                    currentPixel.B = (byte)(averagePixel.B / AverageCount);
                                    currentPixel.G = (byte)(averagePixel.G / AverageCount);
                                }
                                else
                                {
                                    currentPixel = averagePixel;
                                }
                            }
                            catch (Exception e)
                            {
                                // do nothing...this is basically just an out of range error
                                Console.WriteLine("Error doing InFill: " + e.ToString());
                            }
                            returnBytes[index + RedIndex] = currentPixel.R;
                            returnBytes[index + GreenIndex] = currentPixel.G;
                            returnBytes[index + BlueIndex] = currentPixel.B;
                        }
                        else //it's NOT white, so it doesn't need infilling
                        {
                            //so don't change the returnBytes
                        }
                    }
                }
                
                return returnBytes;
            }
    


  • lundi 16 avril 2012 11:11
     
     

    Your method really helps me a lot ,mattharvest.

    I modify it and use it in Win SDK 1.0 , and that in-filling works!

    love you so much!!!!!!

  • mercredi 25 avril 2012 11:21
     
     

    Your method really helps me a lot ,mattharvest.

    I modify it and use it in Win SDK 1.0 , and that in-filling works!

    love you so much!!!!!!

    Can you put the code here, please? ^^