Computação Gráfica
O objetivo deste trabalho é
desenvolver um ambiente de rastreamento de posição baseado em duas câmeras.
O trabalho pode ser entregue em duplas ou individualmente.
Para este trabalho, pode ser usado, como base, o exemplo disponível neste link.
Utilização de Vídeos (somente para Debug)
Para o desenvolvimento do
programa, podem ser utilizados dois vídeos, ao invés de duas câmeras.
É importante notar que a apresentação
deve ser realizada com imagens obtidas com duas câmeras, em tempo real,
ou seja, a apresentação não pode ser realizada com vídeos. A utilização de vídeo
serve a apenas para facilitar o desenvolvimento.
Para usar vídeos, siga os seguites passos:
-
Inicialmente, capture dois simultâneos vídeos no formato WMV. Isto pode ser feito com programas como MovieMaker, AMCap, ou IMLAB (http://imlab.sourceforge.net/).
- Esta gravação pode ser realizada com as duas câmeras conectadas a um
mesmo computador ou com cada câmera conectada a um computador diferente.
- A fim de facilitar a sincronização, sugere-se que, após iniciar a
gravação nas duas câmeras, seja se "apresentado" a ambas algum
objeto, simultaneamente. Isto permitá sincronizar os quadros dos dois vídeos.
- A
seguir, os vídeos devem ser convetidos para do formato AVI com um codec
específico, o CINEPACK. Para tanto, utilize o programa im_copy, da
seguinte forma;
- im_copy video_cam1.wmv video_cam1.avi AVI CINEPACK
- Este comando irá converter o arquivo vídeo video_cam1.wmv para video_cam1.avi, usando o codec CINEPACK.
- A partir disto, utilize o projeto disponivel neste link para ler e exibir o vídeo.
- Abra o projeto exemploGLUT.cbp e, no fonte AVITest-THREE.cpp, altere a função void init(void). Nela altere o nome do arquivo passado como parâmetro para o método openVideoFile.
Videos de Exemplo: Vídeo 1 Vídeo 2
Distorção Radial
A fim de melhor o cálculo da posição, devem ser usados algoritmos de
correção da distorçao radial, como este apresentado abaixo.
// ****************************************************************
// radial_invtransf
//
//
// ****************************************************************
void radial_invtransf(int x, int y, float *xl, float *yl, float k1, float xc, float yc)
{
float aux;
x -= (int)xc;
y -= (int)yc;
aux = 1.0f + k1*(x*x + y*y);
*xl = x*aux + xc;
*yl = y*aux + yc;
}
// ****************************************************************
// void RadialDistortion(ImageClass *Source, ImageClass *Dest)
//
//
// ****************************************************************
void RadialDistortion(ImageClass *Source, ImageClass *Dest)
{
float xl, yl;
float xc = float(Source->SizeX()/2.);
float yc = float(Source->SizeY()/2.);
int diag = (int)sqrt(float(Source->SizeX()*Source->SizeX()+ Source->SizeY()*Source->SizeY()));
unsigned char r,g,b;
float k1 = -0.2; // choose a initial value for "k1"
k1 /= (diag * diag);
for (int y = 0; y < Source->SizeY(); y++)
{
for (int x = 0; x < Source->SizeX(); x++)
{
radial_invtransf(x, y, &xl, &yl, k1, xc,
yc);
// if inside the original image broad area
if
(xl > 0.0 && yl > 0.0 && xl <
Source->SizeX() && yl < Source->SizeY())
{
Source->ReadPixel(xl,yl,r,g,b);
Dest->DrawPixel(x,y,r,g,b);
}
}
}
}
FIM.