terça-feira, 26 de janeiro de 2016

Média, Desvio Padrão e Eistein

Na aula sobre média e desvio padrão, analisamos a média dos tons de cinza da famosa imagem de Albert Eistein, também aplicando sobre a análise desta média os desvios padrões.

Na atividade passada para ser feita em casa, foi pedido que fossem analisadas essa mesma imagem com variações de brilho e contraste.

Primeiro, vou deixar aqui o código comentado utilizado para isso.

//variável que armazena a imagem
PImage img;
void setup(){
  size(640, 480);
  float t=0, mediaT, somaT=0;
  int pos;
  //carregamento da imagem
  img = loadImage("einstein.jpg");
  //a imagem é percorrida e são pegues os valores vermelhos dos pixels
  for (int x = 0; x < 640; x++){
    for (int y = 0 ; y < 480; y++){
      pos = y * 640 + x;
      t = red(img.pixels[pos]);
      //aqui, são deixados o valores totais somados destes pixels
      somaT = somaT + t;
  }
}

//aqui, é calculada a média destes valores
mediaT = somaT/(640*480);
println("Média de Tons é ", mediaT);

/*aqui, é calculado o desvio padrão a partir da raiz quadrada da variância (armazenada
na variável "v"*/
float v, SomaV = 0;
for (int x = 0; x < 640; x++){
  for (int y = 0; y < 480; y++){
    pos = y * 640 + x;
    t = red(img.pixels[pos]);
    v = pow(t - mediaT, 2);
    SomaV = SomaV + sqrt(v);
  }
}
//desvio padrão
float media = SomaV/(640*480);
println(media);

}

void draw(){
  image(img, 0, 0);
}

Nas imagens com níveis diferentes de brilho e contraste havia uma alteração significativa nos valores da média e desvio padrão. Quanto maior o brilho, maior o desvio padrão, o que é refletido pelo maior valor que um brilho maior dá para os pixels que compõem a imagem.

Barco Seno

A função seno consiste na projeção do deslocamento de um ponto no eixo y do gráfico, variando de -1 a 1. Um exemplo disso pode ser verificado no gif abaixo:


Na atividade relativa a essa aula, foi pedido a turma que fosse feita uma aplicação no processing que consistisse de um barco navegando no mar e seu movimento fosse correspondente a função seno.

Segue abaixo o código comentado com um gif ilustrando o resultado:

/*variáveis que armazenam as imagens do barco, do céu(metade de cima da imagem
e do mar(metade de baixo da imagem)*/
PImage barquinho, ceu, mar;

void setup(){
  size(800, 600);
  barquinho = loadImage("barquinho.png");
  ceu = loadImage("ceu.png");
  mar = loadImage("mar.png");
 
  noStroke();
}

float x = 0;
void draw(){
  background(255);
  //eixo y irá pegar o seno do eixo x, causando a variação na altura do barco
  float y = sin(x);
  //o eixo x será incrementado, para haver o deslocamento horizontal do barco
  x+= 0.1;
  //para ficar mais aparente, o eixo y tem seu valor multiplicado em 10 vezes
  y = y*10;
 
  image(ceu, 0, 0);
  /*o barco tem o deslocamento aumentado em 30 vezes no eixo horizontal para
  dar a impressão de ter uma navegação no mar de forma mais "realista", enquanto que
  o eixo y foi adicionado em 90 para que ele fique num ponto que seja mais coerente
  com a imagem*/
  image(barquinho, x*30, y+90);
  image(mar, 0, 300);
 

 
 
}


A importância dos conjuntos nas aplicações

A teoria dos conjuntos ajuda principalmente na organização do raciocínio crítico e no desenvolvimento de métodos que solucionem problemas. Por exemplo, na aula do dia 15/02, foi passado uma atividade que consistia de aplicarmos de forma contínua mais e mais filtros e ruídos a uma image, finalmente colocando-a em uma moldura.

Isso foi a aplicação da teoria dos conjuntos, em que uma propriedade era aplicada sobre a outra, adicionando a anterior e obtendo um resultado que só era possível com a junção da aplicação dos dois métodos. É uma clássica representação da propriedade de um conjunto estar contido no outro, no caso, de uma propriedade estar contida em outra.


Ajuste de contraste

O ajuste de contraste numa imagem é feito a partir da alteração dos valores RGB desta imagem. Quanto maior for o valor dado aos parâmetros RGB, a imagem será mais clara, assim como quanto menores forem estes valores ela vai se tornando mais escura.

Segue abaixo o código que fiz junto com os comentários explicando cada parte do código. Ao final, uma imagem demonstrando o resultado.

//variável com a imagem original
PImage imgOriginal;
//variável que irá armazenar a cópia da imagem, informando o tamanho dele
PImage imgCopia = createImage(320, 240, RGB);

//variável que referencia a posição dos pixels
int pos;
/*variáveis que armazenam o valor dos pixels referenciando, respectivamente,
red, green e blue*/
float r;
float g;
float b;
//variável que receberá o valor de contraste
float contraste;

void setup(){
  size(640, 480);
  imgOriginal = loadImage("original.jpg");
  //loop que percorrerá a imagem original
  for (int x = 0; x < 320; x++){
    for (int y = 0; y <240; y++){
      pos = y * 320 + x;
      //valor dado ao contraste que irá modificar a imagem
      contraste = 30;
      //armazenamento do valor RGB dos pixels da imagem original somados ao contraste
      r =  contraste + red(imgOriginal.pixels[pos]);
      g = contraste + green(imgOriginal.pixels[pos]);
      b = contraste + blue(imgOriginal.pixels[pos]);
      //imagem recebe os valores RGB somado com o contraste
      imgCopia.pixels[pos] = color(r, g, b);
     
    }
  }
}

void draw(){
  //posicionamento das imagens
  image(imgOriginal, 0, 0);
 
  image(imgCopia, 320, 0);
}


Criação de um mapa com tileset isométrico

Na construção do mapa de um jogo, precisamos nos questionar como ele será apresentado na tela, levando sempre em consideração a dimensão dos tiles (ou seja, as imagens) que o compõem.

Para o exercício da aula sobre conjuntos, foi construído com a ajuda de uma matriz uma imagem com diferentes tilesets. Dependendo do valor que havia na matriz, era carregada uma imagem diferente.

Para o exercício passado para casa, foi pedido que construíssemos no Processing uma imagem utilizando um tileset isométrico.

Abaixo, segue o código comentado explicando cada parte dele e em seguida a imagem resultante.


//variáveis que irão armazenar as imagens utilizadas nesta atividade
PImage imgroadNorth, imgroadSouth, imgroadWest, imgroadEast;


//montagem da matriz que irá inserir os elementos da imagem
int[][]mapa = {{2,2,2,2,2,2,2,2},
               {3,1,0,1,0,0,1,0},
               {0,2,0,0,0,1,3,0},
               {0,3,0,2,1,0,0,0},
               {0,2,0,3,0,0,1,0},
               {0,0,1,2,0,2,0,0},
               {0,1,0,2,0,2,1,0},
               {1,1,1,1,1,1,1,1}};
             

void setup(){
  size(800, 420);
}

void draw(){
  //arquivos usados: olhe o nome depois de "img"
  //tamanho das imagens: 100 x 65
  imgroadNorth = loadImage("roadNorth.png");
  imgroadSouth=  loadImage("roadTSouth.png");
  imgroadWest= loadImage("roadTWest.png");
  imgroadEast = loadImage("roadEast.png");
 
  //para fazer a imagem, foi feito um laço dentro de outro laço que percorrem a matriz
  //a matriz é percorrida de coluna em coluna de forma sequencial.
  //Terminada uma coluna, é passado para a próxima.
  for(int i=0; i<8; i++){
    for(int j=0; j<8; j++){
      /*ao percorrer a matriz, é considerado a numeração de cada índice
      para que sejam escolhidas as imagens que serão desenhadas na tela*/
      switch(mapa[j][i]){
        case 0:
        /*para a localização de cada imagem, foi considerado tanto o formato da figura que
        ela possui quanto suas dimensões, além das dimensões da tela.
        Além disso, era necessário considerar o posicionamento da próxima figura
        na tela. Para cada elemento, ele soma na posição Y um quarto da altura
        da imagem e na posição X ele diminui um quarto da largura da imagem.
        Claro, isto funciona nas dimensões destas imagens.
        */
        image(imgroadNorth, i*50-j*50+width/2-50, j*25+i*25);
        break;
       
        case 1:
        image(imgroadSouth,  i*50-j*50+width/2-50, j*25+i*25);
        break;
       
        case 2:
        image(imgroadWest,  i*50-j*50+width/2-50, j*25+i*25);
        break;
       
        case 3:
        image(imgroadEast,  i*50-j*50+width/2-50, j*25+i*25);
        break;
      }
    }
  }
}
 

domingo, 24 de janeiro de 2016

TED Talk: A Beleza na visualização dos dados



TED Talks costumam ser pequenas palestras que tentam ser concisas e buscam sempre mostrar um ponto de vista diferenciado com seus palestrantes. Não por coincidência, somos surpreendidos pela bela palestra de David McCandless com sua demonstração sobre a importância da forma que visualizamos os dados de qualquer pesquisa.

Números, por si só, não colaboram na demonstração realista dos fatos que eles representam. Dizer que uma crise econômica irá prejudicar no desenvolvimento da maioria dos países é uma coisa, entretanto no momento que ele demonstrou graficamente que todo o prejuízo causado por esta crise engoliria facilmente todas as riquezas produzidas por vários países desenvolvidos no curso de um ano, o impacto dessa visualização é sentido na platéia.

A utilização de gráficos facilita a compreensão do dado bruto, o qual quando apenas colocado em uma tabela não deixa fácil sua leitura ou sua compreensão. Outro exemplo, demonstrado pelo palestrante é como fica mais fácil encontrar uma vitamina que ele toma como suplemento se ele se utilizar não apenas de uma demonstração visual dos dados que ele possui, mas aplicar também uma interatividade com a aplicação que está demonstrando aquele dado, destacando de forma dinâmica exatamente o que ele mais precisa.

Na realidade, a percepção da importância da utilização de representação gráfica de dados tem sido algo que tem aumentado bastante. Por exemplo, existe um subreddit (que é uma comunidade dentro do site de compartilhamento de links chamado reddit) chamado Data is Beautiful, o qual consiste de mostrar diferentes representações gráficas que demonstram desde que pessoas que trabalham em casa durante tempestades de neve produzem mais até demonstrar a correlação dos gastos nos Estados Unidos em ciência, viagem espacial e tecnologia com suicídios por enforcamento, estrangulamento e sufocamento.