Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleFill in missing pixels in an image
Keywordsfill, pixels, missing, interpolation, interpolate
CategoriesGraphics, Algorithms
 
This program scans each line in the picture looking for holes of a particular color. The default hole color is red. Click on a pixel in the original image to select a new color.

When it finds a hole, the program fills it in using linear interpolation between the pixels just before and just after the hole.

 
' Resize the image.
Private Sub FillHoles()
Dim pixels() As RGBTriplet
Dim bits_per_pixel As Integer
Dim maxX As Integer
Dim maxY As Integer
Dim Y As Integer
Dim hole_r As Integer
Dim hole_g As Integer
Dim hole_b As Integer
Dim hole_start As Integer
Dim hole_stop As Integer
Dim found_start As Boolean
Dim found_stop As Boolean
Dim r0 As Single
Dim g0 As Single
Dim b0 As Single
Dim dr As Single
Dim dg As Single
Dim db As Single
Dim i As Integer

    Screen.MousePointer = vbHourglass
    DoEvents

    ' Get the holes' RGB values.
    UnRGB lblHoleColor.BackColor, hole_r, hole_g, hole_b

    ' Get the input image's pixels.
    GetBitmapPixels picFrom, pixels, bits_per_pixel

    ' Get the pixel bounds.
    maxX = UBound(pixels, 1)
    maxY = UBound(pixels, 2)

    ' Fill in holes using linear
    ' interpolation on each scanline.
    For Y = 0 To maxY
        hole_start = 1
        Do While hole_start < maxX
            ' Find where the next hole starts.
            found_start = False
            Do While hole_start <= maxX
                With pixels(hole_start, Y)
                    If .rgbRed = hole_r And _
                       .rgbGreen = hole_g And _
                       .rgbBlue = hole_b _
                    Then
                        found_start = True
                        Exit Do
                    End If
                End With
                hole_start = hole_start + 1
            Loop

            ' See if we found the start of a hole.
            If Not found_start Then Exit Do

            ' Find where this hole ends.
            found_stop = False
            hole_stop = hole_start + 1
            Do While hole_stop <= maxX
                With pixels(hole_stop, Y)
                    If .rgbRed <> hole_r Or _
                       .rgbGreen <> hole_g Or _
                       .rgbBlue <> hole_b _
                    Then
                        found_stop = True
                        Exit Do
                    End If
                End With
                hole_stop = hole_stop + 1
            Loop

            ' See if we found the end of a hole.
            If Not found_stop Then Exit Do

            ' Make hole_stop point to
            ' the last pixel in the hole.
            hole_stop = hole_stop - 1

            ' Get the color before the hole.
            With pixels(hole_start - 1, Y)
                r0 = .rgbRed
                g0 = .rgbGreen
                b0 = .rgbBlue
            End With

            ' Calculate the difference per pixel.
            With pixels(hole_stop + 1, Y)
                dr = (.rgbRed - r0) / (hole_stop - _
                    hole_start + 2)
                dg = (.rgbGreen - g0) / (hole_stop - _
                    hole_start + 2)
                db = (.rgbBlue - b0) / (hole_stop - _
                    hole_start + 2)
            End With

            ' Fill the hole.
            For i = hole_start To hole_stop
                r0 = r0 + dr
                g0 = g0 + dg
                b0 = b0 + db
                With pixels(i, Y)
                    .rgbRed = r0
                    .rgbGreen = g0
                    .rgbBlue = b0
                End With
            Next i

            ' Get ready to find the next hole.
            hole_start = hole_stop + 1
        Loop
    Next Y

    ' Display the result.
    SetBitmapPixels picTo, bits_per_pixel, pixels

    Screen.MousePointer = vbDefault
End Sub
 
Note that this method for filling in holes is extremely simple and the literature contains much more sophisticated methods. For example, the program could use differential gradients to fill the holes in from the edges towards the middle.

Because this method scans each line, it works best when the holes are relatively tall and thin (rather than short and wide). You could modify the code to scan by columns instead of rows if you needed to work with short wide holes. Or better still, you could make it consider the shape of each hole and decide which direction to use. This simple example works pretty well, however.

The program also doesn't work well if the hole obscures importantj detail in the picture. For example, if a small line is covered, the interpolation will not regenerate.

This method also uses an exact color to find the image's holes. Amonh other things, that means if you save a picture with red holes in a lossy JPEG or GIF format, the result will not be truely red so the program will not find the holes correctly. To handle this situation, load the picture in a bitmap editor, make the holes red, and save the results as a BMP file. Run the program to fill in the hole. Then convert the result into JPEG or GIF format if you like.

The example included in the download was generates in this way (the bitmap files are not included because they're big). In this example, the text in the lower left corner had a single color and that color was used to define the holes. If the areas you want to remove contain several colors, use a bitmap editor to cut out little boxes or blobs containing the areas you want to remove.

See my book Visual Basic Graphics Programming for more information on image manipulation in Visual Basic.

 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated