martes, 3 de abril de 2012

Tratamiento de imágenes (Parte III)

Tras haber realizado la carga y algunas modificaciones sobre la imagen, continuamos con la modificación de los valores de los píxeles. Para ello, abrimos el trabajo (si quieres, puedes descargar su código fuente aquí), y seguimos.
Lo que vamos a desarrollar son máscaras, es decir, a partir de un valor de un píxel lo comparamos con sus vecinos. En este caso, la matriz será de 3x3, es decir, para un píxel dado, comparamos los valores de sus vecinos más próximos (los que rodean al píxel) y, asignando un determinado peso a ellos y al propio píxel, calculamos el nuevo valor de nuestro píxel. Para ello, creamos un nuevo campo en nuestra barra superior de herramientas que se llame, máscaras, y debajo una máscara denominada repujado:



Antes que nada, creamos en la parte superior del código, una variable que almacenará los valores de la matriz:
Public mascara(,) As Integer 'Matriz que almacena los valores de la máscara

Hacemos doble clic e insertamos el siguiente código:
        Dim i, j As Long
        Dim mi, mj As Long
        Dim SumaRojo, SumaMascara As Long
        Dim Rojo As Integer
        Dim bmp As New Bitmap(Niveles.GetUpperBound(0) + 1, Niveles.GetUpperBound(1) + 1)
        Dim img As Image
        img = CType(bmp, Image)
        PictureBox1.Image = img
        Panel1.AutoScrollMinSize = PictureBox1.Image.Size
        PictureBox1.Refresh()
        ReDim mascara(2, 2) 'Redimensionamos la máscara y asignamos los valores
        mascara(0, 0) = -2 : mascara(0, 1) = -1 : mascara(0, 2) = 0
        mascara(1, 0) = -1 : mascara(1, 1) = 1 : mascara(1, 2) = 1
        mascara(2, 0) = 0 : mascara(2, 1) = 1 : mascara(2, 2) = 2
        For mi = -1 To 1 'Con este bucle recorremos los valores de la máscara
            For mj = -1 To 1
                SumaMascara = SumaMascara + mascara(mi + 1, mj + 1)
            Next
        Next
        If SumaMascara = 0 Then SumaMascara = 1 'Hemos calculado el valor de la máscara en la variable SumaMascara, si fuese 0 lo igualamos a 1 para que no haya divisiones entre 0
        
        'Con este cuadruple bucle se recorre la máscara y la matriz 
        For i = 1 To Niveles.GetUpperBound(0) - 1
            For j = 1 To Niveles.GetUpperBound(1) - 1
                SumaRojo = 0
                For mi = -1 To 1
                    For mj = -1 To 1
                        'Calculamos y vamos acumulando el valor de los píxeles con su respectivo peso
                        SumaRojo = SumaRojo + Niveles(i + mi, j + mj).R * mascara(mi + 1, mj + 1)
                    Next
                Next
              
                Rojo = Math.Abs(SumaRojo / SumaMascara) 'Dividimos el valor acumulado entre la suma de los pesos de la máscara
                If Rojo > 255 Then Rojo = 255 'Para que no haya problemas si hay valores superiores a 255 los igualamos a 255
                bmp.SetPixel(i, j, Color.FromArgb(Rojo, Rojo, Rojo)) 'Dibujamos
            Next
            img = CType(bmp, Image)
            PictureBox1.Image = img
            PictureBox1.Refresh()  'Para que se vaya refrescando línea a línea

Compilamos y ejecutamos y el resultado es el siguiente:



Como se ha podido observar es un código muy simple en el que se recorre, para cada píxel, la máscara acumulando los valores de los pesos de sus vecinos y de él mismo. En este caso sólo se ha utilizado el color rojo, pero con un procedimiento similar, se pueden ir calculando para cada píxel el valor de cada componente (RGB), y luego asignarla al píxel.
Puedes descargar el código fuente aquí.

No hay comentarios:

Publicar un comentario