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 + -
显示快捷键?