RA on-demand
Criando interfaces em tempo de execução.
08:38fb.com/RVA.BR
2
Construção de interfaces on-
demand baseadas em
Realidade Aumentada
Projetiva para Controle de
Hardware (Arduino)
Drª. Ana...
Objetivo do Capítulo
SketchSynth
BackStage
08:38fb.com/RVA.BR
4
Objetivo da Apresentação
08:38fb.com/RVA.BR
5
Objetivo da apresentação
• Devido as restrições, vamos montar uma versão simplificada:
• Ausência de projetores para todos...
Agenda:
• Conceito e openFramework
• Criando o primeiro programa em openFrameworks
• Conectando com o Arduino
• Estudos de...
Conteúdo está em
•http://www.4shared.com/folder/Xka
Uh0KM/Resources.html
• Link tá muito difícil??? Vai em
cscerqueira.com...
CONCEITOS
Básico - Experiências
08:38fb.com/RVA.BR
9
“The product is no longer the
basis of value. The
experience is.”
Venkat Ramaswamy
The Future of Competition
08:38fb.com/R...
Valor de uma boa experiência
08:38fb.com/RVA.BR
11
Interação
Texto, som,
cores, visual,
mecânico ou
físico.
Interface
Mensagens
Usuário Sistema
08:38fb.com/RVA.BR
12
Usabilidade
08:38fb.com/RVA.BR
13
Exemplo:
• Usabilidade:
1. Facilidade de
aprendizado
2. Eficiência
3. Facilidade de
memorização
4. Erros
5. Satisfação sub...
3 níveis
Lógico: Resolvem, solucionam,
facilitam.
Emocional: Satisfazem
necessidades e desejos
afetivos.
Visceral: resolve...
Espera.... Visceral?
08:38fb.com/RVA.BR
16
08:38fb.com/RVA.BR
17
Realidades – Realidade Virtual
interface que permite ao
usuário interagir, em tempo real,
com um mundo
tridimensional gera...
Billinghurst Vision
08:38fb.com/RVA.BR
19
Realidades – Realidade Aumentada
uma interfacebaseada na
sobreposição de informações virtuais
geradas por computador (envo...
Christopher Vision
Informação virtual
Interação Natural
dispositivos tecnológicos
08:38
21
fb.com/RVA.BR
Realidades – Realidade Cruzada
é um ambiente de realidade misturada ubíqua, que
vem da fusão de uma rede de sensores e atu...
Kirner’s Diagram – elementos
Source: (KIRNER et al., 2012)
Lego
Cave
08:38fb.com/RVA.BR
23
Realidade Cruzada
Objetos reais
Sensores e
Atuadores
Realidade Aumentada
OCR
NOCR
NOCR
Introdução
08:38fb.com/RVA.BR
24
HIT - ROADMAP
CR AI
HI
AR
IoT
HR
KMatsuda
08:38fb.com/RVA.BR
25
[ ] Hololens
• Talvez o primeiro hardware de RA, com sobreposição, que
entra com força no mercado.
• Google Glass tentou, ...
Qual o motivo de RA ainda não ter
pego em atividades de engenharia?
HWs de
interação?
HWs de
visualização?
Frameworks
de r...
Um dos motivos ao nosso ver é:
• Dificuldade de criação e manipulação de uma interface
de RA a medida que é utilizada.
• P...
OPENFRAMEWORKS
08:38fb.com/RVA.BR
29
Processing
Adobe Flash
Unity
Cinder
openFrameworks
08:38fb.com/RVA.BR
30
openframeworks.cc
• Vídeo oF1....media_videos7_openFrameworks1.mp4
• Vídeo oF2....media_videos7_openFrameworks2.mp4
08:38f...
oF
• Criado para artistase designers
• Desenvolvido por: Zach Liberman, Theo Watson, Artuno
Castro e Chris O’Shea
•Propost...
33
08:38fb.com/RVA.BR
C++ Portável!!!!
34
08:38fb.com/RVA.BR
Página Principal –
openframeworks.cc
08:38fb.com/RVA.BR
35
Libs no pacote padrão
• OpenGL, GLEW, GLUT, libtess2 e cairo para gráficos.
• rtAudio, PortAudio ou FMOD e Kiss FFT para e...
Addons da comunidade:
ofxaddons.com
08:38fb.com/RVA.BR
37
OSX,
Linux,
Windows,
iOS,
Android,
Linux
ARM
08:38fb.com/RVA.BR
38
ERA TROGLODITA (C++)
• Graduação (2010):
• ARToolKit
• PTAMM
• Bolsista DTI (2011):
• basAR
ERA DO FOGO (C++/oF)
• Mestrad...
MDE (Model Driven Engineering)
MBSE (ModelBased SystemEngineering)
• MDE é um conjunto de práticas de
engenharia, baseadas...
Três tipos principais de aplicações
MDE
MDE
Geração automática Descoberta do Modelo Interoperabilidade de
sistemas
41
Um m...
MDE Natural Env.
08:38fb.com/RVA.BR
42
• Introdução à utilização de openFrameworks para o
desenvolvimento de aplicações de RVA
Link
• Construção de aplicações de...
SVR2013 - Resultados
44
08:38fb.com/RVA.BR
SVR2014 - Resultados
08:38
45
fb.com/RVA.BR
WRVA2014 - Resultados
08:38fb.com/RVA.BR
46
PRIMEIRO PROGRAMA EM OF
Vou pular, coloquei aqui para ficar + completo
08:38fb.com/RVA.BR
47
Onde encontrar?
08:38fb.com/RVA.BR
48
Level Easy: Gerador
Automático
49
08:38fb.com/RVA.BR
Escolhendo expansões
50
DocoreoF
Dacomunidade
08:38fb.com/RVA.BR
Estrutura do projeto
08:38fb.com/RVA.BR
51
Exemplo básico
08:38fb.com/RVA.BR
52
// ofApp.cpp
void ofApp::setup(){
mensagem = "Hello SVR2015!!!";
raio = 0;
}
void ofA...
ARDUINO
O que é? Onde vivem?
Existe? Hoje no Glob..
Fritzing, Arduino 1.0, Firmata, exemplo
openFrameworks
08:38fb.com/RVA...
O que tem no ARDUINO?
08:38
54
fb.com/RVA.BR
Outras versões
08:38
55
fb.com/RVA.BR
Shields
08:38
56
fb.com/RVA.BR
FIRMATA
Literatura indica FIRMATA:
http://firmata.org/wiki/Download
08:38
57
fb.com/RVA.BR
O que a FIRMATA faz!?
• Transforma o ARDUINO numa interface de controle, podendo
ser modificado por um host.
• Quais as va...
Obs.: Mudança da nomenclatura
dos pinos após Firmata 2.3
(Arduino 1.0)
Tomar cuidado na hora de
desenvolver!!!!!!!!!!
08:3...
Instalando a Firmata no
Arduino
• Faça download do
Arduino 1.0.6
http://arduino.cc/en/
Main/Software
• Abra o sketch do
Fi...
“esquemático”
08:38
61
fb.com/RVA.BR
• #crashcourse fritzing
• http://fritzing.org/home/
Arduino e openFrameworks
08:38fb.com/RVA.BR
62
Métodos para conectar com o
ARDUINO
 connect()
 disconnect()
 getAnalog()
 getAnalogPinReporting()
 getDigital()
 ge...
Código no openFrameworks
• Exploração do exemplo: communicationfirmataExample
08:38fb.com/RVA.BR
64
Fluxograma básico
08:38fb.com/RVA.BR
65
SETUP
Habilita callback
de Arduino Alive
Arduino
Responde Evento
Alive
Configura
A...
Código
08:38fb.com/RVA.BR
66
//ofApp.h
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp{
public:
…
ofArduin...
ESTUDO DE CASOS:
08:38fb.com/RVA.BR
67
Casos
• 0.a. O que vamos fazer:
• 1. Detecção de infraestrutura (contornos)
• 2. Detecção de atuador (diferença de
imagens...
0.a. O que vamos
fazer:
Ambiente reativo à
altura da areia
Ambiente reativo ao
comportamento dos
pontos (soldados)
08:38fb.com/RVA.BR
70
Conceito de ambiente dividido
em pontos e camadas
08:38fb.com/RVA.BR
71
Diagrama de etapas
08:38fb.com/RVA.BR
72
O que vamos usar para o
exemplo
08:38fb.com/RVA.BR
73
Só use mais hardware quando
realmente precisar.
08:38fb.com/RVA.BR
74
DETECTING INFRASTRUCTURE
Encontrando uma
folha de papel para
servir de referência
para a montagem dos
elementos de
interaç...
Detectar a infraestrutura
Capturar
Imagem
Procurar
“coisas” brancas
Identificar
polígono
• Maior de todos?
é um
retângulo?...
Exemplo: Rastreio de
Marcador
08:38fb.com/RVA.BR
77
USANDO O OPENCV
Cores, blobs e exemplos
08:38fb.com/RVA.BR
78
Cores
RGB-A (red, green, blue)-alfa HSV (hue (cor), saturation, value)
08:38
79
fb.com/RVA.BR
Blobs
• Método de busca de características.
• Blobs compartilham propriedades constantes que podem ser
“percebidas” na ima...
Construção dos artefatos : Rastreio
Cores
08:38
81
fb.com/RVA.BR
Bonus: Projection Mapping
08:38fb.com/RVA.BR
82
PM
PM
Usos
• Table-tops
• Projeções em paredes
08:38
83
fb.com/RVA.BR
Sensetable
L.A.S.E.R. Tag
Climbing
OASIS
Continuando ....
Usando o addon: ofxCv de Kyle McDonald
https://github.com/kylemcdonald/ofxCv
08:38fb.com/RVA.BR
84
Tipo: ofxCv::ContourFinder
• Tipo/função que procura blobs numa imagem.
• Retorna os blobs e características:
• Posição
• ...
Project Generator addons
08:38fb.com/RVA.BR
86
// Camera:
ofVideoGrabber cam; // Video Tracking source
int camHeight;
int camWidth;
ofImage unwarped; // RAW image from c...
Identificar Formas Convexas
• Entrada: número de vértices
• 3 vértices = TRIANGULO
• 4 vértices e cos +/- 0 = RETÂNGULO
• ...
string ofApp::findForm(const ofPolyline &poly){
vector<ofPoint> corners = poly.getVertices(); // pega todos os vértices
if...
static double angle(ofPoint pt1, ofPoint pt2, ofPoint pt0)
{
double dx1 = pt1.x - pt0.x;
double dy1 = pt1.y - pt0.y;
doubl...
void ofApp::setup(){
// Parte 2 - Código do Exemplo
ofLogNotice("[PAPER DETECTOR]") << " Configure CV ";
contourFinder.set...
void ofApp::update(){
cam.update();
float area;
if(cam.isFrameNew()){
//ofLogNotice("[PAPER DETECTOR]") << "New Frame";
ve...
// teste se foi encontrado algo parecido com um retângulo.
this->foundInfra = false;
if ( this->findForm(maxQuad) == "RECT...
void ofApp::draw(){
ofSetColor(ofColor::white); cam.draw(0,0);
ofNoFill();
int n = contourFinder.size();
for(int i = 0; i ...
Resultado Esperado
08:38fb.com/RVA.BR
95
WHERE IS MY HAND? DETECTING THE
ACTUATOR
Detectando a mão, caneta,
ou qualquer outra coisa
(medo) que você queira
usar par...
Rastrear mão (apontador 2D)
• Restrições (para facilitar)
Fundo homogêneo
Longe das quinas
Uma mão só
• Pseudo-código
•...
Lets code.... Babe!!!! 
#include "ofMain.h"
#include "ofxOpenCv.h" //Cabeçalho do OpenCV
#include "ofxCv.h"
class ofApp :...
Tipo: ofPoint
• ofPoint é um tipo muito utilizado no openFrameworks que
faz as vezes de um ponto na área da janela.
• Com ...
Setup
void ofApp::setup(){
width = 320; height = 240;
vidGrabber.initGrabber(width, height); //abre câmera
colorImage.allo...
Comparando imagens
08:38fb.com/RVA.BR
101
Update
void ofApp::update(){
vidGrabber.update(); // Pega frame da câmera
if(vidGrabber.isFrameNew()){ // é um frame novo ...
Marcando dedos (pontos
distantes)
08:38fb.com/RVA.BR
103
Ponto mais distante – p1
ofPoint ofApp::encontraPontoMaisDistante(){
int n = contourFinder.size(); //qtidade de blobs capt...
Ponto mais distante – p2
for(itVec = vertices.begin(); itVec != vertices.end(); itVec++){
//encontrar ponto mais distante ...
Draw
void ofApp::draw(){
ofSetColor(255); grayImage.draw(0, 0); // desenha câmera
ofTranslate(320, 0); grayDiff.draw(0, 0)...
Resultado desejado:
08:38fb.com/RVA.BR
107
PLAYING IN THE AIR!
Interagindo em
elementos
virtuais com a
mão.
08:38fb.com/RVA.BR
108
Definindo um conjunto de
ações
• Assunto: Controlar um Arduino 
• Ações:
• Acender e Apagar um LED via Arduino, com repli...
Espalhando controles virtuais pela
área capturada pela câmera
• 1º Projeto de Interface (livre em toda a área)
“É você Goo...
Tipo: ofRectangle
• Tipo que define um retângulo na tela.
• Retângulos são muito usados para definir áreas de toque.
(Form...
Some code... (testartoques?inside())
ofRectangle controleServo;
ofRectangle chaveOff;
ofRectangle chaveOn;
ofPoint LEDIndi...
Resultado desejado
08:38fb.com/RVA.BR
113
Adicionando comandos e
leitura do Arduino
// Setup Arduino()
ard.sendDigitalPinMode(2, ARD_INPUT); // led do exemplo
ard.s...
bool ofApp::updateInterface(ofPoint dedo){
if( this->controleServo.inside(dedo) ) { // trata evento com servo
// |controle...
TRACKING PHYSICAL CONTROLS.
THINGS ARE GETING REAL
Rastreando controles
desenhados na
infraestrutura
08:38fb.com/RVA.BR
116
*Versão projetada
08:38fb.com/RVA.BR
117
Pseudo Código
• Encontrada a infraestrutura:
• Update:
1. Processar imagem
2. Procurar controles
1. Procurar tipo Slide
2....
Processamento de Imagem
Infra
08:38fb.com/RVA.BR
119
Etapas do processamento
2.
Canny
3.
Dilate
4.
Erode
6. contourFinder
infra
08:38fb.com/RVA.BR
120
No “ofApp.h”
// Controles
ofxCv::ContourFindercontrolFinder;
booldoControlDetection;
// auxiliares para forçar as imagens:...
Processamento da imagem
void ofApp::encontraControles(){
Mat img = ofxCv::toCv(this->unwarped);
// Get the image in the ri...
Procurar Controles
08:38fb.com/RVA.BR
123
Tipos de Controles:
Switch – Posição 0 ou 1, memoriza a função
Button – Posição 0 ou 1, instantâneo, funciona
enquanto cli...
Identificação dos tipos de
controles
08:38fb.com/RVA.BR
125
Estrutura de dados genérica
(super-hiper-mega simplificada)
enum controlType{
CT_SWITCH,
CT_BUTTON,
CT_SLIDE
};
class Cont...
Tipo: vector (de classes)
• Vector é uma estrutura para armazenar sequencialmente.
• No C++ vários tipos de estruturas de ...
//... Continuing - void ofApp::encontraControles()
listaDeControles.clear();
int n = controlFinder.size();
for(int i = 0; ...
//---------------------------------------------------------
bool ofApp::isButton(int i) {
float radius;
controlFinder.getM...
Criaroscontroles-FYI
void fillSlider( cv::RotatedRect rotRect){
this->type = controlType::CT_SLIDE;
const cv::Size &s = ro...
Draw do botão:
case controlType::CT_BUTTON :{
ofPushMatrix();
ofSetColor(ofColor::green);
ofSetLineWidth(5);
if (this->val...
case controlType::CT_SWITCH:{
ofPushMatrix();
ofTranslate(this->posRect.getCenter());
ofRotate(this->angle);
ofNoFill();
o...
case controlType::CT_SLIDE:{
ofPushMatrix();
ofTranslate(this->posRect.getCenter());
ofRotate(this->angle);
ofNoFill();
of...
FINAL LAP: INTERAÇÃO COM OS
CONTROLES
08:38fb.com/RVA.BR
134
Fixar os pontos de corte da
figura!!!!!!!!!!!!!!
08:38fb.com/RVA.BR
135
Inside!?
bool buttonContains(int x, int y){
return ofDistSquared((float)pos.x, (float)pos.y,
(float)x, (float)y) < radius ...
switch(type){
case controlType::CT_BUTTON :
if (buttonContains(dedo.x, dedo.y)) {
value == 1 ? value = 0 : value = 1;
retu...
Resultado Esperado
08:38fb.com/RVA.BR
138
WRAP-UP
08:38fb.com/RVA.BR
139
O QUE APRENDEMOS HOJE
O QUE
ACONTECEU:
class src
«enumeratio...
controlType
CT_SWITCH
CT_BUTTON
CT_SLIDE
Controle
+ id :int
+ type :controlType
...
class Class Model
ofBaseApp
ofApp
+ par :ofxProjAR
+ setup() :void
+ update() :void
+ draw() :void
+ keyPressed(int) :void...
• Existe um framework em C++ chamado
openFrameworks. Novo player interessante: Unreal
Engine + Blueprints (AWESOME)
• open...
• openCV é uma biblioteca de visão computacional.
• Com openCV podemos rastrear cores, diferenças de
imagens, etc.
• Pense...
08:38fb.com/RVA.BR
144
Motivador
Pesquisa
Dúvidas: christophercerqueira@gmail.com
Site: http://cscerqueira.com.br
Facebook: http://fb.com/RVA.BR
Para maiores dúvida...
Próximos SlideShares
Carregando em…5
×

Construção de interfaces on-demand baseadas em Realidade Aumentada Projetiva para Controle de Hardware (Arduino)

464 visualizações

Publicada em

Minicurso do SVR 2015
O conteúdo do capítulo está na revista: "Tendências e Técnicas em Realidade Virtual e Aumentada - v.05 / 2015"
São Paulo

Publicada em: Educação
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
464
No SlideShare
0
A partir de incorporações
0
Número de incorporações
7
Ações
Compartilhamentos
0
Downloads
5
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Construção de interfaces on-demand baseadas em Realidade Aumentada Projetiva para Controle de Hardware (Arduino)

  1. 1. RA on-demand Criando interfaces em tempo de execução.
  2. 2. 08:38fb.com/RVA.BR 2
  3. 3. Construção de interfaces on- demand baseadas em Realidade Aumentada Projetiva para Controle de Hardware (Arduino) Drª. Ana Maria Ambrosio MSc. Christopher Cerqueira aluno doutorado Dr. Claudio Kirner
  4. 4. Objetivo do Capítulo SketchSynth BackStage 08:38fb.com/RVA.BR 4
  5. 5. Objetivo da Apresentação 08:38fb.com/RVA.BR 5
  6. 6. Objetivo da apresentação • Devido as restrições, vamos montar uma versão simplificada: • Ausência de projetores para todos os alunos • Ausência de ARDUINO para todos os alunos • Mostrar um framework para construção de apps de RA / RC. • openFrameworks • Mostrar os recursos de controle de hardware (Arduino) • Mostrar os recursos de CV (openCV): rastreio de contorno (infraestrutura e controles) e processamento de imagem (mão). • Mostrar tipos comuns para criação de interface. • openFrameworks • Aplicações tipo interação em mesa. (Projeção) 08:38fb.com/RVA.BR 6
  7. 7. Agenda: • Conceito e openFramework • Criando o primeiro programa em openFrameworks • Conectando com o Arduino • Estudos de caso / Construção do ambiente (exemplos): • 1. Detectar infraestrutura (Apenas rastreio do papel) • 2. Rastreio do atuador (rastreio da mão) • 3. Interação com estrutura virtual • 4. Detectar estrutura física on-demand (sem reprojeção) • Wrap-Up 3 horas 1,5h 1,5h 08:38fb.com/RVA.BR 7
  8. 8. Conteúdo está em •http://www.4shared.com/folder/Xka Uh0KM/Resources.html • Link tá muito difícil??? Vai em cscerqueira.com.br 08:38fb.com/RVA.BR 8
  9. 9. CONCEITOS Básico - Experiências 08:38fb.com/RVA.BR 9
  10. 10. “The product is no longer the basis of value. The experience is.” Venkat Ramaswamy The Future of Competition 08:38fb.com/RVA.BR 10
  11. 11. Valor de uma boa experiência 08:38fb.com/RVA.BR 11
  12. 12. Interação Texto, som, cores, visual, mecânico ou físico. Interface Mensagens Usuário Sistema 08:38fb.com/RVA.BR 12
  13. 13. Usabilidade 08:38fb.com/RVA.BR 13
  14. 14. Exemplo: • Usabilidade: 1. Facilidade de aprendizado 2. Eficiência 3. Facilidade de memorização 4. Erros 5. Satisfação subjetiva Meta- Mensagens Usuário Sistema 08:38fb.com/RVA.BR 14
  15. 15. 3 níveis Lógico: Resolvem, solucionam, facilitam. Emocional: Satisfazem necessidades e desejos afetivos. Visceral: resolvem questões fundamentais, sem consciência. Impulso. 08:38fb.com/RVA.BR 15
  16. 16. Espera.... Visceral? 08:38fb.com/RVA.BR 16
  17. 17. 08:38fb.com/RVA.BR 17
  18. 18. Realidades – Realidade Virtual interface que permite ao usuário interagir, em tempo real, com um mundo tridimensional gerado por computador, usando seus sentidos através de equipamentos especiais. SOURCE: NASA (2013a) 08:38 18 fb.com/RVA.BR
  19. 19. Billinghurst Vision 08:38fb.com/RVA.BR 19
  20. 20. Realidades – Realidade Aumentada uma interfacebaseada na sobreposição de informações virtuais geradas por computador (envolvendo imagens estáticas e dinâmicas, sons espaciais e sensações hápticas) com o ambiente físico do usuário, percebida através de dispositivos tecnológicos e usando as interações naturais do usuário, no mundo físico. Claudio Kirner SOURCE: Adapted from ESA (2009) and Capua (2008) 08:38 20 fb.com/RVA.BR
  21. 21. Christopher Vision Informação virtual Interação Natural dispositivos tecnológicos 08:38 21 fb.com/RVA.BR
  22. 22. Realidades – Realidade Cruzada é um ambiente de realidade misturada ubíqua, que vem da fusão de uma rede de sensores e atuadores (que coletam e enviam dados relacionados ao mundo real) com mundos virtuais compartilhados, usando a interface da realidade aumentada. Claudio Kirner Introdução 08:38fb.com/RVA.BR 22
  23. 23. Kirner’s Diagram – elementos Source: (KIRNER et al., 2012) Lego Cave 08:38fb.com/RVA.BR 23
  24. 24. Realidade Cruzada Objetos reais Sensores e Atuadores Realidade Aumentada OCR NOCR NOCR Introdução 08:38fb.com/RVA.BR 24
  25. 25. HIT - ROADMAP CR AI HI AR IoT HR KMatsuda 08:38fb.com/RVA.BR 25
  26. 26. [ ] Hololens • Talvez o primeiro hardware de RA, com sobreposição, que entra com força no mercado. • Google Glass tentou, mas na maioria dos apps não tinha sobreposição intrínseca. • Vídeo 1 08:38fb.com/RVA.BR 26
  27. 27. Qual o motivo de RA ainda não ter pego em atividades de engenharia? HWs de interação? HWs de visualização? Frameworks de rastreio SWs Frameworks geo-localizados Frameworks de interação 08:38fb.com/RVA.BR 27
  28. 28. Um dos motivos ao nosso ver é: • Dificuldade de criação e manipulação de uma interface de RA a medida que é utilizada. • Poderíamos então pensar em uma estratégia, de criação de uma interface física e indicar sua camada virtual a medida que é necessário (on-demand) e a função desejada. • Esses minicurso essencialmente é para mostrar uma opção de criação de interface em RA on demand. • “Solução simplificada: openFrameworks + visão computacional.” 08:38fb.com/RVA.BR 28
  29. 29. OPENFRAMEWORKS 08:38fb.com/RVA.BR 29
  30. 30. Processing Adobe Flash Unity Cinder openFrameworks 08:38fb.com/RVA.BR 30
  31. 31. openframeworks.cc • Vídeo oF1....media_videos7_openFrameworks1.mp4 • Vídeo oF2....media_videos7_openFrameworks2.mp4 08:38fb.com/RVA.BR 31
  32. 32. oF • Criado para artistase designers • Desenvolvido por: Zach Liberman, Theo Watson, Artuno Castro e Chris O’Shea •Proposta: Arrumar a falta de comunicação entre diversas bibliotecas em C++, e permitir portabilidade. • Escrita em C++ • Licença: MIT (educacional e venda) • Usar quando: • O projeto renderiza muitos gráficos 3D, e/ou; • Utilizar muita visão computacional, e/ou; • Controlar equipamentos, como, por exemplo: • o ARDUINO. 08:38fb.com/RVA.BR 32
  33. 33. 33 08:38fb.com/RVA.BR
  34. 34. C++ Portável!!!! 34 08:38fb.com/RVA.BR
  35. 35. Página Principal – openframeworks.cc 08:38fb.com/RVA.BR 35
  36. 36. Libs no pacote padrão • OpenGL, GLEW, GLUT, libtess2 e cairo para gráficos. • rtAudio, PortAudio ou FMOD e Kiss FFT para entrada, saída e análise de áudio. • FreeType para fontes. • FreeImage para salvar e carregar imagens. • Quicktime e videoInput para playback e aquisição de vídeo. • Poco, que contém uma variedade de utilidades. 08:38fb.com/RVA.BR 36
  37. 37. Addons da comunidade: ofxaddons.com 08:38fb.com/RVA.BR 37
  38. 38. OSX, Linux, Windows, iOS, Android, Linux ARM 08:38fb.com/RVA.BR 38
  39. 39. ERA TROGLODITA (C++) • Graduação (2010): • ARToolKit • PTAMM • Bolsista DTI (2011): • basAR ERA DO FOGO (C++/oF) • Mestrado (2012): • Doutorado (2014): 08:38fb.com/RVA.BR 39
  40. 40. MDE (Model Driven Engineering) MBSE (ModelBased SystemEngineering) • MDE é um conjunto de práticas de engenharia, baseadas em ferramentas que utilizam ao mesmo tempo meta- modelagem e transformações de modelos para atingirem automaticamente objetivos em produção, manutenção ou operação de sistemas intensivos em software. 40 Motivador - Matlab 08:38fb.com/RVA.BR
  41. 41. Três tipos principais de aplicações MDE MDE Geração automática Descoberta do Modelo Interoperabilidade de sistemas 41 Um modelo pode ser transformado em outro modelo. Um meta-modelo é um conjunto de conceitos e relações que o modelo pode realizar. “Filtro” de possibilidade. Uma representação gera um conjunto de elementos. 08:38fb.com/RVA.BR
  42. 42. MDE Natural Env. 08:38fb.com/RVA.BR 42
  43. 43. • Introdução à utilização de openFrameworks para o desenvolvimento de aplicações de RVA Link • Construção de aplicações de Realidade Cruzada Projetiva utilizando openFrameworks e ARDUINO Link • Utilização de Realidade Aumentada, com marcadores(ARToolKitPlus) e outros (utilizando openCV), para controle e inspeção de hardware, utilizando a interface ARDUINO. Link 08:38fb.com/RVA.BR 43
  44. 44. SVR2013 - Resultados 44 08:38fb.com/RVA.BR
  45. 45. SVR2014 - Resultados 08:38 45 fb.com/RVA.BR
  46. 46. WRVA2014 - Resultados 08:38fb.com/RVA.BR 46
  47. 47. PRIMEIRO PROGRAMA EM OF Vou pular, coloquei aqui para ficar + completo 08:38fb.com/RVA.BR 47
  48. 48. Onde encontrar? 08:38fb.com/RVA.BR 48
  49. 49. Level Easy: Gerador Automático 49 08:38fb.com/RVA.BR
  50. 50. Escolhendo expansões 50 DocoreoF Dacomunidade 08:38fb.com/RVA.BR
  51. 51. Estrutura do projeto 08:38fb.com/RVA.BR 51
  52. 52. Exemplo básico 08:38fb.com/RVA.BR 52 // ofApp.cpp void ofApp::setup(){ mensagem = "Hello SVR2015!!!"; raio = 0; } void ofApp::draw(){ ofEnableAlphaBlending(); ofSetColor(ofColor::blue,128); ofCircle(x_i,y_i,raio); ofSetColor(ofColor::red); ofDrawBitmapString(mensagem,mouseX,mouseY); } // ofApp.cpp void ofApp::mouseDragged(int x, int y, int button){ raio = ofDist(x_i,y_i,x,y); } void ofApp::mousePressed(int x, int y, int button){ x_i = x; y_i = y; } void ofApp::mouseReleased(int x, int y, int button){ raio = ofDist(x_i,y_i,x,y); } // ofApp.h ... string mensagem; int x_i,y_i; float raio; ...
  53. 53. ARDUINO O que é? Onde vivem? Existe? Hoje no Glob.. Fritzing, Arduino 1.0, Firmata, exemplo openFrameworks 08:38fb.com/RVA.BR 53
  54. 54. O que tem no ARDUINO? 08:38 54 fb.com/RVA.BR
  55. 55. Outras versões 08:38 55 fb.com/RVA.BR
  56. 56. Shields 08:38 56 fb.com/RVA.BR
  57. 57. FIRMATA Literatura indica FIRMATA: http://firmata.org/wiki/Download 08:38 57 fb.com/RVA.BR
  58. 58. O que a FIRMATA faz!? • Transforma o ARDUINO numa interface de controle, podendo ser modificado por um host. • Quais as vantagens? • O host controla a execução! • O host tem mais memória. • O host resolve as lógicas de controle muito mais rápido. • Desvantagens?! • Tem que ficar atrelado ao host! 08:38 58 fb.com/RVA.BR
  59. 59. Obs.: Mudança da nomenclatura dos pinos após Firmata 2.3 (Arduino 1.0) Tomar cuidado na hora de desenvolver!!!!!!!!!! 08:38fb.com/RVA.BR 59
  60. 60. Instalando a Firmata no Arduino • Faça download do Arduino 1.0.6 http://arduino.cc/en/ Main/Software • Abra o sketch do Firmata Standard. • Transfira para a board. 08:38fb.com/RVA.BR 60 http://arduino.cc/en/reference/firmata
  61. 61. “esquemático” 08:38 61 fb.com/RVA.BR • #crashcourse fritzing • http://fritzing.org/home/
  62. 62. Arduino e openFrameworks 08:38fb.com/RVA.BR 62
  63. 63. Métodos para conectar com o ARDUINO  connect()  disconnect()  getAnalog()  getAnalogPinReporting()  getDigital()  getDigitalPinMode()  getPwm()  getString()  isArduinoReady()  isInitialized()  sendAnalogPinReporting()  sendByte()  sendDigital()  sendDigitalPinMode()  sendPwm()  sendReset()  sendString()  setUseDelay()  update() 08:38 63 fb.com/RVA.BR
  64. 64. Código no openFrameworks • Exploração do exemplo: communicationfirmataExample 08:38fb.com/RVA.BR 64
  65. 65. Fluxograma básico 08:38fb.com/RVA.BR 65 SETUP Habilita callback de Arduino Alive Arduino Responde Evento Alive Configura Arduino Loop de execução – sem Arduino Enviar comandos pro Arduino Recebeu um evento Digital Recebeu um evento Analógico Loop de execução – Arduino Update
  66. 66. Código 08:38fb.com/RVA.BR 66 //ofApp.h #pragma once #include "ofMain.h" class ofApp : public ofBaseApp{ public: … ofArduino ard; bool bSetupArduino; private: void setupArduino(const int & version); void digitalPinChanged(const int & pinNum); void analogPinChanged(const int & pinNum); void updateArduino(); }; //ofApp.cpp void ofApp::setup(){ ... ard.connect("COM3", 57600); //conecta com arduino ofAddListener(ard.EInitialized, this, &ofApp::setupArduino); bSetupArduino= false;// flag arduino ok  } void ofApp::setupArduino(const int & version) { ofRemoveListener(ard.EInitialized, this, &ofApp::setupArduino); bSetupArduino = true; // agora pode usar o arduino. ard.sendDigitalPinMode(2, ARD_INPUT); //pino entrada digital ard.sendAnalogPinReporting(0, ARD_ANALOG); // pino entrada analógica ard.sendDigitalPinMode(13, ARD_OUTPUT); // configura pino saída digital ard.sendDigitalPinMode(11, ARD_PWM); // configura pino saída PWM ard.sendServoAttach(9); // diz que o pino tem um servo. ofAddListener(ard.EDigitalPinChanged, this, &ofApp::digitalPinChanged); //callback para eventos de pino digital. ofAddListener(ard.EAnalogPinChanged, this, &ofApp::analogPinChanged); //callback para eventos de pino analógico } void ofApp::updateArduino(){ ard.update(); // verifica se algo mudou no Arduino - obrigatório if (bSetupArduino) { //envia o que for para o Arduino. ard.sendPwm(11, (int)(128 + 128 * sin(ofGetElapsedTimef()))); // pwm... } } //ofApp.cpp void ofApp::digitalPinChanged(const int & pinNum) { // trata o pino digital - ard.getDigital(pinNum) } void ofApp::analogPinChanged(const int & pinNum) { // trata o pino analógico - ard.getAnalog(pinNum) } //outros comandos ard.sendServo(9, 180, false); ard.sendDigital(8, ARD_HIGH);
  67. 67. ESTUDO DE CASOS: 08:38fb.com/RVA.BR 67
  68. 68. Casos • 0.a. O que vamos fazer: • 1. Detecção de infraestrutura (contornos) • 2. Detecção de atuador (diferença de imagens) • 3. Interação mão / virtual / Arduino • 4. Rastreio dos controles. (contornos) • Real (Drawn) e Virtual Matching 08:38fb.com/RVA.BR 68
  69. 69. 0.a. O que vamos fazer:
  70. 70. Ambiente reativo à altura da areia Ambiente reativo ao comportamento dos pontos (soldados) 08:38fb.com/RVA.BR 70
  71. 71. Conceito de ambiente dividido em pontos e camadas 08:38fb.com/RVA.BR 71
  72. 72. Diagrama de etapas 08:38fb.com/RVA.BR 72
  73. 73. O que vamos usar para o exemplo 08:38fb.com/RVA.BR 73
  74. 74. Só use mais hardware quando realmente precisar. 08:38fb.com/RVA.BR 74
  75. 75. DETECTING INFRASTRUCTURE Encontrando uma folha de papel para servir de referência para a montagem dos elementos de interação. 08:38fb.com/RVA.BR 75
  76. 76. Detectar a infraestrutura Capturar Imagem Procurar “coisas” brancas Identificar polígono • Maior de todos? é um retângulo? Encontrei a infraestrutura Retirar a imagem da área ide interação 08:38fb.com/RVA.BR 76
  77. 77. Exemplo: Rastreio de Marcador 08:38fb.com/RVA.BR 77
  78. 78. USANDO O OPENCV Cores, blobs e exemplos 08:38fb.com/RVA.BR 78
  79. 79. Cores RGB-A (red, green, blue)-alfa HSV (hue (cor), saturation, value) 08:38 79 fb.com/RVA.BR
  80. 80. Blobs • Método de busca de características. • Blobs compartilham propriedades constantes que podem ser “percebidas” na imagem. 08:38 80 fb.com/RVA.BR
  81. 81. Construção dos artefatos : Rastreio Cores 08:38 81 fb.com/RVA.BR
  82. 82. Bonus: Projection Mapping 08:38fb.com/RVA.BR 82 PM PM
  83. 83. Usos • Table-tops • Projeções em paredes 08:38 83 fb.com/RVA.BR Sensetable L.A.S.E.R. Tag Climbing OASIS
  84. 84. Continuando .... Usando o addon: ofxCv de Kyle McDonald https://github.com/kylemcdonald/ofxCv 08:38fb.com/RVA.BR 84
  85. 85. Tipo: ofxCv::ContourFinder • Tipo/função que procura blobs numa imagem. • Retorna os blobs e características: • Posição • Contorno • Centroide, média centro, pontos das bordas, menor retângulo contornável, menor elipse, etc etc etc... 08:38fb.com/RVA.BR 85
  86. 86. Project Generator addons 08:38fb.com/RVA.BR 86
  87. 87. // Camera: ofVideoGrabber cam; // Video Tracking source int camHeight; int camWidth; ofImage unwarped; // RAW image from camera // Descobridor de papel ofxCv::ContourFinder contourFinder; int thresholdCV; ofPolyline contour; ofImage warpedPaper; bool foundInfra; // ## Função para retornar tipo de forma geométrica private: string findForm(const ofPolyline &poly); template <class T> string findForm(const T &poly){ return findForm(ofxCv::toOf(poly)); } }; Câmera Procurador de papel 08:38fb.com/RVA.BR 87
  88. 88. Identificar Formas Convexas • Entrada: número de vértices • 3 vértices = TRIANGULO • 4 vértices e cos +/- 0 = RETÂNGULO • 5 vértices e cos +/- 0.3 = PENTÁGONO • 6 vértices e cos +/- 0.5 = HEXÁGONO • > 6 Círculo • http://opencv-code.com/tutorials/detecting-simple-shapes-in-an-image/ • https://github.com/bsdnoobz/opencv-code/blob/master/shape-detect.cpp 08:38fb.com/RVA.BR 88
  89. 89. string ofApp::findForm(const ofPolyline &poly){ vector<ofPoint> corners = poly.getVertices(); // pega todos os vértices if ( corners.size() == 3) return "TRIANGLE"; if ( corners.size() >= 4 && corners.size() <= 6){ // de 4 a 6 vertices int vtc = corners.size(); vector<double> cos; for( int j = 2; j < vtc+1; j++) // mandrakaria para organizar cosenos cos.push_back(angle(corners[j%vtc], corners[j-2], corners[j-1])); sort(cos.begin(),cos.end()); double minCos = cos.front(); double maxCos = cos.back(); if( vtc == 4 && minCos >= -0.1 && maxCos <= 0.3) { cv::Rect r = cv::boundingRect(toCv(poly)); double ratio = std::abs(1 - (double)r.width / r.height); return (ratio <= 0.02) ? "SQUARE" : "RECTANGLE"; } if( vtc == 5 && minCos >= -0.34 && maxCos <= -0.27) return "PENTAGON"; if( vtc == 6 && minCos >= -0.55 && maxCos <= 0.45) return "HEXAGON"; } else { // testar se circulo } return "NO_MATCH";} 08:38fb.com/RVA.BR 89
  90. 90. static double angle(ofPoint pt1, ofPoint pt2, ofPoint pt0) { double dx1 = pt1.x - pt0.x; double dy1 = pt1.y - pt0.y; double dx2 = pt2.x - pt0.x; double dy2 = pt2.y - pt0.y; return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); } 08:38fb.com/RVA.BR 90
  91. 91. void ofApp::setup(){ // Parte 2 - Código do Exemplo ofLogNotice("[PAPER DETECTOR]") << " Configure CV "; contourFinder.setMinAreaRadius(10); // configura menor área . contourFinder.setMaxAreaRadius(200); // configura maior área thresholdCV = 100; // inicializa o nível da camera. //contourFinder.setTargetColor(targetColor, trackingColorMode); // configura cor / padrão contourFinder.setThreshold(thresholdCV); // configura nível ofLogNotice("[PAPER DETECTOR]") << " Configure Camera "; camWidth = 640; camHeight = 480; cam.initGrabber(camWidth,camHeight); cam.listDevices(); unwarped.allocate(camWidth, camHeight, OF_IMAGE_COLOR); // // ALLOCATE RAW IMAGE warpedPaper.allocate(camWidth,camHeight,OF_IMAGE_COLOR); } 08:38fb.com/RVA.BR 91
  92. 92. void ofApp::update(){ cam.update(); float area; if(cam.isFrameNew()){ //ofLogNotice("[PAPER DETECTOR]") << "New Frame"; vector<cv::Point> maxQuad;//maior quadrado na imagem = folha de papel. float maxArea = -numeric_limits<float>::infinity();//escolhe pela maior área. contourFinder.findContours(cam); // realiza a procura por folhas brancas em um fundo preto int n = contourFinder.size(); for(int i = 0; i < n; i++){ //ofLogNotice("[PAPER DETECTOR]") << "update: " + ofToString(i); ofPolyline minAreRect = toOf(contourFinder.getMinAreaRect(i)); vector<cv::Point> quad = contourFinder.getFitQuad(i); area = contourFinder.getContourArea(i); //encontrar o maior quadrado na imagem = folha de papel. if (area > maxArea) { //ofLogNotice("[PAPER DETECTOR]") << "1. " + ofToString(area) + " - " + ofToString(maxArea); maxArea = area; maxQuad = quad; } } 08:38fb.com/RVA.BR 92
  93. 93. // teste se foi encontrado algo parecido com um retângulo. this->foundInfra = false; if ( this->findForm(maxQuad) == "RECTANGLE"){ this->foundInfra = true; // warp paper vector<Point2f> warpPoints; warpPoints.push_back(maxQuad[3]); // para organizar a ordem dos pontos. warpPoints.push_back(maxQuad[0]); warpPoints.push_back(maxQuad[1]); warpPoints.push_back(maxQuad[2]); //copy(maxQuad.begin(), maxQuad.end(), back_inserter(warpPoints)); unwarpPerspective(cam, unwarped, warpPoints); unwarped.update(); } //ofLogNotice("[PAPER DETECTOR]") << "2. " + ofToString(area) + " - " + ofToString(maxArea) + " - " + ofToString(this->foundInfra); } } 08:38fb.com/RVA.BR 93
  94. 94. void ofApp::draw(){ ofSetColor(ofColor::white); cam.draw(0,0); ofNoFill(); int n = contourFinder.size(); for(int i = 0; i < n; i++) { ofSetColor(ofColor::red); // smallest rectangle that fits the contour ofPolyline minAreRect = toOf(contourFinder.getMinAreaRect(i)); minAreRect.draw(); ofSetColor(yellowPrint); // convex hull of the contour ofPolyline convexHull = toOf(contourFinder.getConvexHull(i)); convexHull.draw(); ofSetColor(cyanPrint); vector<cv::Point> quad = contourFinder.getFitQuad(i); vector<cv::Point>::iterator it; for (it = quad.begin(); it != quad.end(); it++) ofCircle(toOf(*it),3); } ofSetColor(255); unwarped.draw(640, 0); if(this->foundInfra){ ofDrawBitmapStringHighlight("Found infra",10,ofGetHeight() - 80);} ofDrawBitmapStringHighlight(ofToString(this->thresholdCV),10,ofGetHeight() - 100); } 08:38fb.com/RVA.BR 94
  95. 95. Resultado Esperado 08:38fb.com/RVA.BR 95
  96. 96. WHERE IS MY HAND? DETECTING THE ACTUATOR Detectando a mão, caneta, ou qualquer outra coisa (medo) que você queira usar para fazer interação. 08:38fb.com/RVA.BR 96
  97. 97. Rastrear mão (apontador 2D) • Restrições (para facilitar) Fundo homogêneo Longe das quinas Uma mão só • Pseudo-código • Fazer diferença entra o fundo e o frame atual para encontrar a mão. • Com a diferença rastreia o blob. • Do blob calcula as quinas • Das quinas pega a mais distante do centroide e que não seja próximo das quinas ( braço). 08:38fb.com/RVA.BR 97
  98. 98. Lets code.... Babe!!!!  #include "ofMain.h" #include "ofxOpenCv.h" //Cabeçalho do OpenCV #include "ofxCv.h" class ofApp : public ofBaseApp{ ... int width, height, threshold; ofVideoGrabber vidGrabber; // Componente do oF que pega a câmera. ofxCvColorImage colorImage; // imagem capturada pela câmera ofxCvGrayscaleImage grayBg, grayImage, grayDiff;// bg, cinza, diferença bool bLearnBackground; ofxCv::TrackingColorMode trackingColorMode; ofxCv::ContourFinder contourFinder; ofColor targetColor; ofPoint apontador; ofPoint encontraPontoMaisDistante(); }; 08:38fb.com/RVA.BR 98
  99. 99. Tipo: ofPoint • ofPoint é um tipo muito utilizado no openFrameworks que faz as vezes de um ponto na área da janela. • Com ele podemos posicionar pontos na área da janela. • Essencialmente é um vetor X,Y,Z. Herda de ofVec3f • Possui propriedades sobrecarregadas de operação de vetores. 08:38fb.com/RVA.BR 99
  100. 100. Setup void ofApp::setup(){ width = 320; height = 240; vidGrabber.initGrabber(width, height); //abre câmera colorImage.allocate(width,height); //aloca memória para as imagens grayBg.allocate(width,height); grayImage.allocate(width,height); grayDiff.allocate(width,height); contourFinder.setMinAreaRadius(10); //configura rastreador contourFinder.setMaxAreaRadius(150); contourFinder.setTargetColor(ofColor::white, TRACK_COLOR_RGB); threshold = 50; bLearnBakground = true; } 08:38fb.com/RVA.BR 100
  101. 101. Comparando imagens 08:38fb.com/RVA.BR 101
  102. 102. Update void ofApp::update(){ vidGrabber.update(); // Pega frame da câmera if(vidGrabber.isFrameNew()){ // é um frame novo ??? colorImage.setFromPixels(vidGrabber.getPixels(),width,height); grayImage = colorImage; if (bLearnBackground == true){ grayBg = grayImage;// salva o fundo da tela - TO ROUBANDO MESMO! bLearnBackground = false;} grayDiff.absDiff(grayBg, grayImage); // fazer fundo x atual grayDiff.threshold(threshold); contourFinder.setThreshold(threshold); // procurar blobs no atual contourFinder.findContours(grayDiff); apontador = encontraPontoMaisDistante(); // procurar “dedo” } } 08:38fb.com/RVA.BR 102
  103. 103. Marcando dedos (pontos distantes) 08:38fb.com/RVA.BR 103
  104. 104. Ponto mais distante – p1 ofPoint ofApp::encontraPontoMaisDistante(){ int n = contourFinder.size(); //qtidade de blobs capturados ofPoint maisDistante ; //nosso ponto mais distante for(int i = 0; i < n; i++) { ofVec2f centroid = toOf(contourFinder.getCentroid(i)); //Centroide; ofPolyline convexHull = toOf(contourFinder.getConvexHull(i)); //quinas; vector<ofPoint> vertices = convexHull.getVertices(); // vetorDeQuinas vector<ofPoint>::iterator itVec; // para percorrer as quinas. maisDistante = (*vertices.begin()); float tamMaisDistante = centroid.distanceSquared(maisDistante); float distanciaAtual = 0; 08:38fb.com/RVA.BR 104
  105. 105. Ponto mais distante – p2 for(itVec = vertices.begin(); itVec != vertices.end(); itVec++){ //encontrar ponto mais distante do dedo --> eliminar as bordas if( ((*itVec).x > 40) && ((*itVec).x < width - 40) && ((*itVec).y > 40) && ((*itVec).y < height - 40)){ //elimina bordas distanciaAtual = centroid.distanceSquared((*itVec)); if(distanciaAtual > tamMaisDistante){ //maior “simple as possible” maisDistante = (*itVec); tamMaisDistante = distanciaAtual; } } } } return maisDistante; } 08:38fb.com/RVA.BR 105
  106. 106. Draw void ofApp::draw(){ ofSetColor(255); grayImage.draw(0, 0); // desenha câmera ofTranslate(320, 0); grayDiff.draw(0, 0); // desenha threshold ofTranslate(-320,240); contourFinder.draw(); //desenha contorno encontrado ofSetColor(ofColor::hotPink); ofDrawBitmapString("openCV Threshold: " + ofToString(threshold),50,50); ofTranslate(0,-240); ofFill(); ofSetColor(ofColor::green); ofCircle(apontador,5); //desenha bola verde no “dedo” } 08:38fb.com/RVA.BR 106
  107. 107. Resultado desejado: 08:38fb.com/RVA.BR 107
  108. 108. PLAYING IN THE AIR! Interagindo em elementos virtuais com a mão. 08:38fb.com/RVA.BR 108
  109. 109. Definindo um conjunto de ações • Assunto: Controlar um Arduino  • Ações: • Acender e Apagar um LED via Arduino, com replicação virtual, via botão físico e botão virtual. • Controlar um servo motor a partir de uma barra virtual. Dica: Esse é um bom algoritmo para fazer o debounce do toque: http://drmarty.blogspot.com.br/2009/05/best-switch-debounce-routine-ever.html 08:38fb.com/RVA.BR 109
  110. 110. Espalhando controles virtuais pela área capturada pela câmera • 1º Projeto de Interface (livre em toda a área) “É você Google Glass? É voce Hololens?” (Clotilde, 1985) 08:38fb.com/RVA.BR 110
  111. 111. Tipo: ofRectangle • Tipo que define um retângulo na tela. • Retângulos são muito usados para definir áreas de toque. (Forma mais simples) • O tipo ofRectangle possui: • X,Y,(Z) do canto superior esquerdo (Referência) • Height, Width • Operadores sobrecarregados • Varias funções de posicionamento • Adição, crescimento para englobar outros, etc etc etc. 08:38fb.com/RVA.BR 111
  112. 112. Some code... (testartoques?inside()) ofRectangle controleServo; ofRectangle chaveOff; ofRectangle chaveOn; ofPoint LEDIndicativo; ofColor ledColor; bool ledStatus; // Configurar posição dos elementos da interface controleServo.set(30,85,40,140); chaveOff.set(197,160,40,40); chaveOn.set(237,160,40,40); LEDIndicativo.set(160,50); if( this->controleServo.inside(dedo) ) { // trata para controle doservo} if( this->chaveOn.inside(dedo)) { // trata evento do botão On} if( this->chaveOff.inside(dedo)) { // trata evento do botão Off} ofApp.h ofApp.cpp – setup() ofApp.cpp – update() 08:38fb.com/RVA.BR 112
  113. 113. Resultado desejado 08:38fb.com/RVA.BR 113
  114. 114. Adicionando comandos e leitura do Arduino // Setup Arduino() ard.sendDigitalPinMode(2, ARD_INPUT); // led do exemplo ard.sendDigitalPinMode(11, ARD_OUTPUT); // botão ard.sendServoAttach(9); // servo ofAddListener(ard.EDigitalPinChanged, this, &ofApp::digitalPinChanged); void ofApp::digitalPinChanged(const int & pinNum) { this->ledStatus = ard.getDigital(pinNum); if ( this->ledStatus == true){ ard.sendDigital(11,ARD_HIGH); } else { ard.sendDigital(11,ARD_LOW); } } 08:38fb.com/RVA.BR 114
  115. 115. bool ofApp::updateInterface(ofPoint dedo){ if( this->controleServo.inside(dedo) ) { // trata evento com servo // |controleServo.y ----- dedo.y ---- controleServo.y + controleServo.height| // |0 --------------------- y --------------------------- 180 | positionServo = (int) (dedo.y - controleServo.y)*180/controleServo.height; ard.sendServo(9, positionServo, false); } if( this->chaveOn.inside(dedo)) { // trata evento com botão On ledStatus = 1; ard.sendDigital(11,ARD_HIGH); // envia comando pro arduino } if( this->chaveOff.inside(dedo)) { // trata evento com botão Off ledStatus = 0; ard.sendDigital(11,ARD_LOW); //envia comando para o arduino } // pega dado do status do led this->ledStatus == 1 ? this->ledColor = ofColor::green : this->ledColor = ofColor::white; return true; } 08:38fb.com/RVA.BR 115
  116. 116. TRACKING PHYSICAL CONTROLS. THINGS ARE GETING REAL Rastreando controles desenhados na infraestrutura 08:38fb.com/RVA.BR 116
  117. 117. *Versão projetada 08:38fb.com/RVA.BR 117
  118. 118. Pseudo Código • Encontrada a infraestrutura: • Update: 1. Processar imagem 2. Procurar controles 1. Procurar tipo Slide 2. Procurar tipo Switch 3. Procurar tipo Button 3. Tendo os controles 1. Associar um controle a uma função predefinida de uma paleta de controles • Draw: 1. Desenhar paleta de funções num canto da infraestrutura 2. Desenhar controles encontrados (Forma e status) 1. Ajustar ponto de vista!!! (mesmo usando vista superior, em caso de projeção é necessário corrigir, pois câmera e projetor não estão no mesmo ponto) 08:38fb.com/RVA.BR 118
  119. 119. Processamento de Imagem Infra 08:38fb.com/RVA.BR 119
  120. 120. Etapas do processamento 2. Canny 3. Dilate 4. Erode 6. contourFinder infra 08:38fb.com/RVA.BR 120
  121. 121. No “ofApp.h” // Controles ofxCv::ContourFindercontrolFinder; booldoControlDetection; // auxiliares para forçar as imagens: cv::Mat grayImg; cv::Mat canny; cv::Mat eroded; cv::Mat dilated; cv::Mat edgesInput; cv::Mat edges; int BORDER; float ALPHA; vector<Controle> listaDeControles; voidtoogleControlDetection() { doControlDetection == true ? doControlDetection = false : doControlDetection = true; }; void encontraControles(); void processaInteracao(); void desenhaControles(); 08:38fb.com/RVA.BR 121
  122. 122. Processamento da imagem void ofApp::encontraControles(){ Mat img = ofxCv::toCv(this->unwarped); // Get the image in the right format and run edge detection - cheat - tricks ofxCv::convertColor(img, grayImg, CV_RGB2GRAY); //converte a imagem para cinza cv::Canny(grayImg, edgesInput, 160, 180, 3); // extrapola as bordas - edge map canny = edgesInput; cv::dilate(edgesInput, edgesInput, Mat::ones(2, 2, CV_8U), cv::Point(-1, -1), 7); //dilata as bordas dilated = edgesInput; cv::erode(edgesInput, edgesInput, Mat::ones(2, 2, CV_8U), cv::Point(-1, -1), 5); // erode as bordas eroded = edgesInput; const cv::Rect &roi = cv::Rect(BORDER, BORDER, edgesInput.cols - 2*BORDER, edgesInput.rows - 2*BORDER); edgesInput(roi).copyTo(edges); // Find contours in the edge detected image controlFinder.findContours(edges); //... continues } 08:38fb.com/RVA.BR 122
  123. 123. Procurar Controles 08:38fb.com/RVA.BR 123
  124. 124. Tipos de Controles: Switch – Posição 0 ou 1, memoriza a função Button – Posição 0 ou 1, instantâneo, funciona enquanto clicado, depois perde o valor Slide - Valor variável entre um máx. e um mín. 08:38fb.com/RVA.BR 124
  125. 125. Identificação dos tipos de controles 08:38fb.com/RVA.BR 125
  126. 126. Estrutura de dados genérica (super-hiper-mega simplificada) enum controlType{ CT_SWITCH, CT_BUTTON, CT_SLIDE }; class Controle { public: int id; controlType type; int value; int max; int min; //Para desenhar: ofPoint pos; ofRectangle posRect; float radius; float angle; void draw(){}; //para preencher os campos void fillSlider( cv::RotatedRect rotRect){} void fillSwitch( cv::RotatedRect rotRect){}; void fillButton( cv::Point center, float radius){}; bool interact(ofPoint dedo); }; Ideal é que sejam feitas classes e polimorfismo de tudo. ofxProjAR R_Infra* xPAR_Actuator* r :ofxPAR_ControlManager xPAR_State* r<ofxPAR_State*> ) :void () :void :void ate) :bool ) :ofxPAR_State* ofxPAR_Infra + cam :ofVideoGrabber + camHeight :int + camWidth :int + unwarped :ofImage + showVideoFeed :bool + foundInfra :bool + projectorPoints :vector<cv::Point2f> + toProjectorMatrix :cv::Mat + alignmentComplete :bool + projWidth :int + projHeight :int # name :string + ofxPAR_Infra() + ~ofxPAR_Infra() + detect() :void + draw() :void + update() :void + setup() :void + getTransformation(int, int) :cv::Mat + getContours() :ofPolyline + unwarpPoint(ofPoint&, int, int) :ofPoint + getCamera() :ofVideoGrabber + setCamera(ofVideoGrabber) :void + setCamera(int, int) :void + getRawUnwarped() :ofImage + toogleVideoFeed() :void + isInfraFound() :bool + addCalibrationPoints(int, int) :void + resetCalibration() :void + doCalibration() :void + drawProjectionLimits() :void # computeProjectorAlignment() :void # loadProjectorAlignment() :bool # saveProjectorAlignment() :bool # resetProjectorAlignment() :void ofxPAR_Infra_PaperDetector # trackingColorMode :ofxCv::TrackingColorMode # contourFinder :ofxCv::ContourFinder # targetColor :ofColor # thresholdCV :int # contour :ofPolyline # paperImage :cv::Mat # paper :vector<cv::Point> # adaptedToScreenSize :vector<cv::Point> + ofxPAR_Infra_PaperDetector() + ~ofxPAR_Infra_PaperDetector() + draw() :void + detect() :void + calibrate() :void + update() :void + setup() :void xPAR_ControlManager etection :bool Color {readOnly} Color {readOnly} Cv::ContourFinder v::Mat Mat :Mat :Mat :cv::Mat Mat :vector<ofxPAR_Control *> int :ofPoint nt at ntrolManager() ontrolManager() d d orInput(float, float, float, float) :void :void Mat) :void rolDetection() :void raction(ofPoint&) :void ls() :void () :void ols() :void e_t) :bool e_t) :bool e_t) :bool ofxPAR_Control # id :int # name :string # value :int # color :ofColor # controlType :ControlType # selected :bool + ofxPAR_Control() + ~ofxPAR_Control() + setId(int) :void + draw() :void + setColor(ofColor&) :void + contains(float, float) :bool + contains(ofPoint&) :bool + onInteraction(float, float) :bool + onInteraction(ofPoint&) :bool + setSelection(bool) :void + isSelected() :bool + getValue() :int ofxPAR_C_Button - cx :float - cy :float - radius :float - active :bool - entered :bool + ofxPAR_C_Button() + ~ofxPAR_C_Button() + ofxPAR_C_Button(float, float, float) + draw() :void + contains(float, float) :bool + onInteraction(float, float) :bool + operator==(ofxPAR_C_Button&) :bool + operator!=(ofxPAR_C_Button&) :bool ofxPAR_C_Slider - value :float + ofxPAR_C_Slider() + ~ofxPAR_C_Slider() + ofxPAR_C_Slider(cv::RotatedRect&) + draw() :void + onInteraction(float, float) :bool ofxPAR_C_Switch - active :bool + ofxPAR_C_Switch() + ~ofxPAR_C_Switch() + ofxPAR_C_Switch(cv::RotatedRect&) + draw() :void + onInteraction(float, float) :bool ofxPAR_State stateType :AppState name :string app :ofxProjAR* ofxPAR_State() ~ofxPAR_State() draw() :void update() :void InfraSetup ofxPAR_State_Play ofxPAR_Control_Rectangular # angle :float # rect :ofRectangle + ofxPAR_Control_Rectangular() + ~ofxPAR_Control_Rectangular() + ofxPAR_Control_Rectangular(cv::RotatedRect&) + draw() :void + contains(float, float) :bool + operator==(ofxPAR_Control_Rectangular&) :bool + operator!=(ofxPAR_Control_Rectangular&) :bool # alignPoint(float, float) :ofVec2f app 08:38fb.com/RVA.BR 126
  127. 127. Tipo: vector (de classes) • Vector é uma estrutura para armazenar sequencialmente. • No C++ vários tipos de estruturas de dados foram definidas usando containers genéricos. (STL) vector<Controle> listaDeControles; • Adição: Controle a; listaDeControles.push_back(a); • Remoção: listaDeControles.erase( listaDeControles.begin() + x); • Percorrer: vector<Controle>::iterator it = listaDeControles.begin(); for(; it != listaDeControles.end(); it++){ it->id; } // se vetor de ponteiros (*it)-> http://www.openframeworks.cc/tutorials/c++%20concepts/001_stl_vectors_basic.html vector<Controle*> listaDeControles; 08:38fb.com/RVA.BR 127
  128. 128. //... Continuing - void ofApp::encontraControles() listaDeControles.clear(); int n = controlFinder.size(); for(int i = 0; i< n; i++){ if (isButton(i)) { float radius; cv::Point center = controlFinder.getMinEnclosingCircle(i, radius); Controle *b = new Controle(); b->id = i; b->fillButton(center, radius); listaDeControles.push_back(b); } else if (isSlider(i)) { cv::RotatedRect rect = controlFinder.getMinAreaRect(i); Controle *s = new Controle(); s->id = i; s->fillSlider(rect); listaDeControles.push_back(s); } else if (isSwitch(i)) { cv::RotatedRect rect = controlFinder.getMinAreaRect(i); Controle *s = new Controle(); s->id = 1; s->fillSwitch(rect); listaDeControles.push_back(s); } } } 08:38fb.com/RVA.BR 128
  129. 129. //--------------------------------------------------------- bool ofApp::isButton(int i) { float radius; controlFinder.getMinEnclosingCircle(i, radius); float circleArea = PI * radius * radius; double contourArea = controlFinder.getContourArea(i); return abs(1.0 - circleArea / contourArea) < 0.3; } //--------------------------------------------------------- bool ofApp::isSlider(int i) { float radius; ofVec2f center = ofxCv::toOf(controlFinder.getMinEnclosingCircle(i, radius)); float circleArea = PI * radius * radius; double contourArea = controlFinder.getContourArea(i); return circleArea / contourArea > 12; } //--------------------------------------------------------- bool ofApp::isSwitch(int i) { RotatedRect rr = controlFinder.getMinAreaRect(i); float rectArea = rr.size.width * rr.size.height; double contourArea = controlFinder.getContourArea(i); return abs(1.0 - rectArea / contourArea) < 0.25 && abs(1.0 - (float) rr.size.width / rr.size.height) > 0.1; } 08:38fb.com/RVA.BR 129
  130. 130. Criaroscontroles-FYI void fillSlider( cv::RotatedRect rotRect){ this->type = controlType::CT_SLIDE; const cv::Size &s = rotRect.size; bool switchHeight = s.width < s.height; if (switchHeight) { this->posRect.setFromCenter(ofxCv::toOf(rotRect.center), s.height, s.width); angle = rotRect.angle + 90; } else { this->posRect.setFromCenter(ofxCv::toOf(rotRect.center), s.width, s.height); angle = rotRect.angle; } this->value = 0; }; void fillSwitch( cv::RotatedRect rotRect){ this->type = controlType::CT_SWITCH; const cv::Size &s = rotRect.size; bool switchHeight = s.width < s.height; if (switchHeight) { this->posRect.setFromCenter(ofxCv::toOf(rotRect.center), s.height, s.width); angle = rotRect.angle + 90; } else { this->posRect.setFromCenter(ofxCv::toOf(rotRect.center), s.width, s.height); angle = rotRect.angle; } this->value = 0; }; void fillButton( cv::Point center, float radius){ this->type = controlType::CT_BUTTON; this->pos.x = center.x; this->pos.y = center.y; this->radius = radius; this->value = 0; }; 08:38fb.com/RVA.BR 130
  131. 131. Draw do botão: case controlType::CT_BUTTON :{ ofPushMatrix(); ofSetColor(ofColor::green); ofSetLineWidth(5); if (this->value == 1) { ofFill(); } else { ofNoFill(); } ofCircle(this->pos, this->radius); ofPopMatrix(); break;} 08:38fb.com/RVA.BR 131
  132. 132. case controlType::CT_SWITCH:{ ofPushMatrix(); ofTranslate(this->posRect.getCenter()); ofRotate(this->angle); ofNoFill(); ofSetLineWidth(3); ofSetColor(ofColor::blue); ofRect(-this->posRect.width / 2, -this->posRect.height / 2, this- >posRect.width, this->posRect.height); ofLine(0, -this->posRect.height / 2, 0, this->posRect.height / 2); float x = (this->value ? 0 : -this->posRect.width / 2); ofLine(x, -this->posRect.height / 2, x + this->posRect.width / 2, this- >posRect.height / 2); ofLine(x + this->posRect.width / 2, -this->posRect.height / 2, x, this- >posRect.height / 2); ofPopMatrix(); break;} Draw da Chave: 08:38fb.com/RVA.BR 132
  133. 133. case controlType::CT_SLIDE:{ ofPushMatrix(); ofTranslate(this->posRect.getCenter()); ofRotate(this->angle); ofNoFill(); ofSetLineWidth(4); ofSetColor(ofColor::red); // Draw the main shape ofLine(-this->posRect.width / 2, 0, this->posRect.width / 2, 0); ofLine(-this->posRect.width / 2, -this->posRect.height / 2, -this->posRect.width / 2, this->posRect.height / 2); ofLine(this->posRect.width / 2, -this->posRect.height / 2, this->posRect.width / 2, this->posRect.height / 2); // Draw the tick marks ofSetLineWidth(2); for (size_t i = 1; i < 8; i++) { float dx = ((float) i / 8) * this->posRect.width; ofLine(-this->posRect.width / 2 + dx, -this->posRect.height / 3, -this->posRect.width / 2 + dx, this- >posRect.height / 3); } // Draw the value marker float xval = ((float)this->value/100) * this->posRect.width; float knobHeight = 5 * this->posRect.height / 4; float knobWidth = this->posRect.width / 8; // Fill the rectangle with black to erase the background ofPushStyle(); ofSetColor(0); ofFill(); ofRect(-this->posRect.width / 2 + xval - knobWidth / 2, -knobHeight / 2, knobWidth, knobHeight); ofPopStyle(); ofSetLineWidth(5); ofRect(-this->posRect.width / 2 + xval - knobWidth / 2, -knobHeight / 2, knobWidth, knobHeight); ofPopMatrix(); break;} Draw do Slider 08:38fb.com/RVA.BR 133
  134. 134. FINAL LAP: INTERAÇÃO COM OS CONTROLES 08:38fb.com/RVA.BR 134
  135. 135. Fixar os pontos de corte da figura!!!!!!!!!!!!!! 08:38fb.com/RVA.BR 135
  136. 136. Inside!? bool buttonContains(int x, int y){ return ofDistSquared((float)pos.x, (float)pos.y, (float)x, (float)y) < radius * radius; } bool rectContains(int x, int y){ return posRect.inside(x, y); } 08:38fb.com/RVA.BR 136
  137. 137. switch(type){ case controlType::CT_BUTTON : if (buttonContains(dedo.x, dedo.y)) { value == 1 ? value = 0 : value = 1; return true; } break; case controlType::CT_SWITCH : if(rectContains(dedo.x,dedo.y)) { bool right = dedo.x > posRect.getCenter().x; if ((bool)value != right) value = right; return true;} break; case controlType::CT_SLIDE : if(rectContains(dedo.x,dedo.y)){ value = (int) ((dedo.x - posRect.x)*100 / posRect.width); return true;} break; default: break; }; interaction 08:38fb.com/RVA.BR 137
  138. 138. Resultado Esperado 08:38fb.com/RVA.BR 138
  139. 139. WRAP-UP 08:38fb.com/RVA.BR 139 O QUE APRENDEMOS HOJE
  140. 140. O QUE ACONTECEU: class src «enumeratio... controlType CT_SWITCH CT_BUTTON CT_SLIDE Controle + id :int + type :controlType + value :int + max :int + min :int + pos :ofPoint + posRect :ofRectangle + radius :float + angle :float + fillSlider(rotRect :cv::RotatedRect) :void + fillSwitch(rotRect :cv::RotatedRect) :void + fillButton(center :cv::Point, radius :float) :void + draw() :void + buttonContains(x :int, y :int) :bool + rectContains(x :int, y :int) :bool + interact(dedo :ofPoint) :bool ofBaseApp ofApp + debugApp :bool + cam :ofVideoGrabber + camHeight :int + camWidth :int + original :ofImage + paperFinder :ofxCv::ContourFinder + warpedPaper :ofImage + verticesInfra :vector<Point2f> + foundInfra :bool + StopToGetInfraPosition :bool + controlFinder :ofxCv::ContourFinder + doControlDetection :bool + grayImg :cv::Mat + canny :cv::Mat + eroded :cv::Mat + dilated :cv::Mat + edgesInput :cv::Mat + edges :cv::Mat + BORDER :int + ALPHA :float + listaDeControles :vector<Controle*> + colorImage :ofxCvColorImage + grayBg :ofxCvGrayscaleImage + grayImage :ofxCvGrayscaleImage + grayDiff :ofxCvGrayscaleImage + bLearnBackground :bool + trackingColorMode :ofxCv::TrackingColorMode + handFinder :ofxCv::ContourFinder + targetColor :ofColor + apontador :ofPoint + setup() :void + update() :void + draw() :void + keyReleased(key :int) :void + trataInfraestrutura() :void + desenhaInfraestrutura(x :int, y :int) :void + encontraControles(source :ofImage) :void + isButton(i :int) :bool + isSwitch(i :int) :bool + isSlider(i :int) :bool + desenhaControles(x :int, y :int) :void + processaInteracao() :void + encontraPontoMaisDistante() :ofPoint + desenhaMao(x :int, y :int) :void + encontraMao(source :ofImage) :void + findForm(poly :ofPolyline&) :string + findForm(poly :T&) :string +type 08:38fb.com/RVA.BR 140
  141. 141. class Class Model ofBaseApp ofApp + par :ofxProjAR + setup() :void + update() :void + draw() :void + keyPressed(int) :void + keyReleased(int) :void + mouseMoved(int, int) :void + mouseDragged(int, int, int) :void + mousePressed(int, int, int) :void + mouseReleased(int, int, int) :void + windowResized(int, int) :void + dragEvent(ofDragInfo) :void + gotMessage(ofMessage) :void ofxProjAR + m_infra :ofxPAR_Infra* + m_actuator :ofxPAR_Actuator* + controlManager :ofxPAR_ControlManager + debug :bool - actualState :ofxPAR_State* - stateList :vector<ofxPAR_State*> + ofxProjAR() + ~ofxProjAR() + standardSetup() :void + standardUpdate() :void + standardDraw() :void + setState(AppState) :bool + getActualState() :ofxPAR_State* ofxPAR_Infra + cam :ofVideoGrabber + camHeight :int + camWidth :int + unwarped :ofImage + showVideoFeed :bool + foundInfra :bool + projectorPoints :vector<cv::Point2f> + toProjectorMatrix :cv::Mat + alignmentComplete :bool + projWidth :int + projHeight :int # name :string + ofxPAR_Infra() + ~ofxPAR_Infra() + detect() :void + draw() :void + update() :void + setup() :void + getTransformation(int, int) :cv::Mat + getContours() :ofPolyline + unwarpPoint(ofPoint&, int, int) :ofPoint + getCamera() :ofVideoGrabber + setCamera(ofVideoGrabber) :void + setCamera(int, int) :void + getRawUnwarped() :ofImage + toogleVideoFeed() :void + isInfraFound() :bool + addCalibrationPoints(int, int) :void + resetCalibration() :void + doCalibration() :void + drawProjectionLimits() :void # computeProjectorAlignment() :void # loadProjectorAlignment() :bool # saveProjectorAlignment() :bool # resetProjectorAlignment() :void ofxPAR_Infra_PaperDetector # trackingColorMode :ofxCv::TrackingColorMode # contourFinder :ofxCv::ContourFinder # targetColor :ofColor # thresholdCV :int # contour :ofPolyline # paperImage :cv::Mat # paper :vector<cv::Point> # adaptedToScreenSize :vector<cv::Point> + ofxPAR_Infra_PaperDetector() + ~ofxPAR_Infra_PaperDetector() + draw() :void + detect() :void + calibrate() :void + update() :void + setup() :void + getTransformation(int, int) :cv::Mat + getContours() :ofPolyline + unwarpPoint(ofPoint&, int, int) :ofPoint - configureCV() :void - drawPaperContour() :void - drawPaperContourIn(int, int) :void - unwarp(S&, D&) :void - unwarp(D&) :void - unwarpPointIntern(ofPoint&, int, int) :ofPoint ofxPAR_Actuator + topBackground :ofxCv::RunningBackground + foreground :cv::Mat + ofxPAR_Actuator() + ~ofxPAR_Actuator() + draw() :void + drawDetectorInput(float, float, float, float) :void + detect(T&, S&, ofPolyline&) :bool + detect(cv::Mat&, ofPolyline&) :bool + getActuatorPoint() :ofPoint + setActuatorThresold(int) :void ofxPAR_HandDetector - topFinder :ofxCv::ContourFinder - sideFinder :ofxCv::ContourFinder - topFilled :cv::Mat - contour :ofPolyline - fingers :vector<size_t> - fingerPoint :ofPoint - foundFingerInLast :bool - fingerThreshold :int - fAlpha :float - elem2x2 :cv::Mat - elem3x3 :cv::Mat - useCenter :cv::Point {readOnly} + ofxPAR_HandDetector() + ~ofxPAR_HandDetector() + draw() :void + drawDetectorInput(float, float, float, float) :void + detect(cv::Mat&, ofPolyline&) :bool + getActuatorPoint() :ofPoint + setActuatorThresold(int) :void - findFingers(ofPolyline&) :bool - getFingerPoint() :ofPoint ofxPAR_ControlManager + doControlDetection :bool + accent1 :ofColor {readOnly} + accent2 :ofColor {readOnly} + finder :ofxCv::ContourFinder + grayImg :cv::Mat + canny :cv::Mat + eroded :cv::Mat + dilated :cv::Mat + edgesInput :cv::Mat + edges :cv::Mat + controlList :vector<ofxPAR_Control *> + lastInputPoint :ofPoint + BORDER :int + ALPHA :float + ofxPAR_ControlManager() + ~ofxPAR_ControlManager() + setup() :void + reset() :void + drawDetectorInput(float, float, float, float) :void + detect(T&) :void + detect(cv::Mat) :void + toogleControlDetection() :void + processInteraction(ofPoint&) :void + drawControls() :void + drawDebug() :void + assignControls() :void + isButton(size_t) :bool + isSlider(size_t) :bool + isSwitch(size_t) :bool ofxPAR_Control # id :int # name :string # value :int # color :ofColor # controlType :ControlType # selected :bool + ofxPAR_Control() + ~ofxPAR_Control() + setId(int) :void + draw() :void + setColor(ofColor&) :void + contains(float, float) :bool + contains(ofPoint&) :bool + onInteraction(float, float) :bool + onInteraction(ofPoint&) :bool + setSelection(bool) :void + isSelected() :bool + getValue() :int ofxPAR_C_Button - cx :float - cy :float - radius :float - active :bool - entered :bool + ofxPAR_C_Button() + ~ofxPAR_C_Button() + ofxPAR_C_Button(float, float, float) + draw() :void + contains(float, float) :bool + onInteraction(float, float) :bool + operator==(ofxPAR_C_Button&) :bool + operator!=(ofxPAR_C_Button&) :bool ofxPAR_C_Slider - value :float + ofxPAR_C_Slider() + ~ofxPAR_C_Slider() + ofxPAR_C_Slider(cv::RotatedRect&) + draw() :void + onInteraction(float, float) :bool ofxPAR_C_Switch - active :bool + ofxPAR_C_Switch() + ~ofxPAR_C_Switch() + ofxPAR_C_Switch(cv::RotatedRect&) + draw() :void + onInteraction(float, float) :bool ofxPAR_State + stateType :AppState + name :string + app :ofxProjAR* + ofxPAR_State() + ~ofxPAR_State() + draw() :void + update() :void ofxPAR_State_Idle + ofxPAR_State_Idle() + ~ofxPAR_State_Idle() + draw() :void + update() :void ofxPAR_State_InfraSetup + ofxPAR_State_InfraSetup() + ~ofxPAR_State_InfraSetup() + draw() :void + update() :void ofxPAR_State_Play + ofxPAR_State_Play() + ~ofxPAR_State_Play() + draw() :void + update() :void - reprojectPaper() :void ofxPAR_Control_Rectangular # angle :float # rect :ofRectangle + ofxPAR_Control_Rectangular() + ~ofxPAR_Control_Rectangular() + ofxPAR_Control_Rectangular(cv::RotatedRect&) + draw() :void + contains(float, float) :bool + operator==(ofxPAR_Control_Rectangular&) :bool + operator!=(ofxPAR_Control_Rectangular&) :bool # alignPoint(float, float) :ofVec2f +app IDEAL: 08:38fb.com/RVA.BR 141
  142. 142. • Existe um framework em C++ chamado openFrameworks. Novo player interessante: Unreal Engine + Blueprints (AWESOME) • openFrameworks pode ser expandido com componentes da comunidade, chamados addons. • Com ele é possível controlar o Arduino (em C++). • O Arduino pode se transformar numa interface de dados usando a lib Firmata. • Arduino é barato e fácil de usar. Um possível software para desenhar circuitos é o Fritzing •Realidade Aumentada é só uma interface de acesso aos elementos virtuais. 08:38fb.com/RVA.BR 142
  143. 143. • openCV é uma biblioteca de visão computacional. • Com openCV podemos rastrear cores, diferenças de imagens, etc. • Pense se sua aplicação pode usar equipamentos simples! • Quanto mais simples e do cotidiano do usuário melhor. • Visão computacional nem sempre é um resultado por si. Ideal são soluções hibridas. • Adicionando elementos de interação físicos (sensores e atuadores) à Realidade Aumentada, que fazem a troca bidirecional de informação cria-se Realidade Cruzada. 08:38fb.com/RVA.BR 143
  144. 144. 08:38fb.com/RVA.BR 144 Motivador Pesquisa
  145. 145. Dúvidas: christophercerqueira@gmail.com Site: http://cscerqueira.com.br Facebook: http://fb.com/RVA.BR Para maiores dúvidas: INPE – SJC Prédio Satélite Sala 95 Drª. Ana Maria Ambrosio Msc. Christopher Cerqueira aluno doutorado Dr. Claudio Kirner 08:38fb.com/RVA.BR 145

×