Mapeamento de contraste ou de intensidade

Autor: cronuxs
Data: 06/04/2009

Exercício

  1. Estudar a função iaapplylut, fazendo alguns exemplos.
  2. Reprogramar a função iaapplylut para que ela seja mais simples. Se possível.

3. Implementar uma função interativa de melhoria de contraste da imagem. Deve-se usar a função monotonicamente crescente de intensidade formada por 3 segmentos de retas. Os dois pontos de inflexão destas retas devem ser calculados em função de 4 parâmetros: Wi,Li largura e intensidade média de entrada, e Wo, Lo, largura e intensidade média de saída. Existem algumas situações que vocês precisam prever o comportamento desta operação dependendo dos parâmetros passados. Utilizar algumas imagens para ilustrar o uso desta função interativa. Uma ilustração desta função, porém apenas com os parâmetros Wi e Li podem ser vistas em http://www.dca.fee.unicamp.br/DIPcourse/html-dip/c4/s3/front-page.html

Resolução

Item 1

1 it = 255 - arange(256)
2 g = iaapplylut(f, it)

imagem original

Este Item apenas ilustra o uso da função iaapplylut e o mmplot

Item 2

1 def myapplylut(f,it):
2     return it[f]

imagem original

imagem transformada

Este item apenas ilustra como é simples criar uma funcao iaaplylut, apenas trabalhando com a imagem como se fossem indices do vetor it

Item 3

 1 def RetasPorPartes(Wi,Li,Wo,Lo):
 2     #ptos de inflexao
 3     Pto = array( [
 4         [0,0],
 5         [Li - Wi/2,Lo - Wo/2],
 6         [Li + Wi/2,Lo + Wo/2],
 7         [256,256]
 8         ] ).astype(float)
 9 
10     def getEqReta(p1,p2):
11         a = (p2[1]-p1[1])/(p2[0]-p1[0])
12         b = p2[1] - a*p2[0]
13         return lambda x: (a*x + b)
14 
15     #Constroe a equacao das 3 retas
16     Retas = [
17         getEqReta( Pto[0], Pto[1] ),        # para Pto[0,0]  > x > Pto[1,0]
18         getEqReta( Pto[1], Pto[2] ),        # para Pto[1,0] > x > Pto[2,0]
19         getEqReta( Pto[2], Pto[3] ),        # para Pto[2,0] > x > Pto[3,0]
20         ]
21 
22     Pto = maximum(0, minimum(256, Pto ))
23 
24     #Cria o vetor com a transformacao
25     it = arange(256)
26 
27     for i in range(3): # 3 Retas
28         if (Pto[i,0] < Pto[i+1,0]): # Garante a continuidade da funcao
29             it[Pto[i,0]:Pto[i+1,0]] = Retas[i] ( it[Pto[i,0]:Pto[i+1,0]] )
30             #Usa a equacao da reta para plotar os pontos
31 
32     return it.astype(int)
 1 parser = OptionParser()
 2 parser.add_option("--Li", type='int', default=50, help='Posição da janela de entrada')
 3 parser.add_option("--Wi", type='int', default=20, help='Tamanho da janela de entrada')
 4 parser.add_option("--Lo", type='int', default=200, help='Posição da janela de saida')
 5 parser.add_option("--Wo", type='int', default=30, help='Tamanho da janela de saida')
 6 opt, arg = parser.parse_args()
 7 Wi,Li,Wo,Lo = opt.Wi,opt.Li,opt.Wo,opt.Lo
 8 
 9 it = RetasPorPartes(Wi,Li,Wo,Lo)
10 g  = myapplylut(f, it)
11 
12 #mmshow(f, title='imagem original')
13 mmshow(g, title='imagem transformada')
14 mmplot([
15         [it], # Grafico
16         [zeros(256)+(Li - Wi/2),arange(256)], # linhas verticais
17         [zeros(256)+(Li + Wi/2),arange(256)],
18         [zeros(256)+(Lo - Wo/2)], # linhas horizontais
19         [zeros(256)+(Lo + Wo/2)]
20     ],
21     ['set yrange [0:256]','set xrange [0:256]'],
22     ptitle='Funcao de intensidade aplicada')
23 
24 mmplot([[iahistogram(f)]],
25     ['set xrange [0:256]'],
26     ptitle='Histograma antes da transformacao')
27 mmplot([[iahistogram(g)]],
28     ['set xrange [0:256]'],
29     ptitle='Histograma depois da transformacao')

imagem transformada

Este exemplo ilustra o uso de funções lambda para criar funções em tempo de execução, e assim utiliza-las para o calculo de todos os valores de uma reta.