www.pudn.com > ReadingPeopleTracker-1.28.rar > Image.h
/* * Image.h * general image class (base class) * * author : A M Baumberg */ #ifndef __IMAGE_H__ #define __IMAGE_H__ #include#include // for strncpy() #ifndef NO_DISPLAY // include graphics libraries #ifdef USE_GL #include #else // use X interface and not GL #include #include // #include #include #endif // #ifdef USE_GL #endif // #ifndef NO_DISPLAY // includes #include "realno.h" #include "tracker_defines_types_and_helpers.h" #include "Kernel.h" #include "GreyMap.h" #include "timestamp_c.h" #include "EnvParameter.h" namespace ReadingPeopleTracker { // forward declarations class RGB32Image; class Point2; class GreyMap; class Image { // The following three lines should not be necessary since protected members // derived `public'ly should be accessible in derived classes. Never mind. friend class Grey8Image; friend class RGB32Image; friend class HSV32Image; public: // public static member variables // 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 line static const ImageAddressing image_addressing_mode; // 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. static const ImageAddressing image_storage_mode; protected: frame_id_t frame_id; // frame id: numeric identifier of this frame (frame number) frame_time_t frame_time_in_ms; // frame time in milliseconds since the Epoch // (01/01/1970) UTC (== GMT) à la 1000 * POSIX.1 (see annex B section 2.2.2) ImageType image_type; unsigned int width; unsigned int height; unsigned int bytes_per_pixel; // bpp_shift := number such that (x * bytes_per_pixel) equals (x << bpp_shift) unsigned int bpp_shift; unsigned int line_length; bool own_data; // whether we have allocated (and should therefore de-allocate) *data unsigned char *data; unsigned char *end_data; unsigned int *ypoints; // array of offsets to (0,y) realno DrawLineWidth; // for graphics routines // time stamp: from JPEG Time Stamp Header specification (see timestamp_c.h) TS_TIMESTAMP timestamp; // FIXME: might not be used by all `ImageSource's yet #ifndef NO_DISPLAY char window_title[64]; #ifdef USE_GL // use GL long int glwin; #else #ifdef USE_VOGL static int vogl_init_flag; #endif // use X Display *mydisplay; Window mywindow; XImage *myimage; Pixmap mypixmap; GC mygc; #endif public: // use setenv IMAGE_ZOOM 2 // to display images magnified by a factor of 2 static EnvIntParameter *display_zoom; #endif // ifndef NO_DISPLAY public: // set drawing colour static void set_colour(unsigned int col); // data accessors and modifiers inline frame_id_t get_frame_id() const { return frame_id; } inline void set_frame_id(frame_id_t new_frame_id) { frame_id = new_frame_id; } inline frame_time_t get_frame_time_in_ms() const { return frame_time_in_ms; } inline void set_frame_time_in_ms(frame_time_t new_frame_time_in_ms) { frame_time_in_ms = new_frame_time_in_ms; } inline unsigned int get_width() const { return width; } inline unsigned int get_height() const { return height; } inline unsigned int get_bytes_per_pixel() const { return bytes_per_pixel; } inline TS_TIMESTAMP *get_timestamp() { return ×tamp; } inline void set_timestamp(const TS_TIMESTAMP *new_timestamp) { timestamp = *new_timestamp; } inline unsigned char *get_data() const { return data; } inline void set_data(unsigned char *new_data) // use with caution! { if (own_data) delete [] data; data = new_data; end_data = data + width * height * bytes_per_pixel; own_data = true; // assume that the new data was allocated exclusively for us } inline unsigned char *get_end_data() const { return end_data; } inline void set_end_data(unsigned char *new_end_data) // use with caution! { end_data = new_end_data; } void set_height(unsigned int new_height) { height = new_height; } void set_width(unsigned int new_width) { width = new_width; } #ifndef NO_DISPLAY #ifdef USE_GL void set_title(char *title) { strncpy(window_title,title,63); // change if already displayed if (glwin != NULLWIN) { winset(glwin); wintitle(window_title); } } inline long int get_glwin() const { return glwin; } inline void set_glwin(long int new_glwin) { glwin = new_glwin; } #else #error Tugdual: Please implement set_title, and, only if necessary, an equivalent to [gs]et_glwin for Qt #endif // ifdef USE_GL else #endif // #ifndef NO_DISPLAY virtual unsigned int measure_contrast(void *p1, void *p2); // constructor, destructor Image (unsigned int the_width, unsigned int the_height, frame_id_t the_frame_id = 0, frame_time_t the_frame_time_in_ms = 0, unsigned int the_bpp = 1, unsigned char *the_data = NULL); Image () { frame_id = 0; frame_time_in_ms = 0; width = height = bytes_per_pixel = 0; image_type = BASE; // change in derived classes! data = end_data = NULL; #ifndef NO_DISPLAY window_title[0] = 0; #endif // #ifndef NO_DISPLAY } ~Image(); // save Image as PNM file. Redefined for each image type. virtual void save_pnm(char *filename = NULL) = 0; virtual void clear(unsigned char fill_char); // get pointer to pixel inline unsigned char *get_pixel(int x, int y) const { assert (x >= 0); assert (x < (unsigned) width); assert (y >= 0); assert (y < (unsigned) height); assert (data != NULL); assert (end_data > data); // pointer arithmetic return data + ypoints[y] + (x << bpp_shift); } inline bool check_coords(int x, int y) const { return (x >= 0) && (x < (unsigned) width) && (y >= 0) && (y < (unsigned) height); } inline bool check_coords(unsigned int x, unsigned int y) const { return (x < width) && (y < height); } inline bool check_coords(const realno &x, const realno &y) const { return check_coords((int) (x+.5), (int) (y+.5)); } inline unsigned char *nearest_pixel(realno x, realno y) const { return get_pixel(real_to_int(x), real_to_int(y)); } void get_pixel_coords(unsigned char *pnt, unsigned int &x, unsigned int &y) const; void draw_in_image(); // lrectread the screen pixels void read_image(); // VIRTUAL FUNCTIONS // *new* graphics routines // virtual graphics routines virtual void set_draw_colour(unsigned char red, unsigned char geen, unsigned char blue) {} virtual void set_draw_colour(unsigned char grey) {} virtual void draw_horizontal(unsigned int y, unsigned int xl, unsigned int xr, bool dotted = false) = 0; virtual void draw_vertical(unsigned int y, unsigned int xl, unsigned int xr, bool dotted = false) = 0; virtual void plot_pixel(unsigned int x, unsigned int y) = 0; // base class graphics routines void draw_filled_circle(int x0, int y0, int r); void set_line_width(realno w) { DrawLineWidth = w; } void draw_line(int x0, int y0, int x1, int y1); inline void draw_line(const realno &x0, const realno &y0, const realno &x1, const realno &y1) { draw_line((int) (x0+.5), (int) (y0+.5), (int) (x1+.5), (int) (y1+.5)); } static const int CIRCLE_PRECISION; void draw_circle(int xc, int yc, int r); // draw a filled concave polygon into the image void draw_filled_polygon(int nvertices, Point2 *vertices); // some more drawing functions from ActiveModel.cc (!) FIXME: check reduncancy --- nts 2002 #ifdef USE_GL // no non-GL versions // GL drawing for debugging output static inline void move2(const Point2 &p) { #ifndef NO_DISPLAY ::move2(p.x, p.y); #endif } static inline void draw2(const Point2 &p) { #ifndef NO_DISPLAY setlinestyle(0); ::draw2(p.x, p.y); #endif } static inline void dotted_draw2(Point2 &p) { #ifndef NO_DISPLAY // deflinestyle(1, 0xff00); setlinestyle(1); ::draw2(p.x, p.y); setlinestyle(0); #endif // #ifndef NO_DISPLAY } static inline void rect(Point2 &p1, Point2 &p2) { #ifndef NO_DISPLAY rectf(p1.x, p1.y, p2.x, p2.y); #endif } static inline void circ(Point2 &p, realno r) { #ifndef NO_DISPLAY circf(p.x, p.y, r); #endif } #endif // #ifdef USE_GL // misc virtual functions // (lrect)read the displayed screen pixels to get an RGB32Image virtual RGB32Image *rgb_read_image(RGB32Image *res = NULL); virtual long display(long window = NULLWIN) = 0; virtual void clear_border() = 0; // crude resample virtual Image *resample(unsigned int xstep, unsigned int ystep, Image *r = NULL) = 0; // create a physical copy of the image, copying image data, dimensions, time. // NB the window handle (in GL, variable glwin) is not copied over! virtual Image *copy(Image *r = NULL) const = 0; // return a new image of same type and dimensons virtual Image *copy_type(unsigned int w = 0, unsigned int h = 0) = 0; // virtual_copy -- returns a new wrapper around the same image data // (not a physical copy) virtual Image *virtual_copy(Image *res = NULL) const = 0; ImageType get_image_type() const { return image_type; } Image *flip_vertically(Image *r= NULL); // general image processing functions // fcombine - general function of two images virtual Image *fcombine(Image *image2, int (*func) (void*, void*), Image *r = NULL); // difference image (no thresholding) virtual Image *difference(Image *image2, Image *r = NULL) = 0; // quick differencing and thresholding using grid method virtual Image *difference(Image *image2, realno threshold, Image *r = NULL) = 0; // simple differencing and thresholding // threshold is always between 0 and 255 // (the derived class rescales for different image types) virtual Image *simple_difference(Image *image2, realno threshold, unsigned int *no_marked, Image *r = NULL) = 0; // difference image and calculate mean, variance of differences virtual Image *diff_stats(Image *img2, realno &mean, realno &variance, Image *r = NULL); // image_blend // Result(x,y) = (a * I1(x,y) + b * I2(x,y)) / (a+b) virtual Image *image_blend(Image *image2, int a, int b, Image *r = NULL); // map_intensities // use an array to map intensity values virtual Image *map_intensities(PntGreyMap intensity_map, Image *res = NULL); // convolve with 3x3 integer array (& normalise) virtual Image *convolve(Kernel k, Image *r = NULL) = 0; virtual Image *blur(Image*r = NULL) { return convolve(BLUR_KER,r); } // take n'th of ordered local pixels virtual Image *neighbour_order(unsigned int n, Image *r = NULL) = 0; // take median of 9 local pixels virtual Image *middle(Image *r = NULL) { return neighbour_order(5, r); } // take minimum of 9 local pixels virtual Image *minimum(Image *r = NULL) { return neighbour_order(1, r); } // take maximum of 9 local pixels virtual Image *maximum(Image *r = NULL) { return neighbour_order(9, r); } // fmed - fast middle filter virtual Image *fmed(Image *r = NULL); // sobel edge detection virtual Image *sobel(unsigned int threshold, Image *r = NULL) = 0; // sobel filter, don't threshold virtual Image *sobel(Image *r = NULL) = 0; // threshold image virtual Image *threshold(unsigned int threshold, Image *r = NULL, unsigned int *no_marked = NULL) = 0; // halve width, height and blur virtual Image *half_blur( Image *r = NULL); // mask image -- mask out image pixels virtual Image *mask(Image *mask, Image *r = NULL) = 0; // extract and clear the subimage - uses top-left as origin virtual Image *extract_subimage(int xmin, int xmax, int ymin, int ymax, Image *r = NULL); virtual void paste_subimage(unsigned int xmin, unsigned int xmax, unsigned int ymin, unsigned int ymax, Image *sub); Image *get_subimage(unsigned int xmin, unsigned int xmax, unsigned int ymin, unsigned int ymax, Image *sub = NULL); virtual Image *to_rgb(Image *r = NULL); virtual void draw_rectangle(int xmin, int xmax, int ymin, int ymax, int val); // Transform image (translate, rotate and scale) into a new image. // WARNING: Source & destination images must be of the same type. // (Added by T Heap) virtual Image *transform(int centre_x, int centre_y, realno angle, realno scale, Image *r = NULL); // add noise to image // returns noise (square sum) #ifdef _SVID_SOURCE // the following uses SVID 48-bit random numbers... virtual Image *add_gaussian_noise(realno sd, realno &noise, Image *r = NULL); #endif virtual realno sum_square_pixels(int zero_value = 0); virtual realno sum_pixels(); // weird and wonderful ... // // median_img_array // pixelwise "median" over array of images // storing result in *this virtual void median_img_array(Image**, int ); // plane project - pass the inverse mapping m00 ..., m22 Image *plane_project( const realno m00, const realno m01, const realno m02, const realno m10, const realno m11, const realno m12, const realno m20, const realno m21, const realno m22, Image *res = NULL); // colour filtering of image to grey levels virtual Image *ColourFilter(Image *res = NULL, ColourFilteringMethod method = CF_METHOD_Y_709); // colour distance in HSV space to grey level virtual Image *ColourDistance(Image *res = NULL, ColourDistanceMethod = CD_METHOD_V_WEIGHTED_HS); #ifdef HSV // convert image to HSV32Image virtual Image *Image::to_HSV32(Image *res); #endif protected: // private helpers typedef struct { realno x; realno dx; int i; } Edge; static Point2 *pt; // 2 comparison routines for qsort static int compare_ind(const void *u, const void *v) { return pt[*(int*)(u)].y <= pt[*(int*)(v)].y ? -1 : 1; } static int compare_active(const void *u, const void *v) { return ((Edge*)(u))->x <= ((Edge*)(v))->x ? -1 : 1; } void poly_delete(int i, int &nact, Edge *active); void poly_insert(int i, int y, int nvert, int &nact, Edge *active); }; } // namespace ReadingPeopleTracker #endif