www.pudn.com > ReadingPeopleTracker-1.28.rar > ProfileSet.cc


/*
 * ProfileSet -
 * a class consisting of a List of `Profile's
 *
 */

#include "ProfileSet.h"

namespace ReadingPeopleTracker
{

void ProfileSet::draw(frame_id_t min_draw_age)
{ 
#ifndef NO_DISPLAY
    for (ListNode *curr = first; curr != NULL; curr = curr->next)
    {
	if (curr->dat->frame_first_detected - curr->dat->frame_last_detected >= min_draw_age)
	    curr->dat->draw();
    }
#endif   // #ifndef NO_DISPLAY    
}

// draw the outlines onto the image data
void ProfileSet::draw_in_image(Image *img,
			       frame_id_t min_age) // = 0
{
    for (start(); current_ok(); forward())
    {
	if (get_current()->frame_last_detected - get_current()->frame_first_detected
	    >= min_age)
	{
	    img->set_line_width(3.0);
	    
	    // draw into image data
	    get_current()->draw_in_image(img, false);
	}
    }
}

void ProfileSet::add_origins(Point2 new_origin)
{
    for (ListNode *curr = first; curr != NULL; curr = curr->next)
    {
	Point2 delta_origin = Point2(curr->dat->origin) - new_origin;

	for (int i = 0; i < Profile::NO_CONTROL_POINTS; i++)
	    curr->dat->point_data()[i] += delta_origin;
    }
}


void ProfileSet::reflect(ProfileSet &result)
{
    ListNode *lastp = last;
    for (ListNode *curr = first; curr != NULL; curr = curr->next)
    {
	result.add(curr->dat->reflect());

	// if the result set is *this we need the following condition
	if (curr == lastp)
	    break;
    }
}

void ProfileSet::transform(NagMatrix &H)
{
    if (H.get_data() == NULL)
	return;
    for (ListNode *curr = first; curr != NULL; curr = curr->next)
	H.multiply(*curr->dat);
}

void ProfileSet::gauss_smooth(realno sd)
{
    int win = (int) (2.0 * sd + 0.5) + 1;
    realno denom = 2 * sd * sd;
    NagVector coeff(win);
    unsigned int n;
    realno sum = 1.0;
    coeff[0] = 1.0;

    for (n = 1; n < win; n++)
	sum += 2.0 * (coeff[n] = exp(-(realno) (n*n) / denom));
    
    coeff.scale(1.0 / sum, coeff);
    
    for (n = 0; n < no_items; n++)
    {
	Profile *res_prf = new Profile;
	res_prf->clear();
	for (int m = -win + 1; m < win; m++)
	{
	    int k = abs(n+m);
	    if (k >= no_items)
		k = abs(2 * (no_items-1) - k);
	    NagVector tmp;
	    (*this)[k]->NagVector::scale(coeff[abs(m)], tmp);
	    res_prf->add(tmp, *res_prf);
	}
	this->add(res_prf);
    }

    // new profiles have been added to *this.  Remove the old ones...
    for (n = 0; n < no_items; n++)
    {
	this->destroy(first);
    }
}

void ProfileSet::fit_to_line()
{
    NagVector t(no_items);
    NagVector x(no_items);
    NagVector y(no_items);
    ListNode *curr;
    
    int i = 0;
    for (curr = first; curr != NULL; curr = curr->next)
    {
	t[i] = i;
	x[i] = curr->dat->origin.x;
	y[i] = curr->dat->origin.y;
	i++;
    }
    
    realno denom = no_items * t.length2() - (t.sum())*(t.sum());
    realno m_x = (no_items * t.dot(x) - t.sum() * x.sum()) / denom;
    realno c_x = (t.length2() * x.sum() - t.sum() * t.dot(x)) / denom;
    
    realno m_y = (no_items * t.dot(y) - t.sum() * y.sum()) / denom;
    realno c_y = (t.length2() * y.sum() - t.sum() * t.dot(y)) / denom;
    i = 0;
    for (curr = first; curr != NULL; curr = curr->next)
    {
	Point2 new_origin(i * m_x + c_x, i * m_y + c_y);
	Point2 adjust(new_origin - curr->dat->origin);
	i++;
	for (int k = 0; k < Profile::NO_CONTROL_POINTS; k++)
	    curr->dat->spline[k] -= adjust;
	
	curr->dat->origin = new_origin;
    }
}  

void ProfileSet::scale_coords(realno scale_fac)
{ 
    if (scale_fac != 1.0)
    {
	for (ListNode *curr = first; curr != NULL; curr = curr->next)
	    curr->dat->scale_coords(scale_fac);
    }
}

} // namespace ReadingPeopleTracker