Smooth
This algorithm attempts to capture important patterns in image without noise.
Private Class ConvolutionMatrix
Public Sub New()
Pixel = 1
Factor = 1
End Sub
Public Sub Apply(Val As Integer)
TopLeft = Val
TopMid = Val
TopRight = Val
MidLeft = Val
MidRight = Val
BottomLeft = Val
BottomMid = Val
BottomRight = Val
Pixel = Val
End Sub
Public Property TopLeft() As Integer
Get
Return m_TopLeft
End Get
Set(value As Integer)
m_TopLeft = value
End Set
End Property
Private m_TopLeft As Integer
Public Property TopMid() As Integer
Get
Return m_TopMid
End Get
Set(value As Integer)
m_TopMid = value
End Set
End Property
Private m_TopMid As Integer
Public Property TopRight() As Integer
Get
Return m_TopRight
End Get
Set(value As Integer)
m_TopRight = value
End Set
End Property
Private m_TopRight As Integer
Public Property MidLeft() As Integer
Get
Return m_MidLeft
End Get
Set(value As Integer)
m_MidLeft = value
End Set
End Property
Private m_MidLeft As Integer
Public Property MidRight() As Integer
Get
Return m_MidRight
End Get
Set(value As Integer)
m_MidRight = value
End Set
End Property
Private m_MidRight As Integer
Public Property BottomLeft() As Integer
Get
Return m_BottomLeft
End Get
Set(value As Integer)
m_BottomLeft = value
End Set
End Property
Private m_BottomLeft As Integer
Public Property BottomMid() As Integer
Get
Return m_BottomMid
End Get
Set(value As Integer)
m_BottomMid = value
End Set
End Property
Private m_BottomMid As Integer
Public Property BottomRight() As Integer
Get
Return m_BottomRight
End Get
Set(value As Integer)
m_BottomRight = value
End Set
End Property
Private m_BottomRight As Integer
Public Property Pixel() As Integer
Get
Return m_Pixel
End Get
Set(value As Integer)
m_Pixel = value
End Set
End Property
Private m_Pixel As Integer
Public Property Factor() As Integer
Get
Return m_Factor
End Get
Set(value As Integer)
m_Factor = value
End Set
End Property
Private m_Factor As Integer
Public Property Offset() As Integer
Get
Return m_Offset
End Get
Set(value As Integer)
m_Offset = value
End Set
End Property
Private m_Offset As Integer
End Class
Private Class Convolution
Public Sub Convolution3x3(ByRef bmp As Bitmap)
Dim Factor As Integer = Matrix.Factor
If Factor = 0 Then
Return
End If
Dim TopLeft As Integer = Matrix.TopLeft
Dim TopMid As Integer = Matrix.TopMid
Dim TopRight As Integer = Matrix.TopRight
Dim MidLeft As Integer = Matrix.MidLeft
Dim MidRight As Integer = Matrix.MidRight
Dim BottomLeft As Integer = Matrix.BottomLeft
Dim BottomMid As Integer = Matrix.BottomMid
Dim BottomRight As Integer = Matrix.BottomRight
Dim Pixel As Integer = Matrix.Pixel
Dim Offset As Integer = Matrix.Offset
Dim TempBmp As Bitmap = bmp.Clone()
Dim bmpData As BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb)
Dim TempBmpData As BitmapData = TempBmp.LockBits(New Rectangle(0, 0, TempBmp.Width, TempBmp.Height), ImageLockMode.[ReadOnly], PixelFormat.Format24bppRgb)
Dim ptr As IntPtr = bmpData.Scan0
Dim TempPtr As IntPtr = TempBmpData.Scan0
Dim Pix As Integer = 0
Dim Stride As Integer = bmpData.Stride
Dim DoubleStride As Integer = Stride * 2
Dim Width As Integer = bmp.Width - 2
Dim Height As Integer = bmp.Height - 2
Dim stopAddress As Integer = CInt(ptr) + bmpData.Stride * bmpData.Height
For y As Integer = 0 To Height - 1
For x As Integer = 0 To Width - 1
Pix = (((((Marshal.ReadByte(TempPtr + 2) * TopLeft) + (Marshal.ReadByte(TempPtr + 5) * TopMid) + (Marshal.ReadByte(TempPtr + 8) * TopRight)) + _
((Marshal.ReadByte(TempPtr + 2 + Stride) * MidLeft) + (Marshal.ReadByte(TempPtr + 5 + Stride) * Pixel) + (Marshal.ReadByte(TempPtr + 8 + Stride) * MidRight)) + _
((Marshal.ReadByte(TempPtr + 2 + DoubleStride) * BottomLeft) + (Marshal.ReadByte(TempPtr + 5 + DoubleStride) * BottomMid) + (Marshal.ReadByte(TempPtr + 8 + DoubleStride) * BottomRight))) \ Factor) + Offset)
If Pix < 0 Then
Pix = 0
ElseIf Pix > 255 Then
Pix = 255
End If
Marshal.WriteByte(ptr + 5 + Stride, CByte(Pix))
Pix = (((((Marshal.ReadByte(TempPtr + 1) * TopLeft) + (Marshal.ReadByte(TempPtr + 4) * TopMid) + (Marshal.ReadByte(TempPtr + 7) * TopRight)) + _
((Marshal.ReadByte(TempPtr + 1 + Stride) * MidLeft) + (Marshal.ReadByte(TempPtr + 4 + Stride) * Pixel) + (Marshal.ReadByte(TempPtr + 7 + Stride) * MidRight)) + _
((Marshal.ReadByte(TempPtr + 1 + DoubleStride) * BottomLeft) + (Marshal.ReadByte(TempPtr + 4 + DoubleStride) * BottomMid) + (Marshal.ReadByte(TempPtr + 7 + DoubleStride) * BottomRight))) \ Factor) + Offset)
If Pix < 0 Then
Pix = 0
ElseIf Pix > 255 Then
Pix = 255
End If
Marshal.WriteByte(ptr + 4 + Stride, CByte(Pix))
Pix = (((((Marshal.ReadByte(TempPtr) * TopLeft) + (Marshal.ReadByte(TempPtr + 3) * TopMid) + (Marshal.ReadByte(TempPtr + 6) * TopRight)) + _
((Marshal.ReadByte(TempPtr + Stride) * MidLeft) + (Marshal.ReadByte(TempPtr + 3 + Stride) * Pixel) + (Marshal.ReadByte(TempPtr + 6 + Stride) * MidRight)) + _
((Marshal.ReadByte(TempPtr + DoubleStride) * BottomLeft) + (Marshal.ReadByte(TempPtr + 3 + DoubleStride) * BottomMid) + (Marshal.ReadByte(TempPtr + 6 + DoubleStride) * BottomRight))) \ Factor) + Offset)
If Pix < 0 Then
Pix = 0
ElseIf Pix > 255 Then
Pix = 255
End If
Marshal.WriteByte(ptr + 3 + Stride, CByte(Pix))
ptr += 3
TempPtr += 3
Next
Next
bmp.UnlockBits(bmpData)
TempBmp.UnlockBits(TempBmpData)
End Sub
Public Property Matrix() As ConvolutionMatrix
Get
Return m_Matrix
End Get
Set(value As ConvolutionMatrix)
m_Matrix = value
End Set
End Property
Private m_Matrix As ConvolutionMatrix
End Class
Public Shared Sub ApplySmooth(ByRef bmp As Bitmap, weight As Integer)
Dim m As New ConvolutionMatrix()
m.Apply(1)
m.Pixel = weight
m.Factor = weight + 8
Dim C As New Convolution()
C.Matrix = m
C.Convolution3x3(bmp)
End Sub
Example
DIm b As Bitmap = CType(Image.FromFile("rose.jpg"), Bitmap)
ApplySmooth(b, 1)