domingo, 5 de mayo de 2013

Aplicar ruido a una imagen. Tratamiento de imágenes. Parte XV.

Hoy vamos a ver cómo añadir algo de ruido a una imagen a través de la función Random que nos proporcionará número aleatorios (pseudoaleatorios). La función que veremos a continuación (RuidoProgresivo), recibe como parámetros, además de la imagen, el valor del ruido que se quiere generar. Este ruido se va a aplicar de la siguiente forma, por ejemplo, para un píxel que en su canal rojo tiene un valor de 24, y el parámetro que ha recibido la función como valor de ruido es 30, generará el nuevo valor de la siguiente forma.
  1. Genera un número aleatorio entre -30 y 30.
  2. Suma el valor del número generado al píxel correspondiente.
Este proceso lo hace en todos los píxeles para los 3 canales RGB. Como vemos es un proceso extremadamente sencillo, a continuación se muestra la función.

Public Function RuidoProgresivo(ByVal bmp As Bitmap, ByVal valorRuido As Integer, Optional RuidoGris As Boolean = False)
    'Creamos un bitmap con el mismo tamaño que el original
    'Este bitmap será el retorno de la función
    Dim bmp3 As New Bitmap(bmp.Width, bmp.Height)

    Dim rojo, verde, azul, alfa As Integer
    'Inicializar la clase Random  
    Dim Random As New Random()

    Dim ValorRandomRuido As Integer
    'Recorremos la matriz (imagen)
    For i = 0 To bmp.Width - 1
       For j = 0 To bmp.Height - 1
          ValorRandomRuido = Random.Next(-(valorRuido - 1), valorRuido + 1)
          rojo = bmp.GetPixel(i, j).R + ValorRandomRuido

          If RuidoGris = False Then
             ValorRandomRuido = Random.Next(-(valorRuido - 1), valorRuido + 1)
          End If
          verde = bmp.GetPixel(i, j).G + ValorRandomRuido

          If RuidoGris = False Then
             ValorRandomRuido = Random.Next(-(valorRuido - 1), valorRuido + 1)
          End If
          azul = bmp.GetPixel(i, j).B + ValorRandomRuido

          'Si hay valores mayores de 255 los pasamos a 255
          'Si hay valores menores de 0 los pasamos a 0
          If rojo < 0 Then rojo = 0
          If rojo > 255 Then rojo = 255
          If verde < 0 Then verde = 0
          If verde > 255 Then verde = 255
          If azul < 0 Then azul = 0
          If azul > 255 Then azul = 255

          'El canal alfa lo conservamos
          alfa = bmp.GetPixel(i, j).A

          'Pintamos bmp3 con los colores obtenidos
          bmp3.SetPixel(i, j, Color.FromArgb(alfa, rojo, verde, azul))

          Next
    Next
    'Retornas el bitmap con ruido
    Return bmp3
End Function

Además de lo explicado, la función recibe también un parámetro llamado RuidoGris que en caso de ser True, hace que el valor generado aleatoriamente sea el mismo para los tres canales RGB, en caso contrario, se generarían 3 valores diferentes para los tres canales.
Ahora vamos a crear un formulario con una imagen, un botón, un checkbox y un scroll. El resultado del formulario sería el siguiente:

Formulario para aplicar ruido

El código para el formulario sería el siguiente.

Dim bmpOriginal As Bitmap
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    'Guardamos como bitmap el Picturebox
    bmpOriginal = PictureBox1.Image
End Sub

'Aplicamos ruido
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'Si está marcado el checkbox aplicamos ruido en escala de grises
    If chbGrises.Checked = True Then
       PictureBox1.Image = RuidoProgresivo(bmpOriginal, HSruido.Value, True)
    Else
       PictureBox1.Image = RuidoProgresivo(bmpOriginal, HSruido.Value, False)
    End If
End Sub

Private Sub HScrollBar1_Scroll(sender As Object, e As ScrollEventArgs) Handles HSruido.Scroll
    'Actualizamos el valor del label
    lblRuido.Text = HSruido.Value
End Sub

Lo único que hace es crear un Bitmap con la imagen del Picturebox en el load del formulario, y en el evento clic del botón botón llamar a la función para aplicar ruido a la imagen. El resultado después de ejecutar la aplicación y aplicar un ruido de 100 puntos y la opción de escala de grises marcada, sería así:

Imagen después de aplicar ruido

Puedes descargar el código fuente aquí.


4 comentarios:

  1. Hola puedes ayudarme, como podría hacer este efecto en java, y aplicarlo a un Jpanel?

    ResponderEliminar
  2. Hola. Revisa los post de java, y ahí te explica cómo leer los píxeles de una imagen. Una vez hecho esto, es simplemente aplicar el algoritmo.
    Si no encuentras los post de tratamiento de imágenes en java, dímelo.
    Un saludo

    ResponderEliminar
    Respuestas
    1. si ya lo resolví tome el programa que hiciste aquí y lo hice en java y me funciono, es solo que pregunte sin ponerme a analizar estos códigos de VB.NET, pero después de analizarlo comprendí lo que haces en el algoritmo y lo hice.

      Eliminar
  3. hola una consulta. como seria el algoritmo para poder quitar el ruido a una imagen. gracias de antemano

    ResponderEliminar