U
untitled
i wrote an application in c++ that capture a motion from a bmp
sequence and outputs a 3DS max secript file contains the motions keys.
i have two points here need to be fixed:
1- it is an offline application, ie. you take a movie file, convert it
to a sequence of 16color BMPs with adobe premiere for example. to
imporve, we should let it read the video stream directly from a webcam
for example and detect motion directly from it.
the problem here i don't know how to read the bit stream from the
webcam and what it the format of the stream.
2- it generate a 3ds secript file, for improvement, we can let it
connect direclty to the 3ds max script listener.
any ideas? questions?
BTW, i didn't use functions or classes because i was in hurry.
this is the source code:
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <string.h>
//most of the "cout" are for debugging purpose.
using namespace std;
int main(int argc, char *argv[])
{ //i,j are for loops
//iX,iY are an array for hit locations
//iTemp is for temporary place to store the character readed from
file to divied it to two hexas
//pFile is the address of the file object
//iDistance is the distance or the weight for each hit
//iWeight is the array containing the weight for iX,iY.
//iWeightTmp is a temporary array for weight
//iNear is a counter represent the weight for a hit.
//iCenterX,iCenterY is the center info.
//Color should be defined before compile the application
//ScriptLine is a temp place to convert ints to strings
//X, Y are the string format of the integer centers
int Color=9;
int i=0,j=0;
int iTmp=0,iPixle[320][240];
int iX[76800],iY[76800],iSize=0;
int iWeight[76800],iWeightTmp[76800];
int iNear=0;
double dDistance=0;
int iCenterX[1000],iCenterY[1000];
FILE * pFile;
int iFileName=0;
char cFileName[10];
char Prefix[3];
char Converter[3];
int iFileCounter=0;
char ScriptLine[20];
char X[5],Y[5];
//make file name
for (iFileName=1;iFileName<1000;iFileName++)
{
if (iFileName>=0&&iFileName<=9) strcpy(Prefix,"000");
if (iFileName>=10&&iFileName<=99) strcpy(Prefix,"00");
if (iFileName>=100&&iFileName<=999) strcpy(Prefix,"0");
strcpy(cFileName,"c:\\pix\\");
strcat(cFileName,Prefix);
strcat(cFileName,itoa(iFileName,Converter,10));
strcat(cFileName,".txt");
//open a picture file to start reading
cout<<"opening file... "<<endl;
pFile = fopen (cFileName,"rb");
//if the file is legal, start reading characters from bottom of
picture to top.
if (pFile!=NULL)
{
cout<<"file open....ok "<<endl;
fseek(pFile,118,SEEK_SET);
for (i=0;i<240;i++)
{
if (!feof(pFile))
{
for (j=0;j<320;j=j+2)
{
if (!feof(pFile))
{
iTmp=fgetc(pFile);
iPixle[j]=iTmp>>4; // one character contains
two bytes-
iPixle[j+1]=iTmp&15; //each byte is a pixle
color, here we devide it to two pixles
}
else cout << "done" << endl;
}
}
else cout << "done2" << endl;
}
}
else
{
cout<<" the center info
array"<<endl<<"=============="<<endl;
goto finish;
}
cout<<"file read complete, closing file now... "<<endl;
fclose (pFile);
cout<<"file closed...ok "<<endl;
//filter loop to read each element of the array and see if its
a hit or not.
iSize=0;
cout<<"reading array and check for hits... "<<iSize<<endl;
for (i=0;i<240;i++)
for (j=0;j<320;j++)
//cout<<iPixle[j]<<endl;
if (iPixle[j]== 9)
{
iX[iSize]=j;
iY[iSize]=i;
//cout<<"hit "<<iX[iSize]<<" "<<iY[iSize]<<endl;
iSize++;
}
cout<<iSize<<" hits found in file... "<<endl;
//check distances between points and save them in a weight
array.
cout<<"measuring distances between hits..iSize="<<endl;
for (i=0;i<iSize;i++)
{
iNear=0;
for (j=0;j<iSize;j++)
{
//cout << sqrt(((iX-iX[j])^2)+((iY-
iY[j])^2))<<endl;
dDistance=sqrt(pow((iX-iX[j]),2)+pow((iY-iY[j]),
2));
if (dDistance<20 && dDistance>10)iNear++;
}
iWeight=iNear;
}
cout<<"measuring distance complete.. "<<endl;
//copy weight array to a temporary array
cout<<"creating shadow array... "<<endl;
for (i=0;i<iSize;i++) iWeightTmp=iWeight;
cout<<"shadow array created. "<<endl;
//get the highest weight of hit
cout<<"getting highest weight... "<<endl;
for (i=1;i<iSize;i++)
{
if (iWeightTmp[0]<iWeightTmp)
iWeightTmp[0]=iWeightTmp;
}
cout<<"highest weigth is "<<iWeightTmp[0]<<endl;
//make an array containing locations for the highest weight.
cout<<"locating highest weight points... "<<endl;
j=0;
for (i=0;i<iSize;i++)
if (iWeight==iWeightTmp[0])
{
iX[j]=iX;
iY[j]=iY;
cout<<" coordinates "<<iX[j]<<" "<<iY[j]<<endl;
j++;
}
cout<<"location found "<<endl;
cout<<"high weight points number is "<<j;
//now we have iX,iY contains the info of the highest hits, and
with a length of j
//get the avarage of the center
cout<<"calculating center info... "<<endl;
for (i=0;i<j;i++)
{
iX[0]=iX[0]+iX;
iY[0]=iY[0]+iY;
}
iCenterX[iFileName]=iX[0]/(j+1);
iCenterY[iFileName]=240-(iY[0]/(j+1));
iFileCounter++;
}
//scripting part
finish:
if (iFileCounter!=0)
{
pFile=fopen("c:\\output.ms","w");
if (pFile!=NULL)
{
fputs ("select $Sphere01\nset animate on\nsliderTime
+= 2\n",pFile);
for (i=2;i<iFileCounter+1;i++)
{
cout<<iCenterX<<" "<<iCenterY<<endl;
fputs("move $ [",pFile);
itoa((iCenterX-iCenterX[i-1]),X,10);
itoa((iCenterY-iCenterY[i-1]),Y,10);
fputs(X,pFile);
fputs(",",pFile);
fputs(Y,pFile);
fputs(",0]\n",pFile);
fputs("sliderTime += 2\n",pFile);
}
fputs ("set animate off\n",pFile);
fclose(pFile);
}
}
else cout<<"no files found";
system("PAUSE");
return EXIT_SUCCESS;
}
sequence and outputs a 3DS max secript file contains the motions keys.
i have two points here need to be fixed:
1- it is an offline application, ie. you take a movie file, convert it
to a sequence of 16color BMPs with adobe premiere for example. to
imporve, we should let it read the video stream directly from a webcam
for example and detect motion directly from it.
the problem here i don't know how to read the bit stream from the
webcam and what it the format of the stream.
2- it generate a 3ds secript file, for improvement, we can let it
connect direclty to the 3ds max script listener.
any ideas? questions?
BTW, i didn't use functions or classes because i was in hurry.
this is the source code:
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <string.h>
//most of the "cout" are for debugging purpose.
using namespace std;
int main(int argc, char *argv[])
{ //i,j are for loops
//iX,iY are an array for hit locations
//iTemp is for temporary place to store the character readed from
file to divied it to two hexas
//pFile is the address of the file object
//iDistance is the distance or the weight for each hit
//iWeight is the array containing the weight for iX,iY.
//iWeightTmp is a temporary array for weight
//iNear is a counter represent the weight for a hit.
//iCenterX,iCenterY is the center info.
//Color should be defined before compile the application
//ScriptLine is a temp place to convert ints to strings
//X, Y are the string format of the integer centers
int Color=9;
int i=0,j=0;
int iTmp=0,iPixle[320][240];
int iX[76800],iY[76800],iSize=0;
int iWeight[76800],iWeightTmp[76800];
int iNear=0;
double dDistance=0;
int iCenterX[1000],iCenterY[1000];
FILE * pFile;
int iFileName=0;
char cFileName[10];
char Prefix[3];
char Converter[3];
int iFileCounter=0;
char ScriptLine[20];
char X[5],Y[5];
//make file name
for (iFileName=1;iFileName<1000;iFileName++)
{
if (iFileName>=0&&iFileName<=9) strcpy(Prefix,"000");
if (iFileName>=10&&iFileName<=99) strcpy(Prefix,"00");
if (iFileName>=100&&iFileName<=999) strcpy(Prefix,"0");
strcpy(cFileName,"c:\\pix\\");
strcat(cFileName,Prefix);
strcat(cFileName,itoa(iFileName,Converter,10));
strcat(cFileName,".txt");
//open a picture file to start reading
cout<<"opening file... "<<endl;
pFile = fopen (cFileName,"rb");
//if the file is legal, start reading characters from bottom of
picture to top.
if (pFile!=NULL)
{
cout<<"file open....ok "<<endl;
fseek(pFile,118,SEEK_SET);
for (i=0;i<240;i++)
{
if (!feof(pFile))
{
for (j=0;j<320;j=j+2)
{
if (!feof(pFile))
{
iTmp=fgetc(pFile);
iPixle[j]=iTmp>>4; // one character contains
two bytes-
iPixle[j+1]=iTmp&15; //each byte is a pixle
color, here we devide it to two pixles
}
else cout << "done" << endl;
}
}
else cout << "done2" << endl;
}
}
else
{
cout<<" the center info
array"<<endl<<"=============="<<endl;
goto finish;
}
cout<<"file read complete, closing file now... "<<endl;
fclose (pFile);
cout<<"file closed...ok "<<endl;
//filter loop to read each element of the array and see if its
a hit or not.
iSize=0;
cout<<"reading array and check for hits... "<<iSize<<endl;
for (i=0;i<240;i++)
for (j=0;j<320;j++)
//cout<<iPixle[j]<<endl;
if (iPixle[j]== 9)
{
iX[iSize]=j;
iY[iSize]=i;
//cout<<"hit "<<iX[iSize]<<" "<<iY[iSize]<<endl;
iSize++;
}
cout<<iSize<<" hits found in file... "<<endl;
//check distances between points and save them in a weight
array.
cout<<"measuring distances between hits..iSize="<<endl;
for (i=0;i<iSize;i++)
{
iNear=0;
for (j=0;j<iSize;j++)
{
//cout << sqrt(((iX-iX[j])^2)+((iY-
iY[j])^2))<<endl;
dDistance=sqrt(pow((iX-iX[j]),2)+pow((iY-iY[j]),
2));
if (dDistance<20 && dDistance>10)iNear++;
}
iWeight=iNear;
}
cout<<"measuring distance complete.. "<<endl;
//copy weight array to a temporary array
cout<<"creating shadow array... "<<endl;
for (i=0;i<iSize;i++) iWeightTmp=iWeight;
cout<<"shadow array created. "<<endl;
//get the highest weight of hit
cout<<"getting highest weight... "<<endl;
for (i=1;i<iSize;i++)
{
if (iWeightTmp[0]<iWeightTmp)
iWeightTmp[0]=iWeightTmp;
}
cout<<"highest weigth is "<<iWeightTmp[0]<<endl;
//make an array containing locations for the highest weight.
cout<<"locating highest weight points... "<<endl;
j=0;
for (i=0;i<iSize;i++)
if (iWeight==iWeightTmp[0])
{
iX[j]=iX;
iY[j]=iY;
cout<<" coordinates "<<iX[j]<<" "<<iY[j]<<endl;
j++;
}
cout<<"location found "<<endl;
cout<<"high weight points number is "<<j;
//now we have iX,iY contains the info of the highest hits, and
with a length of j
//get the avarage of the center
cout<<"calculating center info... "<<endl;
for (i=0;i<j;i++)
{
iX[0]=iX[0]+iX;
iY[0]=iY[0]+iY;
}
iCenterX[iFileName]=iX[0]/(j+1);
iCenterY[iFileName]=240-(iY[0]/(j+1));
iFileCounter++;
}
//scripting part
finish:
if (iFileCounter!=0)
{
pFile=fopen("c:\\output.ms","w");
if (pFile!=NULL)
{
fputs ("select $Sphere01\nset animate on\nsliderTime
+= 2\n",pFile);
for (i=2;i<iFileCounter+1;i++)
{
cout<<iCenterX<<" "<<iCenterY<<endl;
fputs("move $ [",pFile);
itoa((iCenterX-iCenterX[i-1]),X,10);
itoa((iCenterY-iCenterY[i-1]),Y,10);
fputs(X,pFile);
fputs(",",pFile);
fputs(Y,pFile);
fputs(",0]\n",pFile);
fputs("sliderTime += 2\n",pFile);
}
fputs ("set animate off\n",pFile);
fclose(pFile);
}
}
else cout<<"no files found";
system("PAUSE");
return EXIT_SUCCESS;
}