www.pudn.com > ReadingPeopleTracker-1.28.rar > Profile.cc
/* * Profile.cc * * a record class for storing the Profile data * of an object * * AMB 27/4/93 */ #include// for hypot #include #ifndef NO_DISPLAY #ifdef DEBUG #include "os_specific_things.h" // for sleep() #endif #endif // #ifndef NO_DISPLAY #include "Profile.h" //#include "ActiveShapeTracker.h" #include "text_output.h" // for cerror etc #include "SplineWeights.h" #include "tracker_defines_types_and_helpers.h" #ifndef NO_DISPLAY // include graphics libraries... #ifdef USE_GL #include #ifdef LINUX #ifndef DISPLAY_POLY // defbasis, curveprecision, curvebasis, crvn are currently missing from Ygl #ifdef __cplusplus extern "C" { #include } #else // ifdef __cplusplus #include #endif // ifdef __cplusplus else #endif // ifndef DISPLAY_POLY #endif // ifdef LINUX #else // ifdef USE_GL #include #include #include #endif // ifdef USE_GL else #endif // #ifndef NO_DISPLAY #include "SplineWeights.h" #include "EnvParameter.h" #include "Image.h" #include "EdgeDetector.h" #include "Calibration.h" namespace ReadingPeopleTracker { // definition and initialisation of static member variables unsigned int Profile::NO_CONTROL_POINTS = 32; bool Profile::draw_boxes = true; bool Profile::draw_arrow = false; bool Profile::draw_in_colour = true; bool Profile::draw_rectangle = false; bool Profile::draw_spline = true; bool Profile::draw_fill = false; bool Profile::output_points = true; bool Profile::draw_dashed = false; bool Profile::draw_label = true; int Profile::draw_linewidth = 4; realno Profile::draw_box_size = 1.5; const realno Profile::LARGE = 1e10; Profile::Profile(Point2 &p_o, realno &p_w, realno &p_h, realno& p_grad, PointVector &pnts, Point2 &d) : PointVector(NO_CONTROL_POINTS+1), Observation(), direction(point_data()[NO_CONTROL_POINTS]) { spline_weights = NULL; origin = p_o; width = p_w; height = p_h; Observation::xlo = real_to_int(origin.x - width / 2); Observation::xhi = real_to_int(origin.x + width / 2); Observation::ylo = real_to_int(origin.y - height / 2); Observation::yhi = real_to_int(origin.y + height / 2); inv_grad = p_grad; if (pnts.get_data() != NULL) pnts.NagVector::copy(*this); else this->NagVector::clear(0.0); direction = d; filters = NULL; pos_filter = NULL; a_filter = NULL; s_filter = NULL; th_filter = NULL; colour_info = NULL; no_cblobs = 0; PCA_flag = 0; // gp_filter = NULL; a_x = a_y = 0; track_error = 0; fitness = 0; filters_initialised = false; } Profile::Profile(realno orig_x, realno orig_y, realno wdth, realno hgt) : PointVector(NO_CONTROL_POINTS+1), direction(point_data()[NO_CONTROL_POINTS]), Observation() { spline_weights = NULL; origin.x = orig_x; origin.y = orig_y; width = wdth; height = hgt; Observation::xlo = real_to_int(origin.x - width / 2); Observation::xhi = real_to_int(origin.x + width / 2); Observation::ylo = real_to_int(origin.y - height / 2); Observation::yhi = real_to_int(origin.y + height / 2); inv_grad = 0; direction.x = direction.y = 0.0; clear(0); filters = NULL; pos_filter = NULL; a_filter = NULL; s_filter = NULL; th_filter = NULL; colour_info = NULL; no_cblobs = 0; PCA_flag = 0; // gp_filter = NULL; a_x = a_y = 0; track_error = 0; fitness = 0; filters_initialised = false; } Profile::Profile(Profile &original) : PointVector(NO_CONTROL_POINTS+1), direction(point_data()[NO_CONTROL_POINTS]), Observation() { assert (1 == 0); // don't use this contructor! (why would you?) operator= (original); } Profile &Profile::operator=(const Profile &original) { Observation::operator=(original); // tracker = original.tracker; inv_grad = original.inv_grad; // FIXME: should really be there but buggy: filters_initialised = original.filters_initialised; cdebug << endl << " FIXME: Profile::operator=(): `filters_initialised = original.filters_initialised' commented out " << endl; filters_initialised = false; //////////////////// FIXME for (int i = 0 ; i < NO_CONTROL_POINTS; i++) spline[i] = original.spline[i]; track_error = original.track_error; fitness = original.fitness; PCA_flag = original.PCA_flag; no_shape_parameters = original.no_shape_parameters; if (original.filters != NULL) { filters = new FilterOneD*[no_shape_parameters]; for (int i = 0; i < no_shape_parameters; i++) filters[i] = original.filters[i]->clone(); } else filters = NULL; a_x = original.a_x; a_y = original.a_y; if (original.a_filter != NULL) { a_filter = new StaticKalmanTwoD(); *a_filter = *original.a_filter; } else a_filter = NULL; if (original.s_filter != NULL) { s_filter = new StaticKalmanOneD(); *s_filter = *original.s_filter; } else s_filter = NULL; if (original.th_filter != NULL) { th_filter = new StaticKalmanOneD(); *th_filter = *original.th_filter; } else th_filter = NULL; if (original.pos_filter != NULL) { pos_filter = (FilterTwoD*) new StaticKalmanTwoD; *pos_filter = *original.pos_filter; } else pos_filter = NULL; no_cblobs = original.no_cblobs; if (original.colour_info != NULL) { assert(original.no_cblobs > 0); colour_info = new ColourBlob[no_cblobs]; for (int i = 0; i < no_cblobs; i++) colour_info[i].operator=(original.colour_info[i]); } else { colour_info = NULL; } return *this; } Profile::Profile() : PointVector(NO_CONTROL_POINTS+1), direction(point_data()[NO_CONTROL_POINTS]), Observation() { spline_weights = NULL; origin.x = origin.y = width = height = inv_grad = 0; direction.x = direction.y = 0; filters = NULL; pos_filter = NULL; a_filter = NULL; s_filter = NULL; th_filter = NULL; colour_info = NULL; no_cblobs = 0; PCA_flag = 0; // gp_filter = NULL; a_x = a_y = 0; track_error = 0; fitness = 0; filters_initialised = false; } Profile::~Profile() { if (filters != NULL) delete [] filters; if (a_filter != NULL) delete a_filter; if (s_filter != NULL) delete s_filter; if (pos_filter != NULL) delete pos_filter; if (th_filter != NULL) delete th_filter; // if (gp_filter != NULL) delete gp_filter; // FIXME: does not work. why? if (colour_info != NULL) delete [] colour_info; } ostream &operator<< (ostream &out_strm, const Profile &profile) { out_strm << "origin " << profile.origin << endl; out_strm << "width " << profile.width << endl; out_strm << "height " << profile.height << endl; if (profile.direction != Point2(0,0)) out_strm << "direction " << profile.direction << endl; if (profile.filters_initialised) { // // see whether we have calibration data and put out 3D info // if ((profile.tracker != NULL) && (profile.tracker->calibration != NULL)) // { // // new style Calibration class // NagVector nag_origin(2); // nag_origin[0] = profile.origin.x; // nag_origin[1] = profile.ylo; // NB: not origin.y as origin is in the centre of the person // // Image::set_colour(2); // // move2(origin.x,ylo); // // draw2(origin.x,ylo+height); // // Image::set_colour(5); // // move2(origin.x+2,ylo); // // realno h = tracker->calibration->get_image_distance_from_height_in_cm(nag_origin,170); // // draw2(origin.x,ylo+h); // // sleep(2); // NagVector world_position = profile.tracker->calibration->get_world_from_ip(nag_origin); // out_strm << "world_pos (" // << world_position[0] << "," << world_position[1] // << ") " << endl; // out_strm << "world_height " // << profile.tracker->calibration->get_world_distance_from_height_in_pixels(nag_origin, // profile.height) // << " " << endl; // } out_strm << "shape_parameters"; int i; for (i = 0; i get_state(); out_strm << endl; out_strm << "fitness " << profile.fitness << endl; out_strm << "positional variance " << profile.track_error << endl; } if (Profile::output_points) { out_strm << "control_points "; for (int i = 0; i < Profile::NO_CONTROL_POINTS; i++) out_strm << profile.spline[i] << " "; out_strm << endl; } return out_strm; } // new version of operator>> allows more flexibility istream &operator>>(istream &in_strm, Profile &pf) { char dummytag[64]; bool finished = false; // keep going until we reach a 'control_points' tag // OR a second 'label' or 'origin' tag bool found_label = false; bool found_origin = false; pf.inv_grad = 0; pf.direction = Point2(0,0); while (!finished) { in_strm >> dummytag; if (strcmp(dummytag,"label") == 0) { if (found_label) { finished = true; Profile::putback_string(in_strm, dummytag); break; } found_label = true; // in_strm >> pf.ref_no; continue; } else if (strstr(dummytag,"origin") != NULL) // matches *origin* { if (found_origin) { finished = true; Profile::putback_string(in_strm,dummytag); break; } found_origin = true; Point2 origin; in_strm >> origin; pf.origin = origin; } else if (strstr(dummytag,"width") != NULL) // matches *width* in_strm >> pf.width; else if (strstr(dummytag,"height") != NULL) // matches *height* in_strm >> pf.height; else if (strstr(dummytag,"direction") != NULL) // matches *direction* in_strm >> pf.direction; else if (strstr(dummytag,"control_points") != NULL) { for (int i = 0; i < Profile::NO_CONTROL_POINTS; i++) in_strm >> pf.spline[i]; finished = true; } // ignore up to end of line in_strm.ignore(999,'\n'); } return in_strm; } #ifndef NO_DISPLAY #ifndef DISPLAY_POLY NagMatrix bsplinematrix = { { -1.0/6.0, 3.0/6.0, -3.0/6.0, 1.0/6.0 }, { 3.0/6.0, -6.0/6.0, 3.0/6.0, 0 }, { -3.0/6.0, 0, 3.0/6.0, 0 }, { 1.0/6.0, 4.0/6.0, 1.0/6.0, 0 }, }; #endif #endif // #ifndef NO_DISPLAY #ifndef NO_DISPLAY typedef Coord gl_vec3[3]; typedef Coord gl_vec2[2]; #endif // #ifndef NO_DISPLAY void Profile::draw(int col1, int col2, int col3) { #ifndef NO_DISPLAY int i; int j; // if (Profile::draw_in_colour) // Image::set_colour(col1); if (Profile::draw_dashed) setlinestyle(2); else setlinestyle(0); #ifndef DISPLAY_POLY defbasis(1,bsplinematrix); curveprecision(15); curvebasis(1); #endif // linewidth(Profile::draw_linewidth); if ((Profile::draw_spline) && (Profile::draw_fill == false)) { #ifdef DISPLAY_POLY // draw polygon approximation of b spline int no_divisions = 128 / NO_CONTROL_POINTS; if (spline_weights == NULL) spline_weights = new SplineWeights(no_divisions); BoundaryPoints *boundary = to_points(); float vert[2]; setlinestyle(0); bgnclosedline(); for (i = 0; i < boundary->get_no_points(); i++) { vert[0] = boundary->point_data()[i].x; vert[1] = boundary->point_data()[i].y; v2f(vert); } endclosedline(); delete boundary; #else // draw true b spline to screen using GL gl_vec3 geom1[NO_CONTROL_POINTS + 4]; for (i = 0; i < NO_CONTROL_POINTS + 4; i++) { geom1[i][0] = spline[i % NO_CONTROL_POINTS].x + ox; geom1[i][1] = spline[i % NO_CONTROL_POINTS].y + oy; geom1[i][2] = 0.0; } crvn(NO_CONTROL_POINTS+4,geom1); #endif } if (Profile::draw_fill) draw_filled(); #ifdef USE_GL if (Profile::draw_rectangle) { //get_size(); sbox((float) (origin.x - width / 2), (float) (origin.y - height/ 2), (float) (origin.x + width / 2), (float) (origin.y + height / 2)); } #endif float vert[2]; vert[0] = spline[0].x + origin.x; vert[1] = spline[0].y + origin.y; /*bgnpoint(); v2f(vert); endpoint();*/ if (Profile::draw_boxes) { for (j = 0; j < NO_CONTROL_POINTS; j++) { // nts: usually (always?) col1==col2==col3 so don't bother setting it all the time // if (Profile::draw_in_colour) // { // if (j == 0) // Image::set_colour(col3); // else // Image::set_colour(col2); // } vert[0] = spline[j].x + origin.x; vert[1] = spline[j].y + origin.y; rectf((float) (vert[0] - Profile::draw_box_size), (float) (vert[1] - Profile::draw_box_size), (float) (vert[0] + Profile::draw_box_size), (float) (vert[1] + Profile::draw_box_size)); /* if ((j % 4) == 0) { cmov2(spline[j].x + ox, spline[j].y + oy); char nstr[20]; sprintf(nstr, "%d", j); charstr(nstr); }*/ } } if (Profile::draw_arrow) { // if (Profile::draw_in_colour) // Image::set_colour(col3); if (height == 0) get_size(); Point2 arr_start(origin.x, origin.y + 0.2 * height); double arr0 = 0.2 * height; double arr1 = 5 * arr0; double arr2 = 4 * arr0; // linewidth(Profile::draw_linewidth); bgnline(); vert[0] = arr_start.x; vert[1] = arr_start.y; v2f(vert); vert[0] = arr_start.x + arr1 * direction.x; vert[1] = arr_start.y + arr1 * direction.y; v2f(vert); vert[0] = arr_start.x + arr2 * direction.x - arr0 * direction.y; vert[1] = arr_start.y + arr2 * direction.y + arr0 * direction.x; v2f(vert); vert[0] = arr_start.x + arr1 * direction.x; vert[1] = arr_start.y + arr1 * direction.y; v2f(vert); vert[0] = arr_start.x + arr2 * direction.x + arr0 * direction.y; vert[1] = arr_start.y + arr2 * direction.y - arr0 * direction.x; v2f(vert); endline(); // linewidth(Profile::draw_linewidth); } setlinestyle(0); // nts: put into Profile // if (Profile::draw_label) // { // cmov2(ox - width / 2, oy - height / 2 - 12); // char ref_name[32]; // sprintf(ref_name,"person %i",ref_no); // charstr(ref_name); // still in the same colour as the rest :-) // } #endif // #ifndef NO_DISPLAY } void Profile::scale(realno scale_fac) { for (int i = 0; i < NO_CONTROL_POINTS; i++) spline[i] = scale_fac * spline[i]; } void Profile::scale_coords(realno scale_fac) { scale(scale_fac); origin *= scale_fac; width *= scale_fac; height *= scale_fac; direction *= scale_fac; } // realno Profile::get_size() // { // realno ymin = LARGE; // realno ymax = -LARGE; // realno xmin = LARGE; // realno xmax = - LARGE; // for (int i = 0; i < NO_CONTROL_POINTS; i++) // { // if (spline[i].y < ymin) ymin = spline[i].y; // if (spline[i].y > ymax) ymax = spline[i].y; // if (spline[i].x < xmin) xmin = spline[i].x; // if (spline[i].x > xmax) xmax = spline[i].x; // } // width = (xmax - xmin); // height = (ymax - ymin); // return 0.5 * (height + width); // } // void Profile::get_y_bounds(realno &ymin, realno &ymax) // { // ymin = LARGE; // ymax = -LARGE; // for (int i = 0; i < NO_CONTROL_POINTS; i++) // { // if (spline[i].y < ymin) ymin = spline[i].y; // if (spline[i].y > ymax) ymax = spline[i].y; // } // } void Profile::update_size_variables() { // first, calculate bounding box (variables Observation::xlo etc) realno ymin = LARGE; realno ymax = -LARGE; realno xmin = LARGE; realno xmax = - LARGE; for (int i = 0; i < NO_CONTROL_POINTS; i++) { if (spline[i].y < ymin) ymin = spline[i].y; if (spline[i].y > ymax) ymax = spline[i].y; if (spline[i].x < xmin) xmin = spline[i].x; if (spline[i].x > xmax) xmax = spline[i].x; } xlo = (int) ((xmin - 0.5) + origin.x); xhi = (int) ((xmax + 0.5) + origin.x); ylo = (int) ((ymin - 0.5) + origin.y); yhi = (int) ((ymax + 0.5) + origin.y); // now adjust size variables width = xhi - xlo + 1; height = yhi - ylo + 1; } void Profile::normalise(bool flag) { recenter(); if (!flag) scale (get_size() / 200.0); // recenters points, rotates and scales realno sqsin = 1 / (1 + inv_grad * inv_grad); realno sqcos = (1 - sqsin); realno sinang; realno cosang; sinang = sqrt(sqsin); if (inv_grad >= 0) cosang = sqrt(sqcos); else cosang = - sqrt(sqcos); if (!flag) cosang = - cosang; Point2 newx(sinang,-cosang); Point2 newy(cosang,sinang); for (int i = 0; i < NO_CONTROL_POINTS; i++) spline[i] = Point2(newx * spline[i], newy * spline[i]); get_size(); if (flag) scale(200.0/get_size()); } void Profile::recenter(realno *w) { Point2 sum(0,0); // realno wt = (1.0 / NO_CONTROL_POINTS); if (w != NULL) { realno wsum = 0; for (int i = 0;i < NO_CONTROL_POINTS; i++) { sum += w[i] * spline[i]; wsum += w[i]; } sum = (1.0 / wsum) * sum; } else { realno ymin = LARGE; realno ymax = -LARGE; realno xmin = LARGE; realno xmax = - LARGE; for (int i = 0; i < NO_CONTROL_POINTS; i++) { if (spline[i].y < ymin) ymin = spline[i].y; if (spline[i].y > ymax) ymax = spline[i].y; if (spline[i].x < xmin) xmin = spline[i].x; if (spline[i].x > xmax) xmax = spline[i].x; } sum = Point2((xmax + xmin) / 2.0, (ymax + ymin) / 2.0); } origin += sum; for (int i = 0; i < NO_CONTROL_POINTS; i++) spline[i] -= sum; } void Profile::map(const realno &ax, const realno &ay, Profile *result) { if (result == NULL) result = this; PointVector::map(ax,ay,*result); } void Profile::align_to(Profile *mean, Profile *result, realno &s, realno &th, realno *weights) { //mean->recenter(weights); recenter(weights); realno C1, C2, Z; C1 = C2 = Z = 0; Point2 *prf1 = &(mean->spline[0]); Point2 *prf2 = &(spline[0]); realno tmp = (1.0 / NO_CONTROL_POINTS); for (int k = 0; k < NO_CONTROL_POINTS; k++) { if (weights != NULL) tmp = weights[k]; Z += tmp * (prf2[k].x * prf2[k].x + prf2[k].y * prf2[k].y); C1 += tmp * (prf1[k].x * prf2[k].x + prf1[k].y * prf2[k].y); C2 += tmp * (prf1[k].y * prf2[k].x - prf1[k].x * prf2[k].y); } realno ax = C1 / Z; realno ay = C2 / Z; // hypot(X,Y) returns `sqrt(X*X + Y*Y)'. s = hypot(ax,ay); th = (atan2(ay,ax)); map(ax,ay,result); } void Profile::display_shape(realno new_ox, realno new_oy) { Point2 saved_origin = origin; origin = Point2(new_ox,new_oy); draw(); origin = saved_origin; } Profile *Profile::reflect(Profile *result) { if (result == NULL) result = new Profile; result->origin = origin; result->width = width; result->height = height; result->direction = Point2(-direction.x, direction.y); result->spline[0] = Point2(-spline[0].x, spline[0].y); for (int i = 1; i < NO_CONTROL_POINTS; i++) result->spline[NO_CONTROL_POINTS - i] = Point2(- spline[i].x, spline[i].y); return result; } realno *Profile::get_shape(int i) { // if (i == (2 * NO_CONTROL_POINTS)) return &(direction.x); // if (i == (2 * NO_CONTROL_POINTS + 1)) return &(direction.y); if ((i % 2) == 0) return &(spline[i / 2].x); else return &(spline[i / 2].y); } realno Profile::get_data(int i) { if (i < (2*NO_CONTROL_POINTS)) return *get_shape(i); if (i == (2*NO_CONTROL_POINTS)) return direction.x; if (i == (2 * NO_CONTROL_POINTS + 1)) return direction.y; /* NOTREACHED */ return 0; } void Profile::set_data(int i, realno val) { if (i < (2*NO_CONTROL_POINTS)) *get_shape(i) = val; if (i == (2 * NO_CONTROL_POINTS)) direction.x = val; if (i == (2 * NO_CONTROL_POINTS + 1)) direction.y = val; } int Profile::get_data_size() { if (Profile::draw_arrow) return 2 * NO_CONTROL_POINTS+2; return 2 * NO_CONTROL_POINTS; } void Profile::draw_filled() { #ifndef NO_DISPLAY #ifndef DISPLAY_POLY if (spline_weights != NULL) delete spline_weights; int no_divisions = 128 / NO_CONTROL_POINTS; spline_weights = new SplineWeights(no_divisions); BoundaryPoints *boundary = to_points(NULL); float vert[2]; concave(true); polymode(PYM_FILL); bgnpolygon(); for (int i = 0; i < boundary->get_no_points(); i++) { vert[0] = boundary->point_data()[i].x; vert[1] = boundary->point_data()[i].y; v2f(vert); } endpolygon(); delete boundary; #endif // ifndef DISPLAY_POLY #endif // ifndef NO_DISPLAY } BoundaryPoints *Profile::to_points(BoundaryPoints *res) { setup_spline_weights(); if (res == NULL) res = new BoundaryPoints(NO_CONTROL_POINTS * spline_weights->nsubs); else if (res->get_no_points() < (NO_CONTROL_POINTS * spline_weights->nsubs)) { cerror << " error in Profile::ro_points " << endl; abort(); } int k; Point2 p0,p1,p2,p3; Point2 *curr = res->point_data(); for (int i = 0; i < NO_CONTROL_POINTS; i++) { k = (i-1); if (k < 0) k += NO_CONTROL_POINTS; p0 = spline[k]; p1 = spline[(k+1) % NO_CONTROL_POINTS]; p2 = spline[(k+2) % NO_CONTROL_POINTS]; p3 = spline[(k+3) % NO_CONTROL_POINTS]; for (int j = 0; j < spline_weights->nsubs; j++) { *curr++ = origin + (spline_weights->w0[j] * p0) + (spline_weights->w1[j] * p1) + (spline_weights->w2[j] * p2) + (spline_weights->w3[j] * p3); } } return res; } void Profile::interpolate(NagVector &coeff, NagVector &res) { setup_spline_weights(); if ((coeff.get_size() != NO_CONTROL_POINTS) || (res.get_size() != (NO_CONTROL_POINTS * spline_weights->nsubs))) { cerror << " error in Profile::interpolate " << endl; abort(); } int k; realno p0,p1,p2,p3; realno *curr = res.get_data(); for (int i = 0; i < NO_CONTROL_POINTS; i++) { k = (i-1); if (k < 0) k += NO_CONTROL_POINTS; p0 = coeff[k]; p1 = coeff[(k+1) % NO_CONTROL_POINTS]; p2 = coeff[(k+2) % NO_CONTROL_POINTS]; p3 = coeff[(k+3) % NO_CONTROL_POINTS]; for (int j = 0; j < spline_weights->nsubs; j++) { *curr++ = (spline_weights->w0[j] * p0) + (spline_weights->w1[j] * p1) + (spline_weights->w2[j] * p2) + (spline_weights->w3[j] * p3); } } } void Profile::get_normals(Profile &res) { int k; Point2 p0, p2, tmp; for (int i = 0; i < NO_CONTROL_POINTS; i++) { k = (i-1); if (k < 0) k += NO_CONTROL_POINTS; p0 = spline[k]; p2 = spline[(k+2) % NO_CONTROL_POINTS]; tmp = 0.5 * (p2 - p0); tmp.normalise(); res.spline[i] = Point2(-tmp.y, tmp.x); } } BoundaryPoints *Profile::sample_normals(BoundaryPoints *res) { setup_spline_weights(); if (res == NULL) res = new BoundaryPoints(NO_CONTROL_POINTS * spline_weights->nsubs); else if (res->get_no_points() < (NO_CONTROL_POINTS * spline_weights->nsubs)) { cerror << " error in Profile::sample_normals " << endl; abort(); } int k; Point2 p0,p1,p2,p3; Point2 *curr = res->point_data(); for (int i = 0; i < NO_CONTROL_POINTS; i++) { k = (i-1); if (k < 0) k += NO_CONTROL_POINTS; p0 = spline[k]; p1 = spline[(k+1) % NO_CONTROL_POINTS]; p2 = spline[(k+2) % NO_CONTROL_POINTS]; p3 = spline[(k+3) % NO_CONTROL_POINTS]; for (int j = 0; j < spline_weights->nsubs; j++) { *curr = (spline_weights->dw0[j] * p0) + (spline_weights->dw1[j] * p1) + (spline_weights->dw2[j] * p2) + (spline_weights->dw3[j] * p3); curr->normalise(); *curr = Point2(-curr->y, curr->x); curr++; } } return res; } void Profile::points_to_spline() { // convert a set of points to a spline BoundaryPoints *pnts = new BoundaryPoints(NO_CONTROL_POINTS); copy(*pnts); pnts->to_spline(this); delete pnts; } void Profile::draw_in_image(Image *canvas, Point2 offset, bool filled) { if (spline_weights == NULL) spline_weights = new SplineWeights(8); Point2 saved_origin = origin; origin = offset; // FIXME: should this be "+=" ? BoundaryPoints *prf_outline = to_points(); int np = prf_outline->get_no_points(); Point2 *pdata = prf_outline->point_data(); if (filled) { canvas->draw_filled_polygon(np, pdata); } for (int i = 0; i < np; i++) { Point2 p1 = pdata[i]; Point2 p2 = pdata[(i+1)%np]; canvas->set_line_width(3.0); canvas->draw_line(p1.x+0.5,p1.y+0.5,p2.x+0.5,p2.y+0.5); } // restore original origin origin = saved_origin; delete prf_outline; } void Profile::draw() { #ifndef NO_DISPLAY if (filters_initialised == false) return; if (is_visible == false) return; if (Profile::draw_linewidth > 1) { int old_draw_linewidth = Profile::draw_linewidth; Profile::draw_linewidth = 1; Profile::draw(0,0,0); Profile::draw_linewidth = old_draw_linewidth; } else { Profile::draw(0,0,0); } #endif // #ifndef NO_DISPLAY } void Profile::get_enclosing_box(int &xmin, int &xmax, int &ymin, int &ymax) { // NB make sure update_size_variables() was called! xmin = xlo; xmax = xhi; ymin = ylo; ymax = xhi; int dx = (int) (0.5 + sqrt(pos_filter->get_cov().val00)); int dy = (int) (0.5 + sqrt(pos_filter->get_cov().val11)); int max_dx = (int) (0.5 + (xmax - xmin) / 4); int max_dy = (int) (0.5 + (ymax - ymin) / 4); if (dx > max_dx) dx = max_dx; if (dy > max_dy) dy = max_dy; xmin -= dx; xmax += dx; ymin -= dy; ymax += dy; } void Profile::update_shape_filters() { if ((this == NULL) || (filters == NULL)) { cerror << " Profile::update_shape_filters(): bad call to method " << endl; return; } for (int i = 0; i < no_shape_parameters; i++) filters[i]->update_state(); } void Profile::setup_spline_weights() { if (spline_weights == NULL) spline_weights = new SplineWeights(); } } // namespace ReadingPeopleTracker