www.pudn.com > ReadingPeopleTracker-1.28.rar > Region.cc
/* * Region.cc * * a Region is a rectangular subimage and * will in general contain one connected blob * * class created 2/3/93 * author: Adam Baumberg * */ #include "Region.h" #include#include "Image.h" #include "BoundaryPoints.h" // #include "XMLSource.h" #include "Profile.h" #include "Grey8Image.h" #include "text_output.h" #ifndef NO_DISPLAY #ifdef USE_GL #include #else #include #endif #endif // #ifndef NO_DISPLAY namespace ReadingPeopleTracker { // TDG 6/2/98 commented out so that model building uses // vertical axis for alignment better for cars // use principle axis for people // TDG 15/12/98 added REGION_USE_HIGHEST_POINT option // nts 25/10/00 changed to REGION_USE_PRINCIPAL_AXIS for people tracking //#define REGION_USE_DIRECTION #define REGION_USE_PRINCIPAL_AXIS //#define REGION_USE_HIGHEST_POINT // definition and initialisation of static member variables const unsigned int Region::start_list[8] = {5,6,7,0,1,2,3,4}; const unsigned int Region::end_list[8] = {4,5,6,7,0,1,2,3}; const Point2 Region::directions[8] = { Point2(-1,-1), Point2(-1,0) ,Point2(-1,1), Point2(0,1), Point2(1,1), Point2(1,0), Point2(1,-1), Point2(0,-1) }; Region::~Region() { if (region_img != NULL) delete region_img; if (region_boundary != NULL) delete region_boundary; } Region &Region::operator= (const Region &original) { Observation::operator=(original); tracker = original.tracker; // copy over values for normal variables old_origin = original.old_origin; direction = original.direction; xml_blob_data = original.xml_blob_data; xml_blob_data_available = original.xml_blob_data_available; inv_grad = original.inv_grad; incorporated_into_background = original.incorporated_into_background; // instantiate new classes in order to copy *region_img and *region_boundary... if (original.region_img != NULL) region_img = original.region_img->copy(); // instantiates image class if (original.region_boundary != NULL) { region_boundary = new BoundaryPoints(original.region_boundary->get_no_points()); *region_boundary = *original.region_boundary; } return *this; }; void Region::trace() { if (region_boundary == NULL) region_boundary = new BoundaryPoints(); int imgwidth = region_img->get_width(); int imgheight = region_img->get_height(); bool found = false; /*int x = imgwidth / 2; int y; for (y = 0; y < imgheight && !found; y++) if (*(region_img->get_pixel(x,y)) != CLEAR_MARK) found = true; */ int x = 0; int y = 0; while ((y < imgheight) && (!found)) { if (*(region_img->get_pixel(x,y)) != CLEAR_MARK) found = true; else if ((++x) >= imgwidth) { x = 0; y++; } } if (!found) { cerror << " Region::trace(): cannot find starting point in region " << endl; exit(1); } region_boundary->add_point( Point2(x,y)); int forward = 1; int old_tmp = forward; int tmp = old_tmp; bool flag; int loop1; unsigned char *lpix; do { flag = false; // forward = (forward+1) & 7; loop1 = start_list[forward]; while ((loop1 != end_list[forward]) && (flag == false)) { Point2 look_dir = directions[(loop1+1)&7]; if ((region_img->check_coords(x + look_dir.x, y + look_dir.y) == false) || *(lpix = region_img->get_pixel(x + (int) look_dir.x, y + (int)look_dir.y)) == CLEAR_MARK) loop1 = (loop1+1) & 7; else { lpix = region_img->get_pixel(x + (int) look_dir.x, y + (int) look_dir.y); x += (int) look_dir.x; y += (int) look_dir.y; region_boundary->add_point(Point2(x,y)); flag = true; forward = loop1; tmp = (loop1+1) & 7; } } if (flag == false) { Point2 look_dir = directions[(loop1+1)&7]; if ((region_img->check_coords(x + look_dir.x, y + look_dir.y) == false) || *(lpix = region_img->get_pixel(x + (int) look_dir.x, y + (int) look_dir.y)) == CLEAR_MARK) { region_boundary->pop(); forward = old_tmp; Point2* endpoint = region_boundary->last(); x = (int) endpoint->x; y = (int) endpoint->y; } else { x += (int) look_dir.x; y += (int) look_dir.y; region_boundary->add_point(Point2(x,y)); flag = true; forward = loop1; tmp = (loop1+1) & 7; } } old_tmp = tmp; } while ((*(region_boundary->last()) != (*(region_boundary->first()))) && (region_boundary->get_no_points() < (768+576)*3)); // FIXME: how about a constant? region_boundary->pop(); region_boundary->find_best_line(inv_grad, origin.x, origin.y); origin.x += xlo; origin.y += ylo; } istream &operator>> (istream &strmin, Region &r) { char dummy[128]; strmin >> dummy >> r.xlo >> r.xhi >> r.ylo >> r.yhi; strmin >> dummy >> r.direction; return strmin; } ostream &operator<< (ostream &strmout, const Region &r) { strmout << "origin " << r.origin << endl; strmout << "old_origin " << r.old_origin << endl; strmout << "width " << r.width << endl; strmout << "height " << r.height << endl; strmout << "direction " << r.direction << endl; return strmout; } // will allocate memory for a new Profile and return pointer to it or NULL Profile *Region::to_profile() { // only use measurements, do not use predictions if (source != MEASUREMENT) return NULL; Profile *new_prf; PointVector tmp_pnts(0); if (region_boundary == NULL) { // region not traced -- use bounding box; Point2 centre = origin; realno p_grad = 0.0; new_prf = new Profile(centre, width, height, p_grad, tmp_pnts, direction); } else { Point2 new_origin; region_boundary->find_best_line(inv_grad, new_origin.x, new_origin.y); #ifdef REGION_USE_PRINCIPAL_AXIS Point2 p1 = Point2(inv_grad, 1); region_boundary->find_end(p1, new_origin); #elif defined REGION_USE_HIGHEST_POINT region_boundary->find_end_highest(Point2(0,0), new_origin); #elif defined REGION_USE_DIRECTION if (direction.length2() > 1) { region_boundary->find_end(direction, new_origin); #else region_boundary->find_end(Point2(0,1), new_origin); inv_grad = 0.0; #endif Point2 *origin = new Point2(new_origin + Point2(xlo, ylo)); new_prf = new Profile(*origin, width, height, inv_grad, tmp_pnts, direction); //region_boundary->find_optimal_spline(new_prf); region_boundary->convert_to_spline(new_prf); #ifdef REGION_USE_DIRECTION } #endif } if (new_prf != NULL) { // profile created. copy over source of information new_prf->source = source; } return new_prf; } int Region::combine(void *pix1, void *pix2) { return (int) ((*((unsigned char*) pix1) * 10 + *((unsigned char*) pix2)) / 11); } int Region::and_pixels (void *pix1, void *pix2) { return (int) (*((unsigned char*) pix1) & *((unsigned char*) pix2)); } int Region::or_pixels (void *pix1, void *pix2) { return (int) (*((unsigned char*) pix1) | *((unsigned char*) pix2)); } void Region::draw_points() { #ifndef NO_DISPLAY get_best_line(); region_boundary->draw_points(xlo,ylo); move2((float) (-45 * inv_grad + origin.x + xlo), (float) (ylo + origin.y - 45)); draw2((float) (65 * inv_grad + origin.x + xlo), (float) (origin.y + 65 + ylo)); #endif // #ifndef NO_DISPLAY } void Region::merge(Region *reg2) { int nxlo, nxhi, nylo, nyhi; nxlo = xlo; nxhi = xhi; nylo = ylo; nyhi = yhi; if (nxlo > (reg2->xlo)) nxlo = reg2->xlo; if (nxhi < (reg2->xhi)) nxhi = reg2->xhi; if (nylo > (reg2->ylo)) nylo = reg2->ylo; if (nyhi < (reg2->yhi)) nyhi = reg2->yhi; int nwidth = nxhi - nxlo + 1; int nheight = nyhi - nylo + 1; if (region_img != NULL) { Image *newimage = (Image*) new Grey8Image(nwidth,nheight); // because the subregions do not cover the whole newimage newimage->clear(0); newimage->paste_subimage(xlo - nxlo, xhi - nxlo, ylo - nylo, yhi - nylo, region_img); newimage->paste_subimage(reg2->xlo - nxlo, reg2->xhi - nxlo, reg2->ylo - nylo, reg2->yhi - nylo, reg2->region_img); delete region_img; region_img = newimage; } ylo = nylo; yhi = nyhi; xlo = nxlo; xhi = nxhi; old_origin = (old_origin + reg2->old_origin) / 2; // interpolate origin.x = (xlo + xhi) / 2.0; origin.y = (ylo + yhi) / 2.0; width = nwidth; height = nheight; } void Region::draw_box() { #ifndef NO_DISPLAY #ifdef USE_GL if (incorporated_into_background) setlinestyle(2); recti(xlo,ylo,xhi,yhi); setlinestyle(0); #endif #endif // #ifndef NO_DISPLAY } void Region::draw_box_in_image(Image *canvas, unsigned int line_width) { bool dotted; if (incorporated_into_background) dotted = true; else dotted = false; // in the following we add something to image coordinates, so check assert (xlo < xhi); assert (ylo < yhi); for (unsigned int count = 0; count < line_width; count++) { canvas->draw_vertical(xlo + count, ylo, yhi, dotted); canvas->draw_vertical(xhi - count, ylo, yhi, dotted); canvas->draw_horizontal(ylo + count, xlo, xhi, dotted); canvas->draw_horizontal(yhi - count, xlo, xhi, dotted); } } } // namespace ReadingPeopleTracker