Após recebida a imagem, operação realizada com o auxílio da biblioteca OpenCv (cv2), é preciso realizar a normalização da mesma para se adequar ao formato binário.
img = cv2.imread("img.png",0)
img[img > 50] = 1
img[img <> 1] = 0
Utilizou-se o limiar 50 para o caso de serem inseridas imagens em tons de cinza em que tons mais baixos que a metade dos níveis ainda podem ser um objeto.
Considerou-se a abordagem de vizinhança do objeto como 4-conexo. Desse modo, para verificar os pixels pertencentes à um objeto é preciso partir do atual e verificar 4 pixels ao seu redor.
Para melhor visualização dos resultados, não contou-se os elementos apenas, mas criou-se uma matriz de mesmo tamanho da original em que o fundo possui valor zero e cada elemento é preenchido com um valor diferente. Assim, caso a entrada seja:
[[0 0 1 0 0 0 0 0 0 0]
[0 1 1 0 1 0 0 0 0 0]
[0 1 1 1 1 0 0 0 0 0]
[0 0 1 1 0 0 0 0 0 0]
[0 0 0 0 1 1 1 1 0 0]
[0 0 0 0 1 0 0 1 0 0]
[0 1 1 0 1 0 0 1 0 0]
[0 1 1 0 1 0 0 1 0 0]
[0 0 0 0 1 1 1 1 0 0]
[0 0 1 0 0 0 0 0 0 0]]
Será obtida a saída:
4
[[0 0 1 0 0 0 0 0 0 0]
[0 1 1 0 1 0 0 0 0 0]
[0 1 1 1 1 0 0 0 0 0]
[0 0 1 1 0 0 0 0 0 0]
[0 0 0 0 2 2 2 2 0 0]
[0 0 0 0 2 0 0 2 0 0]
[0 3 3 0 2 0 0 2 0 0]
[0 3 3 0 2 0 0 2 0 0]
[0 0 0 0 2 2 2 2 0 0]
[0 0 4 0 0 0 0 0 0 0]]
Para construção do objeto implementou-se uma fila em que seriam inseridos os possíveis pixels contidos no mesmo objeto a partir do pixel atual. A cada pixel analisado, sua posição na matriz original é setada como "-1", identificando que esse pixel não poderá ser utilizado novamente.
Em busca de reduzir o processamento, não analisaram-se todos os pixels da imagem inicial, mas apenas os que fazem parte de algum objeto. Isso é possível com a utilização da função "nonzero()", que retorna dois vetores com as posições das linhas e colunas, respectivamente, em que existem valores diferentes de zero. Nesse caso, todos os valores que não são zeros são uns, e representam os objetos.
Segue o código completo utilizado:
import numpy as np
import cv2
def contaElementos(img):
l,c = np.shape(img)
count = 0
fila = []
m = np.zeros((l,c))
(linha,coluna) = img.nonzero()
tam = len(linha)
for i in range(tam):
e = [linha[i],coluna[i]]
if img[e[0]][e[1]] == 1:
fila.append(e)
count+=1;
while len(fila) <> 0:
[i0,i1] = fila.pop(0)
if img[i0][i1] == 1:
img[i0][i1] = -1
m[i0][i1] = count
if i0 > 0 and fila.count([i0-1,i1]) == 0 and img[i0-1][i1] <> -1:
fila.append([i0-1,i1])
if i1 > 0 and fila.count([i0,i1-1]) == 0 and img[i0][i1-1] <> -1:
fila.append([i0,i1-1])
if i0 < l-1 and fila.count([i0+1,i1]) == 0 and img[i0+1][i1] <> -1:
fila.append([i0+1,i1])
if i1 < c-1 and fila.count([i0,i1+1]) == 0 and img[i0][i1+1] <> -1:
fila.append([i0,i1+1])
img[linha[i]][coluna[i]] = -1
return count,np.uint8(m)
img = cv2.imread("img.png",0)
img[img > 50] = 1
img[img <> 1] = 0
contaElementos(img)
0 comentários:
Postar um comentário