Estereoscopia – Gerando imagem 3D em C usando Allegro

Neste tópico vou mostrar um trabalho realizado por mim: Pedro Henrique, pelo Daniel Mariano Silvério e pelo Carlos Ribeiro, para a matéria de Estrutura de Dados ministrado pelo professor Eduardo Sakaue.

Definição de Estereocopia: Estereoscopia é um fenômeno natural que ocorre quando uma pessoa observa uma cena qualquer. A estereoscopia é a simulação de duas imagens da cena que são projetadas nos olhos em pontos de observação ligeiramente diferentes, o cérebro funde as duas imagens, e nesse processo, obtém informações quanto à profundidade, distância, posição e tamanho dos objetos, gerando uma sensação de visão de 3D.

Resumindo, para fazer uma imagem 3D usando o princípio da Estereoscopia é necessário ter duas imagens, ligeiramente diferentes, uma imagem esquerda e uma direita. Para gerar este efeito no código é necessário que essas duas imagens a esquerda e a direita se intercalem, no caso a imagem esquerda deve ser da cor vermelha e direita da cor azul. Feito isso é necessário pegar cada linha, pixel a pixel, de cada imagem e intercalar em um único vetor. Fazemos dessa maneira, caso a linha de pixel seja par, iremos pegar a imagem esquerda e zerar as cores Azul e Verde do RGB, deixando apenas a cor Vermelha na linha, caso a linha seja ímpar tiramos a cor Vermelha e mantemos apenas a Verde e a Azul, feito isso basta colocar elas em um vetor e pronto: Temos uma ímagem 3D, basta apenas ter os óculos 3D, que podem ser fabricados usando papel Celofane Vermelho e Azul. Veja como.

Vamos ao Código, mas é Importante lembrar que você tem que ter instalado a biblioteca Allegro para fazer este projeto. Para saber como instalar o Allegro.

Para o código use estas imagens, e caso queira colocar outras imagens como fiz no código, basta procurar no Google, que você encontrará diversas imagens para trabalhar com Estereoscopia. Importante: As imagens dever ser .png.

/*
|  FATEC Jessen Vidal - São José dos Campos                 |
|  Trabalho realizado para Disciplina de Estrutura de Dados |
|  Professor: Eduardo Sakaue                                |
|  Alunos: Carlos Ribeiro                                   |
|          Daniel Mariano Silvério                          |
|          Pedro Henrique de Oliveira Silva                 |

*/

#include <allegro.h>
#include <allegro.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <mem.h>

// DEFININDO UMA STRUCT
typedef struct{
     unsigned short int comprimento;
     unsigned short int altura;
     unsigned char palheta[256*3];
     unsigned char *dados;
} IMAGEM;

IMAGEM *esq_buffer;
IMAGEM *dir_buffer;

int a_esq;
int l_esq;
int a_dir;
int l_dir;

/* Inicializa a tela */
void init() {
     int depth, res;
     allegro_init();
     depth = desktop_color_depth();
     if (depth == 0)
         depth = 32;
     set_color_depth(depth);
     set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0); // Adaptar para sua tela
     install_timer();
     install_keyboard();
     install_mouse();
}

void deinit() {
     clear_keybuf();
}

/* Função que lê o header da imagem e grava seus dados */
void le_header(const char *caminhoesq, const char *caminhodir){

/*ABRINDO OS ARQUIVOS PARA LER O HEADER*/
     FILE *esq;
     FILE *dir;

     if((dir=fopen(caminhodir, "rb"))==NULL){
          allegro_message("Nao foi possivel abrir o aqruivo 'direita'");
          exit(-1);
     }
     if((dir_buffer=(IMAGEM *)malloc(sizeof(IMAGEM)))==NULL){
          allegro_message("Erro ao alocar a memoria");
          exit(-1);
     }
     if((esq=fopen(caminhoesq, "rb"))==NULL){
          allegro_message("Nao foi possivel abrir o aqruivo 'esquerda'");
          exit(-1);
     }

     if((esq_buffer=(IMAGEM *)malloc(sizeof(IMAGEM)))==NULL){
          allegro_message("Erro ao alocar a memoria");
          exit(-1);
       }

     fseek(dir, 18, SEEK_SET); //IMAGEM DIREITA
     fread(&dir_buffer->comprimento, sizeof(unsigned short int), 1, dir);
     fseek(dir, 2, SEEK_CUR);
     fread(&dir_buffer->altura, sizeof(unsigned short int), 1, dir);

     fseek(esq, 18, SEEK_SET);//IMAGEM ESQUERDA
     fread(&esq_buffer->comprimento, sizeof(unsigned short int), 1, esq);
     fseek(esq, 2, SEEK_CUR);
     fread(&esq_buffer->altura, sizeof(unsigned short int), 1, esq);

//COMPARA O TAMANHO DAS IMAGENS
     a_esq = esq_buffer->altura;
     l_esq = esq_buffer->comprimento;
     a_dir = dir_buffer->altura;
     l_dir = dir_buffer->comprimento;

     if((a_esq != a_dir) || (l_dir != l_esq)){
          allegro_message("Tamanho das imagens diferentes");
          exit(-1);
     }

//FECHA OS ARQUIVOS
     fclose(esq);
     fclose(dir);

    }

int projeto(const char *caminhoesq, const char *caminhodir){

     BITMAP *esq_bmp;
     BITMAP *dir_bmp;
     BITMAP *j = create_bitmap(l_esq,a_esq);

     esq_bmp = load_bitmap(caminhoesq,NULL);
     if(!esq_bmp){
          allegro_message("Nao foi possivel abrir o aqruivo 'esq.bmp'");
          exit(-1);
     }
     dir_bmp = load_bitmap(caminhodir,NULL);
     if(!dir_bmp){
          allegro_message("Nao foi possivel abrir o aqruivo 'dir.bmp'");
           exit(-1);
     }

     int vetFinal[l_esq][a_esq];
     int x,y;
     for(x=0; x<l_esq; x++){
          for(y=0; y<a_esq; y++){
               int color;
               if ((y%2 )==0) color = makecol((getr(_getpixel32(esq_bmp, x, y))),0,0);
               else color = makecol(0,getg(_getpixel32(dir_bmp, x, y)),getb(_getpixel32(dir_bmp, x, y)));
          vetFinal[x][y] = color;
         }
      }

     for(x=0; x<l_esq; x++){
          for(y=0; y<a_esq; y++){
                _putpixel32(j, x, y, vetFinal[x][y]);
     }
          }

     draw_sprite(screen, j, 0,0);

     destroy_bitmap(esq_bmp);
     destroy_bitmap(dir_bmp);

     deinit();
     return 0;

     }

int main() {
     init();
     while (!key[KEY_ESC]) {

     if ((readkey() >> 8) == KEY_1) {
          le_header("imagens/img00_esq.bmp", "imagens/img00_dir.bmp");
          projeto  ("imagens/img00_esq.bmp", "imagens/img00_dir.bmp");
      }

      if ((readkey() >> 8) == KEY_2) {
          le_header("imagens/img01_esq.bmp", "imagens/img01_dir.bmp");
          projeto  ("imagens/img01_esq.bmp", "imagens/img01_dir.bmp");
       }
       if ((readkey() >> 8) == KEY_3) {
           le_header("imagens/img02_esq.bmp", "imagens/img02_dir.bmp");
           projeto  ("imagens/img02_esq.bmp", "imagens/img02_dir.bmp");
       }
       if ((readkey() >> 8) == KEY_4) {
            le_header("imagens/img03_esq.bmp", "imagens/img03_dir.bmp");
            projeto  ("imagens/img03_esq.bmp", "imagens/img03_dir.bmp");
       }
     }
   }

     END_OF_MAIN()

Bom, é isso, caso tenham gostado deixem um comentário! Dúvidas e sugestões são bem-vindas. Depois irei postar o código que fizemos usando duas câmeras! Para saber mais sobre estereoscopia.

Um forte Abraço!

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s