1) Subrutina para aplicar una máscara de convolución discreta, de
preferencia centralizado al pixel en cuestión.
2) Con esa subrutina,
calcular por lo menos un gradiente horizontal y un gradiente vertical,
posiblemente más o también diagonales, con la posibilidad de combinarlos
al tiempo de calcularlos a uno solo o combinando entre múltiples
matrices de gradiente una vez terminada la aplicación de todas las
máscaras de gradiente:
3) Normalización de la matriz resultante de la
manera que perciben factible y útil a [0, 255]
4)Binarización que deje los bordes como zonas blancas y el resto negro.
La imagen que utilice para estas pruebas fue esta.
Para realizar esta primera tarea utilice dos máscaras.
Estas máscaras presentan una ventaja en cuanto a las demás como la de Robert, es que además de estimar el valor del módulo del gradiente, producen un
alisamiento en la imagen que resulta beneficioso.
1.- Mascara Sobel.- Que utiliza esta matriz para sus operaciones
2- Mascara Prewitt, Esta mascara utiliza esta matriz de 3 x 3 para sus operaciones.
Ya una vez sabiendo lo teórico, se procede a implementar la convolución. Aquí utilice la imagen en escala de grises y filtrada de la entrada de laboratorio.
Aquí se encuentra el código que hace esto.
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
#IMAGEN BORROSA | |
image = Image.open("linea.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
numero=raw_input("Teclea el numero de filtro que quieres ") | |
numerofiltro=int(numero) | |
for z in range(numerofiltro): | |
for x in range(ancho): | |
for y in range(altura): | |
contador = 1 | |
promedio = 0 | |
(r,g,b) = pixeles[ x, y ] | |
promedio += ( r + g + b ) / 3 | |
try : | |
if x - 1 < 0: | |
None | |
else: | |
r1, g1, b1 = pixeles[ ( x - 1 ), y ] | |
promedio += ( r1 + g1 + b1 ) / 3 | |
contador = contador + 1 | |
except: | |
pass | |
try : | |
if x + 1 >= ancho: | |
None | |
else: | |
r2, g2, b2 = pixeles[ ( x + 1 ), y ] | |
promedio += ( r2 + g2 + b2 ) / 3 | |
contador = contador + 1 | |
except: | |
pass | |
try: | |
if y - 1 < 0: | |
None | |
else: | |
r3, g3, b3 = pixeles[ x, ( y - 1 ) ] | |
promedio += ( r3 + g3 + b3 ) / 3 | |
contador = contador + 1 | |
except: | |
pass | |
try: | |
if y + 1 >= altura: | |
None | |
else: | |
r4, g4, b4 = pixeles[ x, ( y + 1 ) ] | |
promedio += ( r4 + g4 + b4 ) / 3 | |
contador = contador + 1 | |
except: | |
pass | |
promedio /= contador | |
pixeles[ x, y ] = ( promedio, promedio, promedio ) | |
image.show() |
Ahora se procederá a implementar las mascaras , y con esto obtendremos los bordes de la imagen.
Como se mencionó existen distintos métodos yo utilice Prewitt y Sobel.
Aquí está el código , y se carga la matriz Sobel y Prewitt con sus valores respectivos.
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
import pygame | |
from pygame.locals import * | |
import Image | |
import math | |
pygame.init() | |
pantalla = pygame.display.set_mode((190,250)) | |
# FOTO NORMAL | |
imagen = pygame.image.load("linea.jpg") | |
#CONVOLUCION A ESCALA DE GRISES Y FILTRADA | |
image = Image.open("convol.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
msobelX = ([-1, 0, 1], [-2, 0, 2], [-1, 0, 1]) #Para gradiente de x. | |
msobelY = ([1, 2, 1], [0, 0, 0], [-1, -2, -1]) #Para gradiente de y. | |
prewittX=([-1, 0, 1], [-1, 0, 1], [-1, 0, 1])#EJE X PREWITT | |
prewittY=([1, 1, 1], [0, 0, 0], [-1,-1,-1])#EJE Y PREWITT | |
tamanomatriz=3 | |
sumatoriaX = 0 | |
sumariaY = 0 | |
seleccion=raw_input("INGRESA 1 PARA SOBEL y DOS PARA PREWITT ") | |
matrizagarrada=int(seleccion) | |
if matrizagarrada==1: | |
for x in range(altura): | |
for y in range(ancho): | |
sumatoriaX = 0 | |
sumatoriaY = 0 | |
for i in range(tamanomatriz): | |
for j in range(tamanomatriz): | |
try: | |
gx = msobelX[i][j]*pixeles[y+j, x+i][1] | |
gy = msobelY[i][j]*pixeles[y+j, x+i][1] | |
except: | |
productosGX = 0 | |
productosGY = 0 | |
sumatoriaX = gx+sumatoriaX | |
sumatoriaY = gy+sumatoriaY | |
gxalcuadrado = pow(sumatoriaX, 2) | |
gyalcuadrado = pow(sumatoriaY, 2) | |
gradienteResultante = int(math.sqrt(gxalcuadrado+gyalcuadrado)) | |
pixelNuevo=gradienteResultante | |
if pixelNuevo> 255: | |
pixelNuevo = 255 | |
if pixelNuevo < 0: | |
pixelNuevo = 0 | |
pixeles[y,x] = ( pixelNuevo, pixelNuevo, pixelNuevo) | |
image.show() | |
if matrizagarrada==2: | |
for x in range(altura): | |
for y in range(ancho): | |
sumatoriaX = 0 | |
sumatoriaY = 0 | |
for i in range(tamanomatriz): | |
for j in range(tamanomatriz): | |
try: | |
gx = prewittX[i][j]*pixeles[y+j, x+i][1] | |
gy = prewittY[i][j]*pixeles[y+j, x+i][1] | |
except: | |
productosGX = 0 | |
productosGY = 0 | |
sumatoriaX = gx+sumatoriaX | |
sumatoriaY = gy+sumatoriaY | |
gxalcuadrado = pow(sumatoriaX, 2) | |
gyalcuadrado = pow(sumatoriaY, 2) | |
gradienteResultante = int(math.sqrt(gxalcuadrado+gyalcuadrado)) | |
pixelNuevo=gradienteResultante | |
if pixelNuevo> 255: | |
pixelNuevo = 255 | |
if pixelNuevo < 0: | |
pixelNuevo = 0 | |
pixeles[y,x] = ( pixelNuevo, pixelNuevo, pixelNuevo) | |
image.show() | |
while True: | |
for eventos in pygame.event.get(): | |
if eventos.type == pygame.QUIT: | |
exit() | |
pantalla.blit(imagen,(0,0)) | |
pygame.display.update() | |
msobelX = ([-1, 0, 1], [-2, 0, 2], [-1, 0, 1])
msobelY = ([1, 2, 1], [0, 0, 0], [-1, -2, -1])
prewittX=([-1, 0, 1], [-1, 0, 1], [-1, 0, 1])
prewittY=([1, 1, 1], [0, 0, 0], [-1,-1,-1])
Se pide que ingreses un "UNO" para trabajar con la matriz Sobel y un "DOS" para trabajar con la matriz prewitt.
Aquí están las distintas pruebas que realice.
4760862 Mascara sobel.
Imagen original Imagen con Mascara
Imagen Original Imagen con máscara

Mascara Prewitt
Imagen original Imagen con máscara


Y aquí todo el código
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
import pygame | |
from pygame.locals import * | |
import Image | |
import math | |
pygame.init() | |
pantalla = pygame.display.set_mode((190,250)) | |
# FOTO NORMAL | |
imagen = pygame.image.load("imagen.jpg") | |
#FOTO ESCALA DE GRISES | |
image = Image.open("imagen.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
for x in range(ancho): | |
for y in range(altura): | |
(r,g,b) = image.getpixel((x,y)) | |
promedio=((r+g+b)/3) | |
pixeles[x,y] = (promedio,promedio,promedio) | |
#image.show() | |
#FOTO Invertida | |
image = Image.open("imagen.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
for x in range(ancho): | |
for y in range(altura): | |
(r,g,b) = image.getpixel((x,y)) | |
if (r>0 and g>0 and b>0): | |
r=255-r | |
g=255-g | |
b=255-b | |
pixeles[x,y] = (r,g,b) | |
#image.show() | |
#FOTO binarizada con un umbral | |
image = Image.open("imagen.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
for x in range(ancho): | |
for y in range(altura): | |
(r,g,b) = image.getpixel((x,y)) | |
if (r<128 and g<128 and b<128): | |
r=0 | |
g=0 | |
b=0 | |
if (r>128 and g>128 and b>128): | |
r=255 | |
g=255 | |
b=255 | |
pixeles[x,y] = (r,g,b) | |
#image.show() | |
#FOTO Escala de grises con binarizacion | |
image = Image.open("imagen.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
for x in range(ancho): | |
for y in range(altura): | |
(r,g,b) = image.getpixel((x,y)) | |
promedio=((r+g+b)/3) | |
if (promedio<=128 and promedio<=128 and promedio<=128): | |
r=0 | |
g=0 | |
b=0 | |
else: | |
r=255 | |
g=255 | |
b=255 | |
pixeles[x,y] = (r,g,b) | |
#image.show() | |
#FOTO binarizada con dos UMBRALes | |
image = Image.open("imagen.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
for x in range(ancho): | |
for y in range(altura): | |
(r,g,b) = image.getpixel((x,y)) | |
promedio = (r+g+b/3) | |
if promedio <= 100: | |
r=0 | |
g=0 | |
b=0 | |
if promedio >= 220: | |
r=255 | |
g=255 | |
b=255 | |
pixeles[x,y] = (promedio,promedio,promedio) | |
#image.show() | |
#FOTO PLATEADAS | |
image = Image.open("imagen.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
for x in range(ancho): | |
for y in range(altura): | |
(r,g,b) = image.getpixel((x,y)) | |
promedio =((r-80)+(g-80)+(b-80)/3) | |
pixeles[x,y] = (promedio,promedio,promedio) | |
#image.show() | |
#IMAGEN BORROSA | |
image = Image.open("linea.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
numero=raw_input("Teclea el numero de filtro que quieres ") | |
numerofiltro=int(numero) | |
for z in range(numerofiltro): | |
for x in range(ancho): | |
for y in range(altura): | |
contador = 1 | |
promedio = 0 | |
(r,g,b) = pixeles[ x, y ] | |
promedio += ( r + g + b ) / 3 | |
try : | |
if x - 1 < 0: | |
None | |
else: | |
r1, g1, b1 = pixeles[ ( x - 1 ), y ] | |
promedio += ( r1 + g1 + b1 ) / 3 | |
contador = contador + 1 | |
except: | |
pass | |
try : | |
if x + 1 >= ancho: | |
None | |
else: | |
r2, g2, b2 = pixeles[ ( x + 1 ), y ] | |
promedio += ( r2 + g2 + b2 ) / 3 | |
contador = contador + 1 | |
except: | |
pass | |
try: | |
if y - 1 < 0: | |
None | |
else: | |
r3, g3, b3 = pixeles[ x, ( y - 1 ) ] | |
promedio += ( r3 + g3 + b3 ) / 3 | |
contador = contador + 1 | |
except: | |
pass | |
try: | |
if y + 1 >= altura: | |
None | |
else: | |
r4, g4, b4 = pixeles[ x, ( y + 1 ) ] | |
promedio += ( r4 + g4 + b4 ) / 3 | |
contador = contador + 1 | |
except: | |
pass | |
promedio /= contador | |
pixeles[ x, y ] = ( promedio, promedio, promedio ) | |
image.show() | |
#CONVOLUCION A ESCALA DE GRISES Y FILTRADA | |
image = Image.open("perrito.jpg") | |
pixeles = image.load() | |
ancho, altura =image.size | |
msobelX = ([-1, 0, 1], [-2, 0, 2], [-1, 0, 1]) #Para gradiente de x. | |
msobelY = ([1, 2, 1], [0, 0, 0], [-1, -2, -1]) #Para gradiente de y. | |
prewittX=([-1, 0, 1], [-1, 0, 1], [-1, 0, 1])#EJE X PREWITT | |
prewittY=([1, 1, 1], [0, 0, 0], [-1,-1,-1])#EJE Y PREWITT | |
tamanomatriz=3 | |
sumatoriaX = 0 | |
sumariaY = 0 | |
seleccion=raw_input("INGRESA 1 PARA SOBEL y DOS PARA PREWITT ") | |
matrizagarrada=int(seleccion) | |
if matrizagarrada==1: | |
for x in range(altura): | |
for y in range(ancho): | |
sumatoriaX = 0 | |
sumatoriaY = 0 | |
for i in range(tamanomatriz): | |
for j in range(tamanomatriz): | |
try: | |
gx = msobelX[i][j]*pixeles[y+j, x+i][1] | |
gy = msobelY[i][j]*pixeles[y+j, x+i][1] | |
except: | |
productosGX = 0 | |
productosGY = 0 | |
sumatoriaX = gx+sumatoriaX | |
sumatoriaY = gy+sumatoriaY | |
gxalcuadrado = pow(sumatoriaX, 2) | |
gyalcuadrado = pow(sumatoriaY, 2) | |
gradienteResultante = int(math.sqrt(gxalcuadrado+gyalcuadrado)) | |
pixelNuevo=gradienteResultante | |
if pixelNuevo> 255: | |
pixelNuevo = 255 | |
if pixelNuevo < 0: | |
pixelNuevo = 0 | |
pixeles[y,x] = ( pixelNuevo, pixelNuevo, pixelNuevo) | |
image.show() | |
if matrizagarrada==2: | |
for x in range(altura): | |
for y in range(ancho): | |
sumatoriaX = 0 | |
sumatoriaY = 0 | |
for i in range(tamanomatriz): | |
for j in range(tamanomatriz): | |
try: | |
gx = prewittX[i][j]*pixeles[y+j, x+i][1] | |
gy = prewittY[i][j]*pixeles[y+j, x+i][1] | |
except: | |
productosGX = 0 | |
productosGY = 0 | |
sumatoriaX = gx+sumatoriaX | |
sumatoriaY = gy+sumatoriaY | |
gxalcuadrado = pow(sumatoriaX, 2) | |
gyalcuadrado = pow(sumatoriaY, 2) | |
gradienteResultante = int(math.sqrt(gxalcuadrado+gyalcuadrado)) | |
pixelNuevo=gradienteResultante | |
if pixelNuevo> 255: | |
pixelNuevo = 255 | |
if pixelNuevo < 0: | |
pixelNuevo = 0 | |
pixeles[y,x] = ( pixelNuevo, pixelNuevo, pixelNuevo) | |
image.show() | |
while True: | |
for eventos in pygame.event.get(): | |
if eventos.type == pygame.QUIT: | |
exit() | |
pantalla.blit(imagen,(0,0)) | |
pygame.display.update() | |
Aquí esta el link a el codigo.
https://gist.github.com/robertovalenzuela91/4760862
Cierta debilidad en los acentos y tampoco mediste los tiempos, pero va el mismo trato que con Osvaldo. 5 pts ahora, pero ya no aguanto mucho más la omisión aleatoria de acentos de palabras.
ResponderEliminar