Atividades da semana 6 | Gustavo (gustavopinheiro) | Atividades

activity_gustavopinheiro_6_3 - Rascunho para implementar tie-zone watershed por marcadores

Nesta atividade você deve programar utilizando varredura sequencial de pixels. Veja a página construída em aula e aprimorada:

Lá estão descritas as duas principais técnicas sugeridas para a implementação:

  • fila hierárquica
  • endereçamento do pixel e seus vizinhos

Leia a teoria associada ao watershed por tie-zone e veja o algoritmo

  • Lotufo, Falcão - The ordered queue and the optimality of the watershed approaches. Citeseer
  • Audigier, Lotufo - The tie-zone watershed: Definition, algorithm and applications. Citeseer

A diferença entre watershed clássico sem marcadores do watershed com marcadores é que no watershed clássimo, os marcadores iniciais são dados pelos mínimos regionais da imagem. Assim, o watershed por marcadores é mais simples, pois os marcadores não precisam ser calculados, pois eles são fornecidos diretamente.

Veja as implementações já existentes

Use o espaço abaixo para fazer a sua implementação:

 1 import numpy as np
 2 import ia636 as ia
 3 import ia870 as MT
 4 import aula11_ws as ws
 5 from result_6_twsm import tester
 6 
 7 #Bc = np.array([[0, 1, 0],
 8 #               [1, 1, 1],
 9 #               [0, 1, 0]])
10 
11 #f = adreadgray('astablet.tif')
12 #f = 255-adreadgray('n2538.tif')
13 f,m,Bc = tester.get_input(1)
14 
15 adshow(f)
16 adshow(m)
17 grad = MT.iagradm(f)
18 adshow(grad)
19 gf = MT.iaareaclose(grad,100)
20 adshow(ia.ianormalize(gf))
21 #wt = MT.iatz(gf, Bc)
22 wt = MT.iatz(grad, Bc)
23 adshow(ia.ianormalize(wt))
24 
25 #ws = MT.iacwatershed(f,m,Bc,'REGIONS')

Use o espaço abaixo para fazer a sua implementação:

1 gf = MT.iaareaclose(grad,100)
2 #wt = MT.iatz(gf, MT.iasebox())
3 wt = MT.iatz(f, MT.iasebox())
4 adshow(gf, 'filtered gradient')
5 adshow(MT.iaglblshow(wt),'tiezone watershed')

filtered gradient

tiezone watershed

Use o espaço abaixo para fazer a sua implementação:

  1 import Queue
  2 class wsHeapQueue():
  3     """ Priority queue class for abstracting list methods with FIFO policy """
  4 
  5     def __init__(self):
  6         self.queue = dict()
  7 
  8     def push(self, a, c):
  9         """ Pushes an element to the queue """
 10         if self.queue.has_key(c):
 11             self.queue[c].append(a)
 12         else:
 13             self.queue[c] = [a]
 14 
 15     def pop(self):
 16         """ Pops the first element of the queue """
 17         key = min(self.queue.keys())
 18         element = self.queue[key].pop(0)
 19         if len(self.queue[key]) == 0:
 20             self.queue.pop(key)
 21         return element
 22 
 23     def empty(self):
 24         """ Returns whether the queue is empty or not """
 25         return len(self.queue) == 0
 26 
 27 
 28 def se2off(Bc):
 29     '''Converts structuring element to list of neighbor offsets in graph image'''
 30     h,w = Bc.shape
 31     hc,wc = h/2,w/2
 32     B = Bc.copy()
 33     B[hc,wc] = 0  # remove origin
 34     off = np.transpose(B.nonzero()) - np.array([hc,wc])
 35     return off  # 2 columns x n. of neighbors rows
 36 
 37 def N(fs,off):
 38     '''Precompute array of neighbors. Optimized by broadcast.
 39 
 40     fs - image shape
 41     off - offset matrix, 2 columns (dh,dw) x n. of neighbors
 42     '''
 43     H,W = fs
 44     n = H*W
 45     hi = np.arange(H).reshape(-1,1)
 46     wi = np.arange(W).reshape(1,-1)
 47     hoff = off[:,0]
 48     woff = off[:,1]
 49     h = hi + hoff.reshape(-1,1,1)
 50     w = wi + woff.reshape(-1,1,1)
 51     h[(h<0) | (h>=H)] = n
 52     w[(w<0) | (w>=W)] = n
 53     Nid = np.clip(h * W + w,0,n)
 54     return Nid.reshape(len(off),-1).transpose()
 55 
 56 
 57 
 58 
 59 
 60 def twsm(f,m,Bc):
 61 
 62     fshape = f.shape
 63     fsize = size(f)
 64     img = f.ravel()
 65     mr = m.ravel()
 66 
 67     done = np.empty(fsize)
 68     done[:] = False
 69 
 70     c1 = np.empty(fsize)
 71     c1[:] = np.inf
 72     c2 = np.zeros(fsize)
 73     lab = np.empty(fsize)
 74     lab[:] = fsize
 75 
 76     queue = wsHeapQueue()
 77     nl = N(fshape,se2off(Bc))
 78 
 79     nz = np.nonzero(m)[0]
 80     for i in nz:
 81         c1[i] = img[i]
 82         lab[i] = mr[i]
 83         #par[p] = p
 84         queue.push(i, img[i])
 85 
 86     while not queue.empty():
 87         p = queue.pop()
 88         done[p] = True
 89         for q in nl[p]:
 90             if q<fsize:
 91                 if done[q]:
 92                     continue
 93             print('q = ',q)
 94             print('q = ',img[q])
 95             c = max(c1[p], img[q])
 96             if c < c1[q]:
 97                 if c1[q] < np.inf:
 98                     if queue.contains(q, c1[q]):
 99                         queue.remove(q, c1[q])
100                 c1[q] = c
101                 lab[q] = lab[p]
102                 par[q] = p
103                 queue.push(q, c1[q])
104                 if c == c1[p]:
105                     c2[q] = c2[p] + 1
106             elif c == c1[q] and lab[q] != lab[p]:
107                 if c == c1[p]:
108                     if c2[q] == c2[p] + 1:
109                         lab[q] = TIE_ZONE
110                 else:
111                     lab[q] = TIE_ZONE
112 
113     return lab.reshape(fshape)

Use o espaço abaixo para fazer a sua implementação:

1 grad = MT.iagradm(f)
2 w = twsm(f,m,Bc)
3 adshow(grad)
('q = ', 16384)
------------------------------------------------------------
*** Exception while evaluating code:
  File "<string>", line 2, in <module>
  File "<string>", line 94, in twsm
IndexError: index 16384 is out of bounds for axis 0 with size 16384

------------------------------------------------------------

Exemplo numérico para testar o tie-zone watershed por marcadores

[–] Comments
Roberto Lotufo at 2015-05-26 22:16h
Likes:
Gustavo Pinheiro
 1
Olá Gustavo, não precisa utilizar a estrutura ipdp, dá para usar apenas as 3 funções do aula11_ws.