Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Private Function EdgeDetectWithInvert(bmp As Bitmap) As Bitmap
- 'convert any input bitmap into jpg just to make sure to have the correct byte order
- If Not bmp.RawFormat.Equals(ImageFormat.Jpeg) Then
- Using msJPG As New IO.MemoryStream()
- bmp.Save(msJPG, ImageFormat.Jpeg)
- bmp = CType(Image.FromStream(msJPG), Bitmap)
- End Using
- End If
- 'setting up the lockbits
- Dim raz As Integer = bmp.Height \ 3
- Dim height As Integer = bmp.Height
- Dim width As Integer = bmp.Width
- Dim rect As New Rectangle(Point.Empty, bmp.Size)
- Dim bmpData As BitmapData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat)
- Dim bpp As Integer = If((bmp.PixelFormat = PixelFormat.Format32bppArgb), 2, 3)
- Dim size As Integer = bmpData.Stride * bmpData.Height
- Dim data As Byte() = New Byte(size - 1) {}
- Dim result As Byte() = New Byte(size - 1) {}
- Marshal.Copy(bmpData.Scan0, data, 0, size)
- Marshal.Copy(bmpData.Scan0, result, 0, size) 'duplicate so that edge finding can run in parallel without using pixels as samples that have already been processed themselves
- 'edge detection
- Dim stride As Integer = bmpData.Stride
- 'convert to grayscale first, makes finding edges cheaper later
- Parallel.For(0, width, Sub(totallynewX)
- Dim totallynewi As Integer
- For totallynewY = 0 To height - 1
- totallynewi = totallynewY * stride + totallynewX * bpp
- Dim avg As Byte = CByte(Math.Min(data(totallynewi) * 0.299 + data(totallynewi + 1) * 0.587 + data(totallynewi + 2) * 0.114, 255)) 'formula for accurate grayscale
- result(totallynewi) = avg
- result(totallynewi + 1) = avg
- result(totallynewi + 2) = avg
- Next
- End Sub)
- 'for dynamic ranging later
- Dim brightest, darkest As Integer
- brightest = 0
- darkest = 255
- 'now find edges
- Parallel.For(0, height, Sub(horizontal)
- Dim pixelOriginal, pixelDiagonal, pixelBelow, pixelRight As Integer
- Dim total, index, diff1, diff2, diff3 As Integer
- For vertical = 0 To width - 1
- Dim offset As Integer = 1
- If horizontal = height - 1 OrElse vertical = width - 1 Then offset = 0
- index = horizontal * stride + vertical * bpp
- pixelOriginal = data(index)
- index = (horizontal) * stride + (vertical + offset) * bpp
- pixelBelow = data(index)
- index = (horizontal + offset) * stride + (vertical) * bpp
- pixelRight = data(index)
- index = (horizontal + offset) * stride + (vertical + offset) * bpp
- pixelDiagonal = data(index)
- diff1 = CInt(Math.Floor((pixelOriginal - pixelDiagonal) / 2) + 128)
- diff2 = CInt(Math.Floor((pixelOriginal - pixelBelow) / 2) + 128)
- diff3 = CInt(Math.Floor((pixelOriginal - pixelRight) / 2) + 128)
- 'total = Math.Max(Math.Max(diff1, diff2), diff3)
- total = (diff1 + diff2 + diff3) \ 3
- 'flip extreme contrasts
- 'Dim flipOffset As Integer = CInt(NumericUpDown1.Value)
- 'If total < flipOffset Then total = 255
- 'If total > 255 - flipOffset Then total = 0
- If total > brightest Then brightest = total
- If total < darkest Then darkest = total
- index = horizontal * stride + vertical * bpp
- result(index) = CByte(total)
- result(index + 1) = CByte(total)
- result(index + 2) = CByte(total)
- Next
- End Sub)
- 'now adjust by darkest and brightest
- If brightest < 255 OrElse darkest > 0 Then
- Dim darknessDiff As Integer = darkest
- Dim brightnessDiff As Integer = 255 - brightest
- Parallel.For(0, height, Sub(horizontal)
- Dim pixel As Integer
- Dim index As Integer
- For vertical = 0 To width - 1
- index = horizontal * stride + vertical * bpp
- pixel = result(index)
- If pixel < 128 Then
- pixel -= darknessDiff
- Else
- pixel += brightnessDiff
- End If
- index = horizontal * stride + vertical * bpp
- result(index) = CByte(pixel)
- result(index + 1) = CByte(pixel)
- result(index + 2) = CByte(pixel)
- Next
- End Sub)
- End If
- Marshal.Copy(result, 0, bmpData.Scan0, data.Length)
- bmp.UnlockBits(bmpData)
- Return bmp
- End Function
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement