|
|
Title | Fill in missing pixels in an image |
Keywords | fill, pixels, missing, interpolation, interpolate |
Categories | Graphics, 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.
|
|
|
|
|
|