Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

ImageRGB.cpp

Go to the documentation of this file.
00001 /**************************************************************************
00008  *
00009  * Source code for Real Time Image Library (libRTImage)
00010  *
00011  * Leeds Vision Group give permission for this code to be copied, modified 
00012  * and distributed within the University of Leeds subject to the following 
00013  * conditions:-
00014  *
00015  * - The code is not to be used for commercial gain.
00016  * - The code and use thereof will be attributed to the author where
00017  *   appropriate (inluding demonstrations which rely on it's use).
00018  * - All modified, distributions of the source files will retain this header.
00019  *
00020  ****************************************************************************/
00021 
00022 #include <new>          // bad_alloc exception
00023 #include <string.h>     // memcpy
00024 #include <MicrosoftBMP_RT.h>
00025 #include <MicrosoftRCBMP_RT.h>
00026 #include <MicrosoftMonoBMP_RT.h>
00027  
00028 #include "ImageRGB.h"
00029 
00030 
00031 ImageRGB::ImageRGB(ImageRGB& img) : ImageBase(img)
00037 {
00038         unsigned int array_size = img.width * img.height;
00039         data = new PixelRGB[array_size];
00040 
00041         *this = img;
00042 }
00043 
00044 ImageRGB::ImageRGB(ImageRGB&    img,  
00045                    unsigned int min_x,
00046                    unsigned int min_y,
00047                    unsigned int max_x,
00048                    unsigned int max_y) : ImageBase(max_x-min_x+1, max_y-min_y+1)
00057 {
00058         data = new PixelRGB[width*height];
00059         copy(img, min_x, min_y, max_x, max_y, 0, 0) ;
00060 }
00061 
00062 ImageRGB::ImageRGB(unsigned int w, unsigned int h) : ImageBase(w,h)
00071 {
00072         unsigned int array_size = width * height;
00073         data = new PixelRGB[array_size];
00074 
00075 //      clear();
00076 }
00077 
00078 ImageRGB::ImageRGB(char *filename, FileFormat format)
00087 {
00088 
00089     if(format == FORMAT_BMP_24){
00090         MicrosoftBMP_RT bmp(filename) ;
00091 
00092         if(!bmp.read()) throw("Invalid Bitmap file specified") ;
00093 
00094         width = bmp.ImageWidth ;
00095         height = bmp.ImageHeight ;
00096 
00097         data = new PixelRGB[width*height] ;
00098 
00099         bmp.extract_data((int *)data) ;
00100     }
00101     else if(format == FORMAT_BMP_RC){
00102         MicrosoftRCBMP_RT bmp(filename) ;
00103 
00104         if(!bmp.read()) throw("Invalid Bitmap file specified") ;
00105 
00106         width = bmp.ImageWidth ;
00107         height = bmp.ImageHeight ;
00108 
00109         data = new PixelRGB[width*height] ;
00110 
00111         bmp.extract_data((int *)data) ;
00112     }
00113     else if(format == FORMAT_BMP_MONO){
00114         MicrosoftMonoBMP_RT bmp(filename) ;
00115 
00116         if(!bmp.read()) throw("Invalid Bitmap file specified") ;
00117 
00118         width = bmp.ImageWidth ;
00119         height = bmp.ImageHeight ;
00120 
00121         data = new PixelRGB[width*height] ;
00122 
00123         bmp.extract_data((int *)data) ;
00124     }
00125     else if(format == FORMAT_BMP_ANY){
00126     // Check all formats
00127          MicrosoftBMP_RT* bmp ;
00128          MicrosoftRCBMP_RT *bmp_rc;
00129          MicrosoftMonoBMP_RT *bmp_mono;
00130 
00131          if((bmp = new  MicrosoftBMP_RT(filename)) != NULL &&
00132             bmp->read()){
00133          // 24 bit bmp
00134             width = bmp->ImageWidth ;
00135             height = bmp->ImageHeight ;
00136 
00137             data = new PixelRGB[width*height] ;
00138 
00139             bmp->extract_data((int *)data) ;
00140          }
00141          else if((bmp_rc = new  MicrosoftRCBMP_RT(filename)) != NULL &&
00142             bmp_rc->read()){
00143          // Reduced clour (palette) bmp
00144             width = bmp_rc->ImageWidth ;
00145             height = bmp_rc->ImageHeight ;
00146 
00147             data = new PixelRGB[width*height] ;
00148 
00149             bmp_rc->extract_data((int *)data) ;
00150 
00151          }
00152          else if((bmp_mono = new  MicrosoftMonoBMP_RT(filename)) != NULL &&
00153             bmp_mono->read()){
00154          // Monochrome (b+w) bmp
00155             width = bmp_mono->ImageWidth ;
00156             height = bmp_mono->ImageHeight ;
00157 
00158             data = new PixelRGB[width*height] ;
00159 
00160             bmp_mono->extract_data((int *)data) ;
00161          }
00162     }
00163 
00164 
00165 }
00166 
00167 ImageRGB::~ImageRGB()
00171 {
00172     delete [] data;
00173 }
00174 
00175 
00176 void ImageRGB::set_pixel(unsigned int x, unsigned int y, PixelRGB p)
00183 {
00184         // Check that co-ords are valid. 
00185         if (x > width || y > height)
00186                 throw "Invalid Coordinates in method set_rgb";
00187         
00188         data[y * width + x] = p;
00189 }
00190 
00191 
00192 void ImageRGB::set_rgb(unsigned int x, unsigned int y, 
00193                     int red, int green, int blue)
00203 {
00204         // Check that co-ords are valid. 
00205         if (x > width || y > height)
00206                 throw "Invalid Coordinates in method set_rgb";
00207         
00208         unsigned int offset = y * width + x; 
00209 
00210         data[offset][RED]   = red;
00211         data[offset][GREEN] = green;
00212         data[offset][BLUE]  = blue;
00213 }
00214 
00215 
00216 void ImageRGB::set_field(unsigned int x, unsigned int y, 
00217                       FieldSelector fs, int value)
00226 {
00227         // Check that co-ords are valid.
00228         if (x > width || y > height)
00229                 throw "Invalid Coordinates in method set_field";
00230 
00231         unsigned int offset = y * width + x;
00232         data[offset][fs] = value;   
00233 }
00234 
00235 
00236 void ImageRGB::get_pixel(unsigned int x, unsigned int y, PixelRGB& p)
00245 {
00246         unsigned int offset = y * width + x;
00247 
00248         p[ RED ] = data[offset][RED];
00249         p[GREEN] = data[offset][GREEN];
00250         p[ BLUE] = data[offset][BLUE];
00251 }
00252 
00253 
00254 int ImageRGB::get_field(unsigned int x, unsigned int y, FieldSelector fs)
00263 {
00264         unsigned int offset = y * width + x;
00265         return data[offset][fs];
00266 }
00267 
00268 
00269 ImageRGB& ImageRGB::clear(int k)
00275 {
00276         int *start = data[0];
00277         int *end   = start + width * height * 3;
00278                 
00279         for (int *d = start; d < end; d++) *d = k;
00280 
00281         return *this;
00282 }
00283 
00284 
00285 ImageRGB& ImageRGB::clear(PixelRGB& p)
00291 {
00292         int *start = data[0];
00293         int *end   = start + width * height * 3;
00294                 
00295         for (int *d = start; d < end; d += 3) {
00296                 d[ RED ] = p[ RED ];
00297                 d[GREEN] = p[GREEN];
00298                 d[ BLUE] = p[ BLUE];
00299         }
00300         
00301         return *this;
00302 }
00303 
00304 
00305 ImageRGB& ImageRGB::clear_field(FieldSelector fs, int k)
00312 {
00313         int *start = data[0];
00314         int *end   = start + width * height * 3;
00315                 
00316         for (int *d = start + fs; d < end; d += 3) *d = k;
00317         
00318         return *this;
00319 }
00320     
00321 
00322 ImageRGB& ImageRGB::copy(ImageRGB& img)
00329 {
00330         /* check we're not trying to copy ourself */
00331         if (this == &img)
00332                 throw "Source and Destination are same Image";
00333         
00334         /* First check images are the same size and valid */
00335         if (width != img.width || height != img.height) 
00336                 throw "Difference in ImageRGB Dimensions";      
00337         
00338         /* Perform copy */
00339         memcpy(data, img.data, width * height * 3 * sizeof(int));
00340 
00341         return *this;
00342 }
00343 
00344 ImageRGB& ImageRGB::copy(ImageRGB&    img,
00345                          unsigned int min_x,
00346                          unsigned int min_y,
00347                          unsigned int max_x, 
00348                          unsigned int max_y,
00349                          unsigned int start_x,
00350                          unsigned int start_y)
00363 {
00364         unsigned int sx ;
00365         unsigned int sy ;
00366         unsigned int cntx ;
00367         unsigned int cnty ;
00368         int          *s_ptr ;
00369         int          *d_ptr ;
00370         unsigned int s_width ;
00371 
00372         s_width = img.get_width() ;
00373 
00374         /* check we're not trying to copy ourself */
00375         if (this == &img)
00376                 throw "Source and Destination are same Image";
00377 
00378         /* check sanity */
00379         if(min_x > max_x || min_y > max_y)
00380                 throw "Invalid arguments to ImageRGB::copy()" ;
00381 
00382         /* Check images are big enough */
00383         sx = max_x - min_x + 1 ;
00384         sy = max_y - min_y + 1 ;
00385 
00386         if(sx+start_x > width || 
00387            sy+start_y > height)
00388                 throw "Dest. image is not big enough" ;
00389 
00390          if(max_x > s_width ||
00391             max_y > img.get_height() )
00392                 throw "Source images is not big enough" ;
00393 
00394          for(cnty=0 ; cnty<sy ; cnty++){
00395 
00396                  s_ptr = (int*)img.data + (min_x + (min_y+cnty)*s_width)*3 ;
00397                  d_ptr = (int*)data + (start_x + (start_y+cnty)*width)*3 ;
00398 
00399                  for(cntx=0 ; cntx<sx ; cntx++){ 
00400 
00401                          *(d_ptr++) = *(s_ptr++) ;
00402                          *(d_ptr++) = *(s_ptr++) ;
00403                          *(d_ptr++) = *(s_ptr++) ;
00404                  }
00405          }
00406 
00407          return *this; 
00408 }
00409 
00410 bool ImageRGB::save(char *filename, FileFormat format)
00417 {
00418  
00419     bool            ret_val = true ;
00420 
00421     if(format == FORMAT_BMP_24 || format==FORMAT_BMP_ANY){
00422     // 24 Bit (full colour) bitmap (+default)
00423         MicrosoftBMP_RT *btmp;
00424         btmp = new MicrosoftBMP_RT(filename);
00425         if(btmp==NULL) ret_val = false ;
00426         else if(!btmp->set_size(width,height)) ret_val = false ;
00427         else{
00428             btmp->put_data((int *)data) ;
00429             ret_val = btmp->write();
00430         }
00431         delete btmp ;
00432     }
00433     else if(format == FORMAT_BMP_RC){
00434     // Greyscale bitmap
00435         MicrosoftRCBMP_RT *btmp;
00436         btmp = new MicrosoftRCBMP_RT(filename);
00437         if(btmp==NULL) ret_val = false ;
00438         else if(!btmp->set_size(width,height)) ret_val = false ;
00439         else if(!btmp->set_palette_grey256()) ret_val = false ;
00440         else{
00441             btmp->put_data((int *)data) ;
00442             ret_val = btmp->write();
00443         }
00444         delete btmp ;
00445     }
00446     else if(format == FORMAT_BMP_MONO){
00447     // Monochrome bitmap
00448         MicrosoftMonoBMP_RT *btmp;
00449         btmp = new MicrosoftMonoBMP_RT(filename);
00450         if(btmp==NULL) ret_val = false ;
00451         else if(!btmp->set_size(width,height)) ret_val = false ;
00452         else{
00453             btmp->put_data((int *)data) ;
00454             ret_val = btmp->write();
00455         }
00456         delete btmp ;
00457     }
00458 
00459     return ret_val ;
00460 }
00461 
00462 bool ImageRGB::enhance_contrast()
00467 {
00468     unsigned int cnt ;
00469     int          max_val = 0 ;
00470     int          *ptr ;
00471     float        fact ;
00472 
00473     ptr = (int*)data ; 
00474     for(cnt=0 ; cnt<width*height*3 ; cnt++, ptr++){
00475         if(*ptr > max_val) max_val = *ptr ;
00476     }
00477    
00478     fact = 255.0 / (float)max_val ;
00479 
00480     ptr = (int*)data ;
00481     for(cnt=0 ; cnt<width*height*3 ; cnt++, ptr++){
00482         *ptr = (int)((float)(*ptr) * fact) ;
00483     }
00484 
00485     return true ;
00486 } 
00487 
00488 
00489 void ImageRGB::normalise_colourspace(int scale_factor)
00494 {
00495     unsigned int cnt ;
00496     int          *ptr ;
00497     int          tot ;
00498 
00499     ptr = (int*)data ; 
00500     for(cnt=0 ; cnt<width*height ; cnt++){
00501         tot = *ptr ;
00502         tot += *(ptr+1) ;
00503         tot += *(ptr+2) ;
00504 
00505         if(tot > 0){
00506             *ptr *= scale_factor ;
00507             *(ptr++) /= tot ; 
00508             *ptr *= scale_factor ;
00509             *(ptr++) /= tot ; 
00510             *ptr *= scale_factor ;
00511             *(ptr++) /= tot ; 
00512         }
00513     }
00514 } 
00515 
00516 void ImageRGB::quick_grey_and_scale_down(unsigned int scale_fact,
00517                                          ImageGrey&   img)     
00521 {
00522     unsigned int xcnt, ycnt ;
00523     PixelRGB*    pix_ptr ;
00524     int*         op_ptr ;
00525     int*         val_ptr ;
00526 
00527     op_ptr = img.brightness ;
00528     for(ycnt=0 ; ycnt<height ; ycnt+=scale_fact){
00529         pix_ptr = &(data[ycnt*width]) ;
00530         for(xcnt=0 ; xcnt<width ; 
00531             xcnt+=scale_fact, op_ptr++, pix_ptr+=scale_fact){
00532             val_ptr = (int*)pix_ptr ;
00533             *op_ptr = *(val_ptr++) ; 
00534             *op_ptr += *(val_ptr++) ; 
00535             *op_ptr += *val_ptr ; 
00536             *op_ptr /= 3 ; 
00537         }
00538     }
00539 }
00540 
00541 void ImageRGB::histogram_segment(Histogram &hist,
00542                                  float     threshold,
00543                                  ImageRGB& result)
00550 {
00551     unsigned int cnt ;
00552     PixelRGB*    pix_ptr ;
00553     PixelRGB*    res_ptr ;
00554     PixelRGB     p_true(255,255,255) ;
00555     PixelRGB     p_false(0,0,0) ; 
00556     float        prob ;
00557 
00558     for(cnt=0, pix_ptr=data, res_ptr=result.data ;
00559         cnt<width*height ; cnt++, pix_ptr++, res_ptr++){
00560         prob = hist.get_mapped_value((unsigned int*) pix_ptr);
00561         if(prob > threshold) *res_ptr = p_true ;
00562         else                 *res_ptr = p_false ;
00563     }
00564 }
00565 
00566 void ImageRGB::histogram_segment(Histogram &hist,
00567                                  float     threshold,
00568                                  bool*     result)
00575 {
00576     unsigned int cnt ;
00577     PixelRGB*    pix_ptr ;
00578     bool*        res_ptr ;
00579     float        prob ;
00580 
00581     for(cnt=0, pix_ptr=data, res_ptr=result ;
00582         cnt<width*height ; cnt++, pix_ptr++, res_ptr++){
00583         prob = hist.get_mapped_value((unsigned int*) pix_ptr);
00584         if(prob > threshold) *res_ptr = true ;
00585         else                 *res_ptr = false ;
00586     }
00587 }
00588 
00589 
00590 /****************************************************************************\
00591  *       Extra doxygen comments and information relating to this file       *
00592 \****************************************************************************/
00593  

Generated at Fri Aug 13 17:29:21 2004 for libRTImage by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001