martes, 30 de abril de 2013

Modificar contraste. Tratamiento de imágenes. Parte XII.

En esta entrada vamos a ver una sencilla forma de modificar el contraste de una imagen, obteniendo muy buenos resultados. Al modificar el contraste de una imagen lo que se hace realmente es ensanchar o contraer el histograma de la imagen. Viendo un ejemplo se verá de forma más clara.

Histogramas


En la parte superior se muestra la imagen original con su correspondiente histograma, justo debajo la misma imagen después de haber aumentado el contraste, y por último se muestra la imagen después de haber disminuido el contraste. Como puede observarse, las diferencias en el histograma son claras, ya que cuando se aumenta el contraste, se estira el histograma abarcando más tonos de gris, en cambio cuando se disminuye, el histograma está más comprimido.
Ahora vamos a ver la función que modificará el contraste:

'Función que modifica el contraste de una imagen
Public Function Contraste(ByVal bmp As Bitmap, ByVal valorContraste As Double) As Bitmap
   'Creamos un bitmap con las dimensiones del bitmap recibido
   Dim bmpResultado As New Bitmap(bmp.Width, bmp.Height)

   Dim Rojo, Verde, Azul, alfa As Byte
   Dim Rojoaxu, Verdeaux, Azulaux As Double
   Dim calculo, calculoAux As Double
   'Con esto hacemos que si recibimos 0 (valorcontraste) no haya modificación en la imagen
   calculoAux = (1 / ((Math.PI) / 4))
   'Pi/4
   calculo = (valorContraste + 1) * (Math.PI / 4)
   calculo *= calculoAux

   For i = 0 To bmp.Width - 1  'Recorremos la matriz 
       For j = 0 To bmp.Height - 1
            'obtenemos el valor del píxel actual con GetPixel y le aplicamos la transformación
            Rojoaxu = ((bmp.GetPixel(i, j).R - 128) * calculo) + 128
            Verdeaux = ((bmp.GetPixel(i, j).G - 128) * calculo) + 128
            Azulaux = ((bmp.GetPixel(i, j).B - 128) * calculo) + 128

            'Eliminamos valores mayores de 255
            If Rojoaxu > 255 Then Rojoaxu = 255
            If Verdeaux > 255 Then Verdeaux = 255
            If Azulaux > 255 Then Azulaux = 255
            'Eliminamos valores menores de 0
            If Rojoaxu < 0 Then Rojoaxu = 0
            If Verdeaux < 0 Then Verdeaux = 0
            If Azulaux < 0 Then Azulaux = 0
            'ASignamos el resultado a las variables rojo, verde, azul
            Rojo = Rojoaxu
            Verde = Verdeaux
            Azul = Azulaux
            'El canal alfa no lo modificamos
            alfa = bmp.GetPixel(i, j).A
            'Almacenamos los valores obtenidos en un bitmap
            bmpResultado.SetPixel(i, j, Color.FromArgb(alfa, Rojo, Verde, Azul))
        Next
    Next
   
    'Devolvemos el bitmap transformado
    Return bmpResultado
End Function

La función como vemos es muy sencilla, ahora vamos a crear un formulario como el que se observa en la siguiente imagen.

Formulario para modificar contraste

Por último, vamos a mostrar el código fuente asociado al Load del formulario, al HScrollbar y al botón.

Dim bmp As Bitmap 'Variable que almacenará el contenido del Picturebox

'Carga incial del formulario
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    'Almacenamos como bitmap la imagen
    bmp = PictureBox1.Image
End Sub

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

'Modificar contraste
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'Asigamos al picturebox la imagen transformada
    'El valor del Hscrollbar se divide entre 100 para que esté entre -1 y 1
    PictureBox1.Image = Contraste(bmp, HSvalor.Value / 100)
End Sub

Todo el proceso es muy sencillo y los resultados a la hora de aumentar el contraste son bastante buenos. Podéis descargar la aplicación desde aquí:


Más info en http://ocw.usal.es/ensenanzas-tecnicas/herramientas-informaticas-para-el-geoprocesado

No hay comentarios:

Publicar un comentario