Exercício 2

Autor: Rodrigo Mologni Gonçalves dos Santos
Data: 16/03/2009

Geração de Imagem Cossenoidal

A toolbox ia636 (http://calhau.dca.fee.unicamp.br/adessoweb/toolboxes/ia636/) oferece diversas funções para manipulação de imagens em Python. A função iacos, por exemplo, é capaz de gerar uma imagem cossenoidal, tal como ilustrada na Figura 1. Visando implementar um algoritmo com a mesma funcionalidade, foi desenvolvida pelo autor a função denominada cossenoidal, que será apresentada mais adiante.

Figura 1 - Exemplo de uma imagem cossenoidal gerada pela função 'iacos'.

1. Equação da cossenóide

A equação para geração de uma imagem cossenoidal, pode ser expressa da seguinte maneira:

Onde:

  • A é a amplitude;
  • fₓ é a frequência horizontal (em ciclos por pixel);
  • fᵧ é a frequência vertical (em ciclos por pixel);
  • u é o número de ciclos (horizontal);
  • v é o número de ciclos (vertical);
  • M é a altura (em pixels);
  • N é a largura (em pixels);
  • θ é a direção da cossenóide (em radianos);
  • T é o período (em pixels);
  • φ é a fase da cossenóide (em radianos).

2. Implementação da função cossenoidal

O código fonte abaixo apresenta a implementação da função cossenoidal pelo autor.

 1 # size   = tamanho da imagem (em pixels)
 2 # period = período (em pixels)
 3 # theta  = direção da cossenóide (em radianos)
 4 # varphi = fase da cossenóide (em radianos)
 5 
 6 def cossenoidal(size, period, theta, varphi):
 7     width  = size[0] # largura da imagem (em pixels)
 8     height = size[1] # altura da imagem (em pixels)
 9 
10     # cria duas matrizes para manipulação
11     x, y = meshgrid(range(height), range(width))
12 
13     fx = cos(theta) / period # frequência horizontal (em ciclos/pixel)
14     fy = sin(theta) / period # frequência vertical (em ciclos/pixel)
15 
16     # equação da cossenóide
17     return cos(2 * pi * (fx * x + fy * y) + varphi)

3. Imagens geradas pela função cossenoidal

As imagens abaixo foram geradas pela função cossenoidal. Todas apresentam tamanho igual a 480 pixels de altura e 640 pixels de largura, amplitude A igual a um e fase da cossenoíde φ igual a zero radianos.

1 fig_2 = cossenoidal([480, 640], 100, pi    , 0)
2 fig_3 = cossenoidal([480, 640], 100, pi / 2, 0)
3 fig_4 = cossenoidal([480, 640], 20 , pi / 4, 0)
4 fig_5 = cossenoidal([480, 640], 200, pi / 4, 0)
5 
6 mmshow(ianormalize(fig_2, [0, 255]), title = 'Figura 2 - Ângulo θ igual a 180 graus.')
7 mmshow(ianormalize(fig_3, [0, 255]), title = 'Figura 3 - Ângulo θ igual a 90 graus.')
8 mmshow(ianormalize(fig_4, [0, 255]), title = 'Figura 4 - Período T igual a 20 pixels.')
9 mmshow(ianormalize(fig_5, [0, 255]), title = 'Figura 5 - Período T igual a 200 pixels')

Figura 2 - Ângulo θ igual a 180 graus.

Figura 3 - Ângulo θ igual a 90 graus.

Figura 4 - Período T igual a 20 pixels.

Figura 5 - Período T igual a 200 pixels

4. Comparação entre as funções aicos e cossenoidal

Visando comparar o desempenho das duas funções, foram geradas duas imagens, sendo a Figura 6 pela função cossenoidal e a Figura 7 pela função iacos. Ambas apresentam tamanho igual a 480 pixels de altura e 640 pixels de largura, amplitude A igual a um, fase da cossenoíde φ igual a zero radianos, ângulo θ igual a 45 graus e período T igual a 100 pixels.

 1 ts    = time.time()
 2 fig_6 = cossenoidal([480, 640], 100, pi / 4, 0)
 3 te    = time.time()
 4 mmshow(ianormalize(fig_6, [0, 255]),
 5     title = 'Figura 6 - ' + str(round((te - ts) * 100000) / 100) + ' milisegundos.')
 6 
 7 ts    = time.time()
 8 fig_7 = iacos([480, 640], 100, pi / 4, 0)
 9 te    = time.time()
10 mmshow(ianormalize(fig_7, [0, 255]),
11     title = 'Figura 7 - ' + str(round((te - ts) * 100000) / 100) + ' milisegundos.')

Figura 6 - 33.29 milisegundos.

Figura 7 - 34.13 milisegundos.

A tabela abaixo exibe seis testes realizados para se comparar o tempo gasto com o processamento para gerar as imagens pelas duas funções.

Teste 1 2 3 4 5 6 Total
cossenoidal 33,42 33,63 33,58 33,28 33,29 33,27 200,47
iacos 34,10 34,38 34,12 34,16 34,32 34,42 205,5
Variação 0,68 0,75 0,54 0,88 1,03 1,15 5,03

Ao final dos seis testes, houve uma economia de 5.03 milisegundos entre o processamento das imagens via função cossenoidal em relação à iacos.

5. Comparação de desempenho automática

O código fonte abaixo imprime uma comparação de desempenho automática entre as funções cossenoidal e iacos. Os parâmetros de entrada são iguais em ambas: tamanho igual a 480 pixels de altura e 640 pixels de largura, fase da cossenoíde φ igual a zero radianos, ângulo θ igual a 45 graus e período T igual a 100 pixels.

 1 n = 10 # número de testes realizados
 2 
 3 a = zeros([n]) # tempo gasto com o processamento da função 'cossenoidal'
 4 b = zeros([n]) # tempo gasto com o processamento da função 'iacos'
 5 c = zeros([n]) # diferença de desempenho entre as funções 'iacos' e 'cossenoidal'
 6 
 7 for k in range(0, n):
 8     ts   = time.time()
 9     cossenoidal([480, 640], 100, pi / 4, 0)
10     te   = time.time()
11     a[k] = round((te - ts) * 100000) / 100
12 
13     ts   = time.time()
14     iacos([480, 640], 100, pi / 4, 0)
15     te   = time.time()
16     b[k] = round((te - ts) * 100000) / 100
17 
18 c = b - a
19 
20 print 'Para ' + str(n) + ' testes simultâneos as funções \'cossenoidal\' e \'iacos\' \
21 gastaram respectivamente (em milisegundos)'
22 print 'com o processamento das imagens:'
23 print ''
24 
25 print a
26 print b
27 print ''
28 
29 print 'Ou seja, as funções \'cossenoidal\' e \'iacos\' gastaram respectivamente ' + \
30 str(sum(a, 0)) + ' e ' + str(sum(b, 0)) + ' milisegundos para'
31 print 'processar ' + str(n) + ' imagens.'
32 print ''
33 
34 if sum(a, 0) != sum(b, 0):
35     if sum(a, 0) > sum(b, 0):
36         print 'Conclui-se que a função \'iacos\' obteve uma economia de ' + \
37         str(sum(c, 0)) + ' milisegundos em relação a função \'cossenoidal\'.'
38     else:
39         print 'Conclui-se que a função \'cossenoidal\' obteve uma economia de ' + \
40         str(sum(c, 0)) + ' milisegundos em relação a função \'iacos\'.'
Para 10 testes simultâneos as funções 'cossenoidal' e 'iacos' gastaram respectivamente (em milisegundos)
com o processamento das imagens:

[ 33.59  33.87  33.85  33.85  33.86  33.87  33.84  33.88  34.05  33.83]
[ 34.99  35.21  34.98  35.01  34.98  35.    34.97  34.93  34.96  35.  ]

Ou seja, as funções 'cossenoidal' e 'iacos' gastaram respectivamente 338.49 e 350.03 milisegundos para
processar 10 imagens.

Conclui-se que a função 'cossenoidal' obteve uma economia de 11.54 milisegundos em relação a função 'iacos'.