Então galera nesse tutorial vamos aprender a detectar os contornos de uma imagem usando um algoritimo bem simples, nesse tutorial vamos utilizar o python com o modulo PIL (pillow) embora possa ser feito em qualquer outra linguagem de sua preferencia ja que vamos fazer na mão. Para começar importamos o modulo pil (não vou abordar a instalação do mesmo)
podemos carregar a imagem usando o metodo open da classe Image (Image.open), podemos inclusive exibir ela com o metodo show
transformamos a imagem em preto e branco para ter apenas duas cores a ser manipulada, criamos um novo objeto de imagem com o metodo new com o mesmo tamanho da imagem atual para receber a imagem preto e branco, depois basta ler pixel a pixel da imagem original tirar uma media das 3 cores RGB e por comparar essa media com um valor (esse valor pode ser uma variavel ~ no caso chamei ela de nivel), caso a media seja maior a gente desenha um pixel branco e caso seja menor a gente desenha um pixel preto
as bordas são os limites de uma superficie no caso contorno dela, existe uma pequena diferença na sua coloração entre a borda e depois dela, sendo que é essa diferença que vamos utilizar para detectar elas. A logica em cima disso é bastante simples bastando ler a imagem preto e branco pixel a pixel, caso a imagem tenha o pixel preto a gente ignora, caso tenha o pixel branco a gente pinta um pixel na imagem (no caso uma imagem nova), se tiver outro pixel branco seguido do anterior a gente ignora ate o proximo pixel preto (para fazer isso usamos uma variavel para indicar se o pixel anterior é branco ou não, caso detecte o pixel branco setamos a variavel como verdadeiro e com isso não permitindo desenhar na imagem outro pixel branco, caso detecte um pixel preto ele atribui falso naquela variavel permitindo desenhar o proximo pixel branco e com isso ficando nesse loop)
se a gente tentar pegar as bordas de um quadrado de uma unica cor usando esse script vai gera apenas uma linha T.T
para uma precisão maior é necessario ler a imagem pixel a pixel da direita para a esquerda, depois da esquerda para direita, depois de cima para baixo e por fim de baixo para cima (não necessarimente nessa ordem), obs: esse mesmo codigo poderia ser melhorado de varias formas possiveis por exemplo usando apenas um loop para aumentar a performance
outro exemplo com a foto da mikan e como seria no exemplo anterior
outra coisa que a gente pode fazer é mexer naquela variavel nivel para tentar pegar alguns outros contornos mais escuros ou ignorar os mais escuros (isso pode variar de imagem para imagem), ex: em 240 pegamos apenas uma parte dos olhos da mikan ignorando todo o resto
bom galera é isso, ate o proximo tutorial sobre computação grafica \o
by kodo no kami
- Código:
#!/usr/bin/python3
from PIL import Image
podemos carregar a imagem usando o metodo open da classe Image (Image.open), podemos inclusive exibir ela com o metodo show
- Código:
#!/usr/bin/python3
from PIL import Image
img = Image.open("mikan.jpg")
img.show()
transformamos a imagem em preto e branco para ter apenas duas cores a ser manipulada, criamos um novo objeto de imagem com o metodo new com o mesmo tamanho da imagem atual para receber a imagem preto e branco, depois basta ler pixel a pixel da imagem original tirar uma media das 3 cores RGB e por comparar essa media com um valor (esse valor pode ser uma variavel ~ no caso chamei ela de nivel), caso a media seja maior a gente desenha um pixel branco e caso seja menor a gente desenha um pixel preto
- Código:
#!/usr/bin/python3
from PIL import Image
img = Image.open("mikan.jpg")
tam = img.size
imgMono = Image.new("RGB",tam)
nivel = 127
contx = 0
while contx < tam[0]:
conty = 0
while conty < tam[1]:
r, g, b = img.getpixel((contx, conty))
media = (r + g + b) // 3
if media > nivel:
imgMono.putpixel((contx, conty),(255,255,255))
else:
imgMono.putpixel((contx, conty),(0,0,0))
conty += 1
contx += 1
imgMono.show()
as bordas são os limites de uma superficie no caso contorno dela, existe uma pequena diferença na sua coloração entre a borda e depois dela, sendo que é essa diferença que vamos utilizar para detectar elas. A logica em cima disso é bastante simples bastando ler a imagem preto e branco pixel a pixel, caso a imagem tenha o pixel preto a gente ignora, caso tenha o pixel branco a gente pinta um pixel na imagem (no caso uma imagem nova), se tiver outro pixel branco seguido do anterior a gente ignora ate o proximo pixel preto (para fazer isso usamos uma variavel para indicar se o pixel anterior é branco ou não, caso detecte o pixel branco setamos a variavel como verdadeiro e com isso não permitindo desenhar na imagem outro pixel branco, caso detecte um pixel preto ele atribui falso naquela variavel permitindo desenhar o proximo pixel branco e com isso ficando nesse loop)
- Código:
#!/usr/bin/python3
from PIL import Image
img = Image.open("mikan.jpg")
tam = img.size
imgMono = Image.new("RGB",tam)
imgBorda = Image.new("RGB",tam)
nivel = 127
contx = 0
while contx < tam[0]:
conty = 0
while conty < tam[1]:
r, g, b = img.getpixel((contx, conty))
media = (r + g + b) // 3
if media > nivel:
imgMono.putpixel((contx, conty),(255,255,255))
else:
imgMono.putpixel((contx, conty),(0,0,0))
conty += 1
contx += 1
contx = 0
desenhado = False
while contx < tam[0]:
conty = 0
while conty < tam[1]:
r, g, b = imgMono.getpixel((contx, conty))
if (desenhado == False) and (r == 255):
imgBorda.putpixel((contx, conty),(255,255,255))
desenhado = True
else:
if r == 0:
desenhado = False
conty += 1
contx += 1
imgBorda.show()
se a gente tentar pegar as bordas de um quadrado de uma unica cor usando esse script vai gera apenas uma linha T.T
para uma precisão maior é necessario ler a imagem pixel a pixel da direita para a esquerda, depois da esquerda para direita, depois de cima para baixo e por fim de baixo para cima (não necessarimente nessa ordem), obs: esse mesmo codigo poderia ser melhorado de varias formas possiveis por exemplo usando apenas um loop para aumentar a performance
- Código:
#!/usr/bin/python3
from PIL import Image
img = Image.open("quadrado.jpg")
tam = img.size
imgMono = Image.new("RGB",tam)
imgBorda = Image.new("RGB",tam)
nivel = 127
contx = 0
while contx < tam[0]:
conty = 0
while conty < tam[1]:
r, g, b = img.getpixel((contx, conty))
media = (r + g + b) // 3
if media > nivel:
imgMono.putpixel((contx, conty),(255,255,255))
else:
imgMono.putpixel((contx, conty),(0,0,0))
conty += 1
contx += 1
contx = 0
desenhado = False
while contx < tam[0]:
conty = 0
while conty < tam[1]:
r, g, b = imgMono.getpixel((contx, conty))
if (desenhado == False) and (r == 255):
imgBorda.putpixel((contx, conty),(255,255,255))
desenhado = True
else:
if r == 0:
desenhado = False
conty += 1
contx += 1
conty = 0
desenhado = False
while conty < tam[1]:
contx = 0
while contx < tam[0]:
r, g, b = imgMono.getpixel((contx, conty))
if (desenhado == False) and (r == 255):
imgBorda.putpixel((contx, conty),(255,255,255))
desenhado = True
else:
if r == 0:
desenhado = False
contx += 1
conty += 1
contx = tam[0] -1
desenhado = False
while contx >= 0:
conty = tam[1] -1
while conty >= 0:
r, g, b = imgMono.getpixel((contx, conty))
if (desenhado == False) and (r == 255):
imgBorda.putpixel((contx, conty),(255,255,255))
desenhado = True
else:
if r == 0:
desenhado = False
conty -= 1
contx -= 1
conty = tam[1] -1
desenhado = False
while conty >= 0:
contx = tam[0] -1
while contx >= 0:
r, g, b = imgMono.getpixel((contx, conty))
if (desenhado == False) and (r == 255):
imgBorda.putpixel((contx, conty),(255,255,255))
desenhado = True
else:
if r == 0:
desenhado = False
contx -= 1
conty -= 1
img.show()
imgBorda.show()
outro exemplo com a foto da mikan e como seria no exemplo anterior
outra coisa que a gente pode fazer é mexer naquela variavel nivel para tentar pegar alguns outros contornos mais escuros ou ignorar os mais escuros (isso pode variar de imagem para imagem), ex: em 240 pegamos apenas uma parte dos olhos da mikan ignorando todo o resto
- Código:
nivel = 240
bom galera é isso, ate o proximo tutorial sobre computação grafica \o
by kodo no kami