📄 image.cc
字号:
/* * Image.cc * general Image class * * author : A M Baumberg */#ifdef _SVID_SOURCE#include <cstdlib> // for System V style 48-bit random number generator// functions void srand48(long int seed_val), double drand48(void)// (_SVID_SOURCE must be defined for this to work --- available under Linux)#endif#include <cassert>#include <cstdio>#include <cstring>#include <ctime>#include <cmath>#include "Image.h"#include "Point2.h"#include "Kernel.h"#include "text_output.h"#include "tracker_defines_types_and_helpers.h"namespace ReadingPeopleTracker{// definition and initialisation of static member variablesconst int Image::CIRCLE_PRECISION = 8;Point2 *Image::pt = NULL;#ifndef NO_DISPLAYEnvIntParameter *Image::display_zoom = new EnvIntParameter("IMAGE_ZOOM", 1);#endif // ifndef NO_DISPLAY// Global and constant variables that determine Image Addressing: // image_addressing_mode: determines the orientation of the v axis in the image.// This should always be BOTTOM_TO_TOP, like axes in mathematics and physics.// TOP_TO_BOTTOM: line 0 is the top line, BOTTOM_TO_TOP: line 0 is the bottom lineconst ImageAddressing Image::image_addressing_mode = IA_BOTTOM_TO_TOP;// image_storage_mode: determines the orientation of the image in memory. This has an// influence only on functions which operate in the image memory, e.g. JPEGSource.// This should be set to the way your graphics library or display (e.g. X11) handles it.// TOP_TO_BOTTOM: a lower memory address is closer to the top line of the image,// BOTTOM_TO_TOP: a higher memory address is closer to the top line of the image.#ifdef LINUX#ifdef USE_GL// Warning: this is unlike X11, which makes displaying images slower...const ImageAddressing Image::image_storage_mode = IA_BOTTOM_TO_TOP;#elseconst ImageAddressing Image::image_storage_mode = IA_TOP_TO_BOTTOM;#endif // USE_GL#else // ie not LINUX#error " Set both image addressing variables to correct values. "ImageAddressing Image::image_storage_mode = IA_TOP_TO_BOTTOM;#endif // ifdef LINUX// please check usage of this varable below when changing this!#ifndef NO_DISPLAY#ifndef USE_GL#ifdef USE_VOGLextern "C"{ // these are vogl void ginit(); void vo_xt_window(Display*, Window, int, int); void vo_xt_drawable(Display*, Window, Drawable, GC, int, int); void vo_array(unsigned char*, int, int, int); typedef unsigned short Colorindex; extern void color(Colorindex);} int Image::vogl_init_flag = 0;#endif // ifdef USE_VOGL#endif // ifndef USE_GL#endif // ifndef NO_DISPLAYvoid Image::set_colour(unsigned int col){#ifndef NO_DISPLAY#ifndef USE_GL // ie use VOGL#ifdef USE_VOGL ::color(col);#endif // ifdef USE_VOGL#else// FIXME: we are assuming we have an RGB (true colour?) display. // get r,g,b colour from table defined in Image.h ... ::RGBcolor( draw_colour_table[col % NUM_DRAW_COLOURS][0], draw_colour_table[col % NUM_DRAW_COLOURS][1], draw_colour_table[col % NUM_DRAW_COLOURS][2] );#endif#endif // #ifndef NO_DISPLAY} Image::Image(unsigned int the_width, unsigned int the_height, frame_id_t the_frame_id, frame_time_t the_frame_time_in_ms, unsigned int the_bpp, unsigned char *the_data){ assert (the_width > 0); assert (the_height > 0); assert (the_bpp > 0); width = the_width; height = the_height; frame_id = the_frame_id; frame_time_in_ms = the_frame_time_in_ms; image_type = BASE; // change in derived classes! switch (bytes_per_pixel = the_bpp) { case 1: bpp_shift = 0; break; case 2: bpp_shift = 1; break; case 4: bpp_shift = 2; break; default: cerror << " Image::Image: Bad call to Image constructor (unknown #bpp)" << endl; exit(1); } #ifndef NO_DISPLAY window_title[0] = 0;#endif // #ifndef NO_DISPLAY // length (size) of an image line in memory line_length = width * bytes_per_pixel; if (the_data == NULL) { data = new unsigned char[height * line_length]; own_data = true; } else { data = the_data; own_data = false; } end_data = (data + height * line_length); ypoints = new unsigned int[height]; // make sure that ypoints can be used as the user wants (image_addressing_mode) // while respecting the image's layout in memory (image_storage_mode): if (image_storage_mode == image_addressing_mode) { for (unsigned int y = 0; y < height; y++) ypoints[y] = y * line_length; } else { // flip ypoints to hide the discrepancy from other methods for (unsigned int y = 0; y < height; y++) ypoints[y] = (height - (y+1)) * line_length; }#ifndef NO_DISPLAY#ifdef USE_GL glwin = NULLWIN;#else mydisplay = NULL; mywindow = NULLWIN;#endif#endif // #ifndef NO_DISPLAY }Image::~Image(){ // de-allocate image memory if ((own_data) && (data != NULL)) delete [] data; delete [] ypoints; // close window if Image is currently displayed#ifndef NO_DISPLAY#ifdef USE_GL// GL interface if (glwin != NULLWIN) winclose(glwin);#else// X interface if (mydisplay != NULL) { XFreeGC(mydisplay, mygc); XDestroyWindow(mydisplay, mywindow); if (myimage->data != (char *) data) delete [] (myimage->data); myimage->data = None; XFree((char *) myimage); }#endif#endif // #ifndef NO_DISPLAY }inline void Image::clear(unsigned char fill_char){ memset(data, (int) fill_char, (end_data - data));}// given a pointer to a pixel within the Image, return x and y ccordinatesvoid Image::get_pixel_coords(unsigned char *pnt, unsigned int &x, unsigned int &y) const{ assert(pnt > data); assert(pnt <= end_data); register unsigned int offset = pnt - data; x = (offset % line_length) >> bpp_shift; // this is dependent on image addressing and storage modes: if (image_addressing_mode == image_storage_mode) y = offset / line_length; else y = height - ((offset / line_length) + 1);}void Image::draw_in_image(){ #ifndef NO_DISPLAY#ifdef USE_GL if (glwin != NULLWIN) { winset(glwin); if (image_type == GREY8) cmode(); else RGBmode(); gconfig(); // NB we have to do this after cmode / RGBmode }#else if (vogl_init_flag == 0) { if (mydisplay == NULL) // draw directly into image data { // use amb's extension to vogl // vo_array(data, width, height, bytes_per_pixel); ginit(); vogl_init_flag = 1; } else // draw into backing pixmap or into window { // vo_xt_drawable(mydisplay, mywindow, mywindow, mygc, width, // height); vogl_init_flag = 3; ginit(); } }#endif#endif // #ifndef NO_DISPLAY}#ifdef USE_GLinline#endifvoid Image::read_image(){ #ifndef NO_DISPLAY#ifdef USE_GL winset(glwin); lrectread(0,0,width-1,height-1, (Int32 *) data); #else // do nothing if drawing directly into image data if (vogl_init_flag == 1) return; XImage *xi; if (vogl_init_flag == 2) xi = XGetImage(mydisplay, mypixmap, 0,0, width, height, AllPlanes, ZPixmap); else if ((vogl_init_flag == 3) || (vogl_init_flag == 0)) xi = XGetImage(mydisplay, mywindow, 0,0, width, height, AllPlanes, ZPixmap); else memcpy(data, xi->data, (end_data - data)); XDestroyImage(xi); flip_vertically(this); #endif#endif // #ifndef NO_DISPLAY}Image *Image::flip_vertically(Image *r) { if (r == NULL) r = copy_type(); unsigned char *tmp_store = new unsigned char[line_length]; int endloop; if ((height % 2) == 0) endloop = height / 2; else { endloop = (height - 1) / 2; memcpy(r->get_pixel(0,endloop), get_pixel(0,endloop), line_length); } int y1; int y2; // could use register here? but then, get_pixel is inline for (y1 = 0; y1 < endloop; y1++) { y2 = height - y1 - 1; memcpy(tmp_store, get_pixel(0,y2), line_length); memcpy(r->get_pixel(0,y2), get_pixel(0,y1), line_length); memcpy(r->get_pixel(0,y1), tmp_store, line_length); } delete [] tmp_store; return r;}Image *Image::extract_subimage(int xmin, int xmax, int ymin, int ymax, Image *r){ // new implementation for base class // should be reasonably efficient if (r == NULL) r = copy_type(xmax-xmin+1, ymax-ymin+1); for (int y = ymin; y <= ymax; y++) memcpy(r->get_pixel(0,y-ymin), get_pixel(xmin,y), r->line_length); return r;}void Image::paste_subimage(unsigned int xmin, unsigned int xmax, unsigned int ymin, unsigned int ymax, Image *subimg){ // sanity checks assert (xmin < xmax); assert (ymin < ymax); assert (subimg != NULL); assert (check_coords(xmin,ymin) == true); assert (check_coords(xmax,ymax) == true); assert (get_image_type() == subimg->get_image_type()); // if ((check_pixel(xmin,ymin) == NULL ) || // (check_pixel(xmax,ymax) == NULL) || // (xmin > xmax) || (ymin > ymax) || (get_image_type() != subimg->get_image_type()))// {// cerror << " bad parameters to paste_subimage because "// << (void*) check_pixel(xmin,ymin) << " == NULL or "// << (void*) check_pixel(xmax,ymax) << " == NULL or "// << xmin << " > " << xmax << " or " << ymin << " > " << ymax// << " or " << get_image_type() << " != " << subimg->get_image_type()// << endl;// exit(1);// } int nbytes = (xmax - xmin + 1) * bytes_per_pixel; for (unsigned int y = ymin; y <= ymax; y++) memcpy(get_pixel(xmin,y),subimg->get_pixel(0,y-ymin), nbytes);}Image *Image::get_subimage(unsigned int xmin, unsigned int xmax, unsigned int ymin, unsigned int ymax, Image *subimg){ if (subimg == NULL) subimg = copy_type(xmax - xmin + 1, ymax - ymin + 1); else assert (get_image_type() == subimg->get_image_type()); assert (xmin < xmax); assert (ymin < ymax); assert (check_coords(xmin,ymin) == true); assert (check_coords(xmax,ymax) == true);// if ((check_pixel(xmin,ymin) == NULL ) || // (check_pixel(xmax,ymax) == NULL) || // (xmin > xmax) || (ymin > ymax) || (image_type != subimg->get_image_type()))// {// cerror << " Image::get_subimage: bad parameters. " << endl;// exit(1);// } int nbytes = (xmax - xmin + 1) * bytes_per_pixel; for (unsigned int y = ymin; y <= ymax; y++) memcpy(subimg->get_pixel(0,y-ymin),get_pixel(xmin,y), nbytes); return subimg;}unsigned int Image::measure_contrast(void *p1, void *p2){ unsigned char *pix1 = (unsigned char*) p1; unsigned char *pix2 = (unsigned char*) p2; if ((pix1 == NULL) || (pix2 == NULL)) return 0; unsigned int val1 = (unsigned int) *pix1; unsigned int val2 = (unsigned int) *pix2; return abs(val1 - val2);}// the following VIRTUAL function implementations // do nothing but return error messages if not overridden/redefinedRGB32Image *Image::rgb_read_image(RGB32Image *res){ cerror << " illegal call to Image::rgb_read_image " << endl << " res = " << res << endl; abort();}Image *Image::fcombine(Image *image2, int (*func) (void*, void*), Image *r) { cerror << " illegal call to Image::fcombine. " << endl << " image2 = " << image2 << ", func = " << func << ", r = " << r << endl; abort();}Image *Image::diff_stats(Image *img2, realno &mean, realno &variance, Image *r) { cerror << "illegal call to Image::diff_stats " << endl; mean = variance = 0; abort();}Image *Image::image_blend(Image *image2, int a, int b, Image *r){ cerror << "illegal call to Image::image_blend " << endl; abort();}Image *Image::map_intensities(PntGreyMap gmap, Image *r){ cerror << "illegal call to Image::gamma_correct " << endl; abort();}// Image *Image::neighbour_order(unsigned int n, Image *r) // { // cerror << "illegal call to Image::neighbour_order " << endl;// abort();// }Image *Image::fmed(Image *r) { cerror << "illegal call to Image::fmed " << endl; abort(); }Image *Image::half_blur( Image *r) { cerror << "illegal call to Image::half_blur " << endl; abort();}Image *Image::ColourFilter(Image *res, ColourFilteringMethod method){ cerror << "illegal call to Image::ColourFilter " << endl; abort();}Image *Image::ColourDistance(Image *res, ColourDistanceMethod){ cerror << "illegal call to Image::ColourDistance " << endl; abort();}#ifdef HSVImage *Image::to_HSV32(Image *res){ cerror << "illegal call to Image::to_HSV32 " << endl; abort();}#endifImage *Image::to_rgb(Image *r){ cerror << "illegal call to Image::to_rgb " << endl; abort();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -