viernes, 3 de mayo de 2013

Corrección de gamma. Tratamiento de imágenes. Parte XIII.

La corrección de gamma es la responsable de la sensación de contraste de una imagen, y decimos sensación porque no es algo inherente a la imagen, sino a los dispositivos que la registran, a los dispositivos que la reproducen y a la luminosidad del entorno donde la estamos viendo.
En esta entrada vamos a explicar cómo aplicar corrección de gamma a una imagen en sus 3 canales RGB. Lo primero que vamos a mostrar es la función que hace esta corrección, y realmente lo que crea es una rampa de tonos con los diferentes canales.


Public Function Gamma(ByVal bmp As Bitmap, ByVal ValorGammaRojo As Double, ByVal ValorGammaVerde As Double, ByVal ValorGammaAzul As Double)
    'Creamos un bitmap con el mismo tamaño que el bitmap recibido
    Dim bmp3 As New Bitmap(bmp.Width, bmp.Height)
    'Variables que almacenarán los colores modificados
    Dim rojo, verde, azul, alfa As Byte

    'Recorremos la matriz (imagen)
    For i = 0 To bmp.Width - 1
        For j = 0 To bmp.Height - 1
            'Cambiamos la gamma creando una rampa de contraste
            Rojo = CByte(Math.Min(255, CInt(Math.Truncate((255.0 * Math.Pow(bmp.GetPixel(i, j).R / 255.0, 1.0 / ValorGammaRojo)) + 0.5))))
            Verde = CByte(Math.Min(255, CInt(Math.Truncate((255.0 * Math.Pow(bmp.GetPixel(i, j).G / 255.0, 1.0 / ValorGammaVerde)) + 0.5))))
            Azul = CByte(Math.Min(255, CInt(Math.Truncate((255.0 * Math.Pow(bmp.GetPixel(i, j).B / 255.0, 1.0 / ValorGammaAzul)) + 0.5))))
            alfa = bmp.GetPixel(i, j).A
            'Asignamos a bmp los colores modificados
            bmp3.SetPixel(i, j, Color.FromArgb(alfa, rojo, verde, azul))
        Next
    Next
    Return bmp3
End Function

Como vemos, simplemente la función recibe los valores de corrección para cada canal RGB, y crea una escala para modificar la imagen. Cuando los valores son menores que 1, la imagen se hará más oscura, y en caso de ser mayores, la imagen se aclarará.
Ahora vamos a crear un formulario similar al que se muestra en la siguiente imagen:

Formulario corrección de gamma

Y por último añadimos el siguiente código fuente.

Dim bmpOriginal As Bitmap
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    'Establecemos la imagen del Picturebox como imagen original
    bmpOriginal = PictureBox1.Image
End Sub

'Botón para aplicar la corrección
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    PictureBox1.Image = Gamma(bmpOriginal, HSRojo.Value / 100, HSVerde.Value / 100, HSAzul.Value / 100)
End Sub

Sub ScrollsVinculados(ByVal valor As Integer)
    lblrojo.Text = valor / 100
    HSRojo.Value = valor
    lblverde.Text = valor / 100
    HSVerde.Value = valor
    lblazul.Text = valor / 100
    HSAzul.Value = valor
End Sub
Private Sub HSAzul_Scroll(sender As Object, e As ScrollEventArgs) Handles HSAzul.Scroll
    If chbVincular.Checked = True Then
       ScrollsVinculados(HSAzul.Value)
    Else
       lblazul.Text = HSAzul.Value / 100
    End If
End Sub
Private Sub HSVerde_Scroll(sender As Object, e As ScrollEventArgs) Handles HSVerde.Scroll
    If chbVincular.Checked = True Then
        ScrollsVinculados(HSVerde.Value)
    Else
        lblverde.Text = HSVerde.Value / 100
    End If
End Sub
Private Sub HSRojo_Scroll(sender As Object, e As ScrollEventArgs) Handles HSRojo.Scroll
    If chbVincular.Checked = True Then
        ScrollsVinculados(HSRojo.Value)
    Else
        lblrojo.Text = HSRojo.Value / 100
    End If
End Sub

Este código lo único que hace es crear en el load del formulario un bitmap que será pasado a la función (junto con los parámetros) en el evento clic del botón. Por último, la función ScrollsVinculados simplemente  hace que los tres scrolls (junto con los labels), tengan el mismo valor.
El resultado después de aplicar una corrección de gamma de 0.45 para los tres canales, sería.

Imagen con corrección de gamma

Más info aquí: http://ocw.usal.es/ensenanzas-tecnicas/herramientas-informaticas-para-el-geoprocesado
Descarga el código fuente:

1 comentario: