regionset.cc
来自「VC视频对象的跟踪提取原代码(vc视频监控源码)」· CC 代码 · 共 409 行
CC
409 行
/* * RegionSet.cc * * functions for RegionSet class * (declared in Region.h) * */#include "RegionSet.h"#include <cstdio>#ifndef NO_DISPLAY #ifdef USE_GL#include <gl/gl.h>#else#include <X11/Xlib.h>#include <vogl.h>#endif#ifdef DEBUG#include "os_specific_things.h" // for sleep()#endif#endif // #ifndef NO_DISPLAY#include "ProfileSet.h"#include "Image.h"#include "Grey8Image.h"#include "tracker_defines_types_and_helpers.h"namespace ReadingPeopleTracker{// definition and initialisation of static member variablesconst unsigned int RegionSet::DEFAULT_MIN_REGION_SIZE = 20;const unsigned int RegionSet::DEFAULT_MAX_REGION_SIZE = 100;#define DEFAULT_BORDER_WIDTH 8void RegionSet::grab_regions_and_subimages(const Grey8Image *img, unsigned int min_size, unsigned int max_size, bool keep_edge_regions){ unsigned int border_width; if (keep_edge_regions) border_width = 0; else border_width = DEFAULT_BORDER_WIDTH; Image *scene = new Grey8Image(img->get_width(), img->get_height()); scene->clear(CLEAR_MARK); Image *temp_image = NULL; unsigned char *sptr, *eptr, *tptr; unsigned char *ptr = img->get_data(); unsigned char *scene_data = scene->get_data(); int offset; unsigned int width = scene->get_width(); unsigned int height = scene->get_height(); int count, x, y; int os1 = width+1; int os2 = width; int os3 = width-1; int tnx = width-border_width - 1; int tny = height-border_width - 1; bool on_edge = false; for (y = border_width; y < tny; y++) { tptr = img->get_pixel(border_width,y); eptr = img->get_pixel(tnx,y); for ( ; tptr < eptr; tptr++) { if (*tptr == MARK) { stack->push(tptr); *tptr = CLEAR_MARK; int xhi = 1; int yhi = 1; int xlo = tnx; int ylo = tny; count = 0; on_edge = false; while (! stack->is_empty()) { stack->pop(sptr); img->get_pixel_coords(sptr, (unsigned int &) x, (unsigned int &) y); offset = sptr - ptr; *(scene_data + offset) = MARK; count++; if (x < xlo) xlo = x; // no else here! if (x > xhi) xhi = x; if (y < ylo) ylo = y; // no else here! if (y > yhi) yhi = y; /* add marked neighbours to stack */ if (y > border_width) { if (x > border_width) stack->test(sptr-os1); stack->test(sptr-os2); if (x < tnx) stack->test(sptr-os3); } else on_edge = true; if (x > border_width) stack->test(sptr-1); else on_edge = true; if (x < tnx) stack->test(sptr+1); else on_edge = true; if (y < tny) { if (x > border_width) stack->test(sptr+os3); stack->test(sptr+os2); if (x < tnx) stack->test(sptr+os1); } else on_edge = true; } if (keep_edge_regions) on_edge = false; xlo -= 2; xhi += 2; ylo -= 2; yhi += 2; xhi = ((((xhi - xlo) >> 3)+1) << 3) + xlo - 1; yhi = ((((yhi - ylo) >> 3)+1) << 3) + ylo - 1; if (xlo < 0) xlo = 0; if (xhi >= width) xhi = width - 1; if (ylo < 0) ylo = 0; if (yhi >= height) yhi = height -1; temp_image = scene->extract_subimage(xlo,xhi,ylo,yhi); if (!on_edge && (count <= max_size) && (count >= min_size)) add(new Region(xlo,xhi,ylo,yhi,temp_image)); else if (temp_image != NULL) delete temp_image; // free unused memory } } } delete scene;}void RegionSet::grab_regions(const Grey8Image *img, unsigned int min_size, unsigned int max_size, bool keep_edge_regions){ int border_width; if (keep_edge_regions) border_width = 0; else border_width = DEFAULT_BORDER_WIDTH; unsigned char *sptr, *eptr, *tptr; unsigned char *ptr = img->get_data(); int offset; int width = img->get_width(); int height = img->get_height(); int count, x, y; int os1 = width+1; int os2 = width; int os3 = width-1; int tnx = width-border_width - 1; int tny = height-border_width - 1; for (y = border_width; y < tny; y++) { tptr = img->get_pixel(border_width,y); eptr = img->get_pixel(tnx,y); for (;tptr < eptr; tptr++) { if (*tptr == MARK) { stack->push(tptr); *tptr = CLEAR_MARK; int xhi = 1; int yhi = 1; int xlo = tnx; int ylo = tny; count = 0; while (! stack->is_empty()) { stack->pop(sptr); img->get_pixel_coords(sptr, (unsigned int &) x, (unsigned int &) y); offset = sptr - ptr; count++; if (x < xlo) xlo = x; // no else here! if (x > xhi) xhi = x; if (y < ylo) ylo = y; // no else here! if (y > yhi) yhi = y; /* add marked neighbours to stack */ if (y > border_width) { if (x > border_width) stack->test(sptr-os1); stack->test(sptr-os2); if (x < tnx) stack->test(sptr-os3); } if (x > border_width) stack->test(sptr-1); if (x < tnx) stack->test(sptr+1); if (y < tny) { if (x > border_width) stack->test(sptr+os3); stack->test(sptr+os2); if (x < tnx) stack->test(sptr+os1); } } //if (!((xlo < (0.75 * width)) && //(xhi > (0.25 * width)) && //(ylo < (0.75 *height)) && //(yhi > (0.25 * height))) && if ((xlo > border_width) && (xhi < (width - border_width)) && (ylo > border_width) && (yhi < (height - border_width)) && ((count <= max_size) && (count >= min_size))) add(new Region(xlo,xhi,ylo,yhi,NULL)); } } }}void RegionSet::draw_regions(){#ifndef NO_DISPLAY for (ListNode<Region> *curr = first; curr != NULL; curr = curr->next) curr->dat->draw_points();#endif // #ifndef NO_DISPLAY}// draw rectangles around all regionsvoid RegionSet::draw_boxes(frame_id_t min_draw_age){#ifndef NO_DISPLAY for (ListNode<Region> *curr = first; curr != NULL; curr = curr->next) { if (curr->dat->frame_first_detected + min_draw_age <= curr->dat->frame_last_detected) curr->dat->draw_box(); } #endif // #ifndef NO_DISPLAY}// draw rectangles around all regions, into given Imagevoid RegionSet::draw_boxes_in_image(Image *canvas, frame_id_t min_draw_age){ for (ListNode<Region> *curr = first; curr != NULL; curr = curr->next) { // if max_age is not 0, only draw visible regions of age >= min_age if ((curr->dat->frame_first_detected) + min_draw_age <= (curr->dat->frame_last_detected)) { assert(curr->dat->is_visible); // otherwise the above should be false curr->dat->draw_box_in_image(canvas); } }}void RegionSet::clear_window(){#ifndef NO_DISPLAY //winset(gl_win); color(BLACK); clear();#endif // #ifndef NO_DISPLAY}void RegionSet::trace_regions(){ for (ListNode<Region> *curr = first; curr != NULL; curr = curr->next) curr->dat->trace();}void RegionSet::smooth(realno sd, int window_size){ for (ListNode<Region> *curr = first; curr != NULL; curr = curr->next) curr->dat->smooth_boundary(sd, window_size);}ProfileSet *RegionSet::to_profiles(){ ProfileSet *profiles = new ProfileSet; Profile *tmp; for (ListNode<Region> *curr = first; curr != NULL; curr = curr->next) { tmp = curr->dat->to_profile(); // which allocates memory if (tmp != NULL) profiles->add(tmp); } return profiles;} // distance between 2 blobs (regions)realno RegionSet::bbdistance(Region *r, Region *t){ realno d1; realno d2; realno dx; realno dy; d1 = r->xlo - t->xhi; d2 = t->xlo - r->xhi; if (d1 > 0) // r is right of t dx = d1; else if (d2 > 0) // t is right of r dx = d2; else dx = 0; // regions are not apart in x direction d1 = r->ylo - t->yhi; d2 = t->ylo - r->yhi; if (d1 > 0) // r is over t (thinking bottom to top) dy = d1; else if (d2 > 0) // t is over r dy = d2; else dy = 0; // regions are not apart in y direction d1 = MAX(r->width, r->height); d2 = MAX(t->width, t->height); // divided by 16 in order for the regions to have a greater tendency to // merge vertically rather than horizontally. register realno dd = (dx + dy/16) / (d1 + d2 + 1); return dd;}void RegionSet::merge_regions(realno dist_threshold){ bool flag=true; //dist_threshold = dist_threshold*dist_threshold; /* bbdistance returns square of distance */ ListNode<Region> *reg_r, *reg_t, *reg_t2; while (flag == true) { flag = false; for (reg_r=first; reg_r != NULL; reg_r = (reg_r->next)) { for (reg_t = (reg_r->next); reg_t != NULL; reg_t = (reg_t->next)) { if (bbdistance(reg_r->dat, reg_t->dat) < dist_threshold) { reg_r->dat->merge(reg_t->dat); flag = true; reg_t2 = (reg_t->prev); destroy(reg_t); reg_t = reg_t2; } } } }}void RegionSet::filter(realno min_region_size = 0.0){ for (ListNode<Region> *regn = first; regn != NULL; ) { if (abs((regn->dat->xhi - regn->dat->xlo) * (regn->dat->yhi - regn->dat->ylo)) < min_region_size) { ListNode<Region> *rgn_tmp = regn; regn = regn->next; destroy(rgn_tmp); } else regn = regn->next; }}} // namespace ReadingPeopleTracker
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?