vb.netimageisonoise

simulate iso noise in vb.net


i have taken a lot of pictures with a long exposure time and low ISO to have nice, clean images. Then after training my nerual network with these images, I found that the real images have a lot of camera noise, since due to speed requirements they have been taken with low shutter speed and high ISO settings. On dark objects, my neural network doesnt work anymore and needs to be retrained with images containing ISO noise.

Is tehre a way I can add ISO noise to the images using vb.net? It must be vb.net since the software that generates the dataset has been written in vb.net, and adding noise would be an additional step in the proces of creating the dataset.

Any help greatly appreciated.


Solution

  • I found a solution.

    I took a picture with the lens covered at very high ISO settings. the resulting image is a black image with ISO noise.

    Then I added each pixel's value to the values of the nice images. The result is perfect and realistic.

    'add noise
    Public Shared Function AddNoise(imageSource As Bitmap, imageNoise As Bitmap) As Bitmap
    
        Dim source As New Bitmap(imageSource.Width, imageSource.Height, PixelFormat.Format32bppArgb)
        source.SetResolution(imageSource.HorizontalResolution, imageSource.VerticalResolution)
    
        Using g = Graphics.FromImage(source)
            g.PixelOffsetMode = PixelOffsetMode.Half
            g.DrawImage(imageSource, Point.Empty)
        End Using
        Dim destImage As Bitmap = New Bitmap(source.Width, source.Height, PixelFormat.Format32bppArgb)
        destImage.SetResolution(imageSource.HorizontalResolution, imageSource.VerticalResolution)
        For Each item As PropertyItem In imageSource.PropertyItems
            source.SetPropertyItem(item)
            destImage.SetPropertyItem(item)
        Next
    
        Dim dataFrom = source.LockBits(New Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)
        Dim dataTo = destImage.LockBits(New Rectangle(0, 0, destImage.Width, destImage.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb)
    
        Dim buffer As Byte() = New Byte(Math.Abs(dataFrom.Stride) * dataFrom.Height - 1) {}
        Marshal.Copy(dataFrom.Scan0, buffer, 0, buffer.Length)
    
        Dim sourceNoise As New Bitmap(imageNoise.Width, imageNoise.Height, PixelFormat.Format32bppArgb)
        sourceNoise.SetResolution(imageNoise.HorizontalResolution, imageNoise.VerticalResolution)
        Using g = Graphics.FromImage(sourceNoise)
            g.PixelOffsetMode = PixelOffsetMode.Half
            g.DrawImage(imageNoise, Point.Empty)
        End Using
    
        Dim destImageNoise As Bitmap = New Bitmap(sourceNoise.Width, sourceNoise.Height, PixelFormat.Format32bppArgb)
        destImageNoise.SetResolution(imageNoise.HorizontalResolution, imageNoise.VerticalResolution)
        For Each item As PropertyItem In imageNoise.PropertyItems
            sourceNoise.SetPropertyItem(item)
            destImageNoise.SetPropertyItem(item)
        Next
    
        Dim dataFromNoise = sourceNoise.LockBits(New Rectangle(0, 0, sourceNoise.Width, sourceNoise.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)
        Dim dataToNoise = destImageNoise.LockBits(New Rectangle(0, 0, destImageNoise.Width, destImageNoise.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb)
    
        Dim bufferNoise As Byte() = New Byte(Math.Abs(dataFromNoise.Stride) * dataFromNoise.Height - 1) {}
        Marshal.Copy(dataFromNoise.Scan0, bufferNoise, 0, bufferNoise.Length)
    
        sourceNoise.UnlockBits(dataFromNoise)
    
    
    
        source.UnlockBits(dataFrom)
        Dim bytesPerPixel As Integer = Image.GetPixelFormatSize(source.PixelFormat) \ 8
    
        For pos As Integer = 0 To buffer.Length - 1 Step bytesPerPixel
    
    
            buffer(pos) = CByte(Math.Max(Math.Min(255, CInt(buffer(pos)) + CInt(bufferNoise(pos))), 0))
            buffer(pos + 1) = CByte(Math.Max(Math.Min(255, CInt(buffer(pos + 1)) + CInt(bufferNoise(pos + 1))), 0))
            buffer(pos + 2) = CByte(Math.Max(Math.Min(255, CInt(buffer(pos + 2)) + CInt(bufferNoise(pos + 2))), 0))
    
        Next
    
    
        Marshal.Copy(buffer, 0, dataTo.Scan0, buffer.Length)
        destImage.UnlockBits(dataTo)
        Return destImage
    End Function