Si no sabemos que es el gradiente, podemos explicarlo decir que es un vector, donde nos muestra la dirección en la que un determinado punto crece más rápido.
Aplicado
Para poder detectar los bordes de una imagen ocupamos la combinación de tres cosas: imagen a escala de grises + cualquier filtro en la imagen + máscara(puede ser Sobel, Prewitt ó alguna otra). En mi caso el tipo de Filtro que apliqué en la imagen es la de Blur y utilicé ambas máscaras.
Sobel
Esta máscara es de un tamaño de 3x3, donde tendremos dos matrices una aplicada en Gx y otra en Gy (primera imagen), para después combinarlos y tener la magnitud del gradiente (segunda imagen).
[http://es.wikipedia.org/wiki/Operador_Sobel]
Prewitt
Al igual que Sobel es una máscara de 3x3, donde se tienen dos matrices una aplicada en Gx y otra en Gy (primera imagen), para después combinarlas y tener su gradiente (segunda imagen).
[http://en.wikipedia.org/wiki/Prewitt_operator]
Código
A continuación les dejo el código con una breve explicación donde menciona las fórmulas empleadas mencionadas anteriormente, al igual dejo la liga de mi git.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def convolucion(self, typeMask): | |
w, h = self.img.size | |
self.pixel = self.img.load() | |
if(typeMask == 1 or typeMask == None): #Escogemos el tipo de Mascara a aplicar ya sea Sobel en x & y o Prewitt en x & y | |
MascaraX, MascaraY = ([-1, 0, 1], [-2, 0, 2], [-1, 0, 1]), ([1, 2, 1], [0, 0, 0], [-1, -2, -1]) # Sobel | |
nameImage = 'borderSobel.png' | |
else: | |
MascaraX, MascaraY = ([-1, 0, 1], [-1, 0, 1], [-1, 0, 1]), ([1, 1, 1], [0, 0, 0], [-1, -1, -1]) #Prewitt | |
nameImage = 'borderPrewittBlur.png' | |
for i in range(w): | |
for j in range(h): | |
gX = self.matrixMult(i, j, MascaraX) #Hacemos la multiplicacion de la matrix en x escogida por el pixel seleccionado | |
gY = self.matrixMult(i, j, MascaraY) #Hacemos la multiplicacion de la matrix en y escogida por el pixel seleccionado | |
g = int(math.sqrt(gX + gY)) #Aplicamos la formula para obtener el gradiente | |
self.pixel[i,j] = (g, g, g) #nuevo Pixel creado | |
self.img.save(nameImage) | |
def matrixMult(self, x, y, matrix): #Funcion donde hacemos la multiplicacion de matrices | |
suma = 0 | |
for i in range(len(matrix)): | |
for j in range(len(matrix)): | |
try: | |
suma += matrix[i][j]*self.pixel[x+i, y+j][0] #Vamos sumando el resultado de la multiplicacion de la mascara seleccionada a nuestro pixel actual | |
except: | |
suma += 0 #Sumamos 0 en dado caso que nos salgamos de la posicion | |
return pow(suma, 2) #Aplicamos formula, al regresar la potencia de la matriz obtenida |
Resultados
Con los resultados obtenidos, podemos decir que aplicando la mascara de Sobel o Prewitt, no se tiene mucha diferencia en la imagen, más que la imagen un poco más opaca que la otra.
[imagen original]
[imagen escala de grises]
[imagen filtro blur 5 iteraciones]
[imagen Sobel]
[imagen Prewitt]
Jugando un Poco
Jugando un poco con las imagenes y que otros resultados podemos tener, ya sea aplicando el gradiente en x, y o al igual si se toma la imagen sin el filtro. Podemos decir que en x podemos observar los bordes que se tienen en horizontal y en y los que tenemos en vertical.
[gradiente en X]
[gradiente en Y]
[sin filtro Sobel]
[sin filtro Prewitt]
Referencias
http://es.wikipedia.org/wiki/Operador_Sobel
http://en.wikipedia.org/wiki/Prewitt_operator
http://www.songho.ca/dsp/convolution/convolution2d_example.html
http://docs.gimp.org/es/plug-in-convmatrix.html
Bien; 5.
ResponderEliminar