//!Function for real-time hand extraction
void extractHand(IplImage* img)
{
set<HighlightPixel,lthp> handPixels;
//Variable for parallelization
int nthreads, tid;
//Parallel segment
#pragma omp parallel num_threads(NUMTHREADS) private(nthreads, tid)
{
//Get total number of threads
nthreads = omp_get_num_threads();
//Get current thread id
tid = omp_get_thread_num();
//Iterate through each row
for(int i = tid * (img->height - 1)/nthreads; i < (tid+1) * (img->height - 1)/nthreads; ++i)
{
//Iterate through each pixel in i row
for(int j = 0; j < img->width - 1; ++j)
{
//Grab the color of the pixel
CvScalar color = cvGet2D(img,i,j);
//Check each element in the profile
for(int x = 0; x < PROFILE_SIZE; ++x)
{
//Compare the pixel too a the element in the profile
if(compareColor(color,profile[x],50))
{
//If so, select pixel
cvSet2D(img,i,j,selectX);
HighlightPixel p;
p.i = i;
p.j = j;
//Critical section to prevent data acess violations
#pragma omp critical
{
handPixels.insert(p);
}
break;
}
}
}
}
}
//Initialize variables to default stage
int highestY = -1;
int lowestY = -1;
int highestX = -1;
int lowestX = -1;
int sumX = 0;
//Iterate through all pixels, finding the sum, the highest point, and the lowest point
for(set<HighlightPixel,lthp>::iterator it = handPixels.begin(); it != handPixels.end(); ++it)
{
sumX += (*it).i;
if(highestY == -1 || (*it).j > highestY)
{
highestY = (*it).j;
}
if(lowestY == -1 || (*it).j < lowestY)
{
lowestY = (*it).j;
}
if(highestX == -1 || (*it).i > highestX)
{
highestX = (*it).i;
}
if(lowestX == -1 || (*it).i < lowestX)
{
lowestX = (*it).i;
}
}
//Draw a circle for the center of the hand
cvCircle(img,cvPoint((highestY-lowestY)/2 + lowestY,sumX/handPixels.size()),3,cvScalar(0, 0, 255, 0),1,8,0);
//Draw a rectangle bounding box
cvRectangle(img,cvPoint(lowestY, lowestX),cvPoint(highestY, highestX),cvScalar(0, 0, 255, 0),1, 8, 0);
if(openHandWidth == -1)
{
openHandWidth = highestX - lowestX;
}
if(openHandHeight == -1)
{
openHandHeight = highestY - lowestY;
}
//Set all states to false
for (map<const char*,bool>::iterator it=state.begin() ; it != state.end(); it++ )
{
(*it).second = false;
}
//State catching
StateCatcher(highestX - lowestX,highestY - lowestY);
//Gesture catching
GestureCatcher((highestY-lowestY)/2 + lowestY,sumX/handPixels.size());
//Display state debug information
int i = 0;
for (map<const char*,bool>::iterator it=state.begin() ; it != state.end(); it++ )
{
if((*it).second == true)
{
cvPutText (img,(*it).first,cvPoint(0,i*20+20), &font, cvScalar(255,255,0));
++i;
}
}
}