ObjectState HTCamshift::update(InputArray _rgbFrame, InputArray _depthFrame, InputArray _mask) {
	CV_Assert(_rgbFrame.size() == rgbFrameSize && _rgbFrame.type() == rgbFrameType);

	if(useDepth == true) {
		CV_Assert(_depthFrame.size() == depthFrameSize && _depthFrame.type() == depthFrameType);
	}

	split(_rgbFrame, channels);

	if(state.valid == false) {
		calculateFeatureSet(_rgbFrame, _depthFrame);
	}
	calculateBackPro(_rgbFrame, _depthFrame, _mask);
	Rect bounding = state.location.boundingRect();
	state.location = CamShift(backPro, bounding, term);
	return state;
}
    int track(Mat &image,Rect &rect)
    {
        int status=0;
        cvtColor(image, hsv, CV_BGR2HSV_FULL);
        selection=rect;
        if(rect.width!=0&&rect.height!=0)
        {
            if(trackObject==false)
                buildHistogram ();
            if(trackObject==true)
            {
                Rect trackWindow=selection;
                Mat backproj=calcProbability ();
                RotatedRect trackBox = CamShift(backproj,trackWindow,TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ));
                if( trackWindow.area() <= 1 )
                {
                    int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5)/6;
                    trackWindow = Rect(0,0,0,0);
                    trackObject=false;
                }
                else
                {
                    Point2f rect_points[4]; trackBox.points( rect_points );
                          for( int j = 0; j < 4; j++ )
                              line( image, rect_points[j], rect_points[(j+1)%4], Scalar(0,0,255), 1, 8 );

                }

            }
        }
        else
        {
            trackObject=false;
        }

        status=1;
        return status;
    }
void FindObjectMain::process_camshift()
{
// Some user defined parameters
	int vmin = config.vmin;
	int vmax = config.vmax;
	int smin = config.smin;
	float hranges[] = { 0, 180 };
	const float* phranges = hranges;


// Create aligned, RGB images
	if(!object_image)
	{
		object_image = cvCreateImage( 
			cvSize(object_image_w, object_image_h), 
			8, 
			3);
	}

	if(!scene_image)
	{
		scene_image = cvCreateImage( 
			cvSize(scene_image_w, scene_image_h), 
			8, 
			3);
	}

// Temporary row pointers
	unsigned char **object_rows = new unsigned char*[object_image_h];
	unsigned char **scene_rows = new unsigned char*[scene_image_h];
	for(int i = 0; i < object_image_h; i++)
	{
		object_rows[i] = (unsigned char*)(object_image->imageData + i * object_image_w * 3);
	}
	for(int i = 0; i < scene_image_h; i++)
	{
		scene_rows[i] = (unsigned char*)(scene_image->imageData + i * scene_image_w * 3);
	}

// Transfer object & scene to RGB images for OpenCV
	if(!prev_object) prev_object = new unsigned char[object_image_w * object_image_h * 3];
// Back up old object image
	memcpy(prev_object, object_image->imageData, object_image_w * object_image_h * 3);

	BC_CModels::transfer(object_rows,
		get_input(object_layer)->get_rows(),
		0,
		0,
		0,
		0,
		0,
		0,
		object_x1,
		object_y1,
		object_w,
		object_h,
		0,
		0,
		object_w,
		object_h,
		get_input(object_layer)->get_color_model(),
		BC_RGB888,
		0,
		0,
		0);
	BC_CModels::transfer(scene_rows,
		get_input(scene_layer)->get_rows(),
		0,
		0,
		0,
		0,
		0,
		0,
		scene_x1,
		scene_y1,
		scene_w,
		scene_h,
		0,
		0,
		scene_w,
		scene_h,
		get_input(scene_layer)->get_color_model(),
		BC_RGB888,
		0,
		0,
		0);

	delete [] object_rows;
	delete [] scene_rows;

// from camshiftdemo.cpp
// Compute new object	
	if(memcmp(prev_object, 
		object_image->imageData, 
		object_image_w * object_image_h * 3) ||
		!hist.dims)
	{
		Mat image(object_image);
		Mat hsv, hue, mask;
		cvtColor(image, hsv, CV_RGB2HSV);
    	int _vmin = vmin, _vmax = vmax;
//printf("FindObjectMain::process_camshift %d\n", __LINE__);

    	inRange(hsv, 
			Scalar(0, smin, MIN(_vmin,_vmax)),
        	Scalar(180, 256, MAX(_vmin, _vmax)), 
			mask);
    	int ch[] = { 0, 0 };
    	hue.create(hsv.size(), hsv.depth());
    	mixChannels(&hsv, 1, &hue, 1, ch, 1);

		Rect selection = Rect(0, 0, object_w, object_h);
		trackWindow = selection;
		int hsize = 16;
		Mat roi(hue, selection), maskroi(mask, selection);
		calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
		normalize(hist, hist, 0, 255, CV_MINMAX);
	}


// compute scene
	Mat image(scene_image);
	Mat hsv, hue, mask, backproj;
	cvtColor(image, hsv, CV_RGB2HSV);
    int _vmin = vmin, _vmax = vmax;

    inRange(hsv, 
		Scalar(0, smin, MIN(_vmin,_vmax)),
        Scalar(180, 256, MAX(_vmin, _vmax)), 
		mask);
    int ch[] = {0, 0};
    hue.create(hsv.size(), hsv.depth());
    mixChannels(&hsv, 1, &hue, 1, ch, 1);
	
//printf("FindObjectMain::process_camshift %d %d %d\n", __LINE__, hist.dims, hist.size[1]);
	RotatedRect trackBox = RotatedRect(
		Point2f((object_x1 + object_x2) / 2, (object_y1 + object_y2) / 2), 
		Size2f(object_w, object_h), 
		0);
	trackWindow = Rect(0, 
		0,
        scene_w, 
		scene_h);
	if(hist.dims > 0)
	{
		

		calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
		backproj &= mask;
//printf("FindObjectMain::process_camshift %d\n", __LINE__);
// 		if(trackWindow.width <= 0 ||
// 			trackWindow.height <= 0)
// 		{
// 			trackWindow.width = object_w;
// 			trackWindow.height = object_h;
// 		}

		trackBox = CamShift(backproj, 
			trackWindow,
        	TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ));
//printf("FindObjectMain::process_camshift %d\n", __LINE__);


//     	if( trackWindow.area() <= 1 )
//     	{
//         	int cols = backproj.cols;
// 			int rows = backproj.rows;
// 			int r = (MIN(cols, rows) + 5) / 6;
//         	trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,
//                         	   trackWindow.x + r, trackWindow.y + r) &
//                     	  Rect(0, 0, cols, rows);
//     	}
	}
// printf("FindObjectMain::process_camshift %d %d %d %d %d\n", 
// __LINE__,
// trackWindow.x,
// trackWindow.y,
// trackWindow.width,
// trackWindow.height);


// Draw mask over scene
	if(config.draw_keypoints)
	{
		for(int i = 0; i < scene_h; i++)
		{
			switch(get_input(scene_layer)->get_color_model())
			{
				case BC_YUV888:
				{
					unsigned char *input = backproj.data + i * scene_image_w;
					unsigned char *output = get_input(scene_layer)->get_rows()[i + scene_y1] + scene_x1 * 3;
					for(int j = 0; j < scene_w; j++)
					{
						output[0] = *input;
						output[1] = 0x80;
						output[2] = 0x80;
						output += 3;
						input++;
					}
					break;
				}
			}
		}
	}

// Get object outline in the scene layer
// printf("FindObjectMain::process_camshift %d %d %d %d %d %d\n", 
// __LINE__,
// (int)trackBox.center.x,
// (int)trackBox.center.y,
// (int)trackBox.size.width,
// (int)trackBox.size.height,
// (int)trackBox.angle);
	double angle = trackBox.angle * 2 * M_PI / 360;
	double angle1 = atan2(-(double)trackBox.size.height / 2, -(double)trackBox.size.width / 2) + angle;
	double angle2 = atan2(-(double)trackBox.size.height / 2, (double)trackBox.size.width / 2) + angle;
	double angle3 = atan2((double)trackBox.size.height / 2, (double)trackBox.size.width / 2) + angle;
	double angle4 = atan2((double)trackBox.size.height / 2, -(double)trackBox.size.width / 2) + angle;
	double radius = sqrt(SQR(trackBox.size.height / 2) + SQR(trackBox.size.width / 2));
	border_x1 = (int)(trackBox.center.x + cos(angle1) * radius) + scene_x1;
	border_y1 = (int)(trackBox.center.y + sin(angle1) * radius) + scene_y1;
	border_x2 = (int)(trackBox.center.x + cos(angle2) * radius) + scene_x1;
	border_y2 = (int)(trackBox.center.y + sin(angle2) * radius) + scene_y1;
	border_x3 = (int)(trackBox.center.x + cos(angle3) * radius) + scene_x1;
	border_y3 = (int)(trackBox.center.y + sin(angle3) * radius) + scene_y1;
	border_x4 = (int)(trackBox.center.x + cos(angle4) * radius) + scene_x1;
	border_y4 = (int)(trackBox.center.y + sin(angle4) * radius) + scene_y1;

}