Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Representations/Perception/Image.cpp

Go to the documentation of this file.
00001 /**
00002  * @file Image.cpp
00003  *
00004  * Implementation of class Image.
00005  */
00006 
00007 #include "Platform/GTAssert.h"
00008 #include "Tools/Streams/InOut.h"
00009 #include "Image.h"
00010 #include "Tools/Math/Common.h"
00011 
00012 
00013 Image::Image() : frameNumber(0)
00014 {
00015   for(int y = 0; y < cameraInfo.resolutionHeight; ++y)
00016     for(int x = 0; x < cameraInfo.resolutionWidth; ++x)
00017     {
00018       image[y][0][x] = 0;
00019       image[y][1][x] = 128;
00020       image[y][2][x] = 128;
00021       image[y][3][x] = 128;
00022       image[y][4][x] = 128;
00023       image[y][5][x] = 128;
00024     }
00025 }
00026 
00027 Image::~Image()
00028 {
00029 }
00030 
00031 bool Image::hasColorTable(void)
00032 {
00033   if (colorTable) return true;
00034   else return false;
00035 }
00036 
00037 
00038 //int Image::getHeight(void)
00039 //{  return height; }
00040 
00041 void Image::setColorTable(const ColorTable* ct)
00042 {
00043   colorTable = ct;
00044 }
00045 
00046 
00047 char Image::getClassifiedColor(int x, int y)
00048 {
00049   if (colorTable) 
00050     return colorTable->getColorClass(image[y][0][x], image[y][1][x], image[y][2][x]);
00051   else return -1;
00052 }
00053 
00054 void Image::convertFromYUVToRGB(const Image& yuvImage)
00055 {
00056   Image::convertFromYCbCrToRGB(yuvImage);
00057   /*
00058   int Y,U,V;
00059   int R,G,B;
00060   for(int y=0; y < yuvImage.cameraInfo.resolutionHeight; y++)
00061   {
00062     for(int x=0; x < yuvImage.cameraInfo.resolutionWidth; x++)
00063     {
00064       Y = yuvImage.image[y][0][x];
00065       U = yuvImage.image[y][1][x];
00066       V = yuvImage.image[y][2][x];
00067       R = (int)(Y + 1.140 * (U - 128));
00068       G = (int)(Y - 0.394 * (V - 128) - 0.581 * (U - 128));
00069       B = (int)(Y + 2.028 * (V - 128));
00070       if(R < 0) R = 0; if(R > 255) R = 255;
00071       if(G < 0) G = 0; if(G > 255) G = 255;
00072       if(B < 0) B = 0; if(B > 255) B = 255;
00073       image[y][0][x] = (unsigned char)R;
00074       image[y][1][x] = (unsigned char)G;
00075       image[y][2][x] = (unsigned char)B;
00076     }
00077   }
00078   this->cameraInfo = yuvImage.cameraInfo;
00079   */
00080 }
00081 
00082 void Image::convertFromYCbCrToRGB(const Image& ycbcrImage)
00083 {
00084   for(int y=0; y < ycbcrImage.cameraInfo.resolutionHeight; y++)
00085     for(int x=0; x < ycbcrImage.cameraInfo.resolutionWidth; x++)
00086       convertFromYCbCrToRGB(ycbcrImage.image[y][0][x],
00087                             ycbcrImage.image[y][1][x],
00088                             ycbcrImage.image[y][2][x],
00089                             image[y][0][x],
00090                             image[y][1][x],
00091                             image[y][2][x]);
00092   this->cameraInfo = ycbcrImage.cameraInfo;
00093 }
00094 
00095 void Image::convertFromRGBToYUV(const Image& rgbImage)
00096 {
00097   int Y,U,V;
00098   int R,G,B;
00099   
00100   for(int y=0; y < rgbImage.cameraInfo.resolutionHeight; y++)
00101   {
00102     for(int x=0; x < rgbImage.cameraInfo.resolutionWidth; x++)
00103     {
00104       R = rgbImage.image[y][0][x];
00105       G = rgbImage.image[y][1][x];
00106       B = rgbImage.image[y][2][x];
00107       
00108       // RGB2YUV Method 1
00109       //Y =       (int) ( 0.299 * R + 0.587 * G + 0.114 * B);
00110       //V = 127 + (int) (-0.147 * R - 0.289 * G + 0.437 * B);
00111       //U = 127 + (int) ( 0.615 * R - 0.515 * G - 0.100 * B);
00112       
00113       // RGB2YUV Method 2
00114       Y =       (int)( 0.2990 * R + 0.5870 * G + 0.1140 * B);
00115       V = 127 + (int)(-0.1687 * R - 0.3313 * G + 0.5000 * B);
00116       U = 127 + (int)( 0.5000 * R - 0.4187 * G - 0.0813 * B);
00117       
00118 //     if (R+G+B != 3*204)
00119 //         int i=0;
00120 
00121       if(Y < 0) Y = 0; if(Y > 255) Y = 255;
00122       if(U < 0) U = 0; if(U > 255) U = 255;
00123       if(V < 0) V = 0; if(V > 255) V = 255;
00124 
00125       image[y][0][x] = (unsigned char)Y;
00126       image[y][1][x] = (unsigned char)U;
00127       image[y][2][x] = (unsigned char)V;
00128     }
00129   }
00130   this->cameraInfo = rgbImage.cameraInfo;
00131 }
00132 
00133 void Image::convertFromYCbCrToHSI(const Image& ycbcrImage)
00134 {
00135   for(int y=0; y < ycbcrImage.cameraInfo.resolutionHeight; y++)
00136     for(int x=0; x < ycbcrImage.cameraInfo.resolutionWidth; x++)
00137       convertFromYCbCrToHSI(ycbcrImage.image[y][0][x],
00138                             ycbcrImage.image[y][1][x],
00139                             ycbcrImage.image[y][2][x],
00140                             image[y][0][x],
00141                             image[y][1][x],
00142                             image[y][2][x]);
00143   this->cameraInfo = ycbcrImage.cameraInfo;
00144 }
00145 
00146 void Image::convertFromYUVToTSL(const Image& yuvImage)
00147 {
00148   int Y,U,V;
00149   int T,S,L;
00150   double  y_in, u_in, v_in, tmp, tmp_r, tmp_g, tmp_b, t_out, s_out;
00151   
00152   for(int y = 0; y < yuvImage.cameraInfo.resolutionHeight; y++)
00153   {
00154     for(int x = 0; x < yuvImage.cameraInfo.resolutionWidth; x++)
00155     {
00156       Y = yuvImage.image[y][0][x];
00157       U = yuvImage.image[y][1][x];
00158       V = yuvImage.image[y][2][x];
00159       
00160       
00161       const double pi2_div = 0.15915494309189533576888376337251;  /* 1.0 / (PI * 2.0) */
00162       
00163       y_in = (double) Y;
00164       u_in = (double) U;
00165       v_in = (double) V;
00166       u_in -= 128.0;
00167       v_in -= 128.0;
00168       tmp = 1.0 / (4.3403 * y_in +  2.0 * u_in + v_in);
00169       tmp_r = (-0.6697 * u_in + 1.6959 * v_in) * tmp;
00170       tmp_g = (-1.168  * u_in - 1.3626 * v_in) * tmp;
00171       tmp_b = ( 1.8613 * u_in - 0.331  * v_in) * tmp;
00172       if (tmp_g > 0.0)
00173       {
00174         t_out = (atan2(tmp_r, tmp_g) * pi2_div + 0.25) * 255.0;
00175       }
00176       else if (tmp_g < 0.0)
00177       {
00178         t_out = (atan2(-tmp_r, -tmp_g) * pi2_div + 0.75) * 255.0;
00179       }
00180       else
00181       {
00182         t_out = 0.0;
00183       }
00184       s_out = sqrt(1.8 * (tmp_r * tmp_r + tmp_g * tmp_g + tmp_b * tmp_b)) * 255.0;
00185       
00186       /* Crop T and S values */
00187       if (t_out < 0.0)
00188       {
00189         t_out = 0.0;
00190       }
00191       else if (t_out > 255.0)
00192       {
00193         t_out = 255.0;
00194       }
00195       if (s_out < 0.0)
00196       {
00197         s_out = 0.0;
00198       }
00199       else if (s_out > 255.0)
00200       {
00201         s_out = 255.0;
00202       }
00203       
00204       T = (unsigned char) t_out;
00205       S = (unsigned char) s_out;
00206       L = Y;
00207       
00208       image[y][0][x] = (unsigned char)T;
00209       image[y][1][x] = (unsigned char)S;
00210       image[y][2][x] = (unsigned char)L;
00211     }
00212   }
00213   this->cameraInfo = yuvImage.cameraInfo;
00214 }
00215 
00216 unsigned char Image::getHighResY(int x, int y) const
00217 {
00218   if ((x & 1) == 0)
00219     if ((y & 1) == 0)
00220     {
00221       // Pixel Top Left       = LL - LH - HL + HH 
00222       y=y>>1;x=x>>1;
00223       return (unsigned char) ((int)image[y][0][x] - (int)image[y][3][x] - 128 - (int)image[y][4][x] - 128 + (int)image[y][5][x] - 128);
00224     } 
00225     else
00226     {
00227       // Pixel Bottom Left    = LL + LH - HL - HH
00228       y=y>>1;x=x>>1;
00229       return (unsigned char)((int)image[y][0][x] + (int)image[y][3][x] - 128 - (int)image[y][4][x] - 128 - (int)image[y][5][x] - 128);
00230     }
00231   else
00232     if ((y & 1) == 0)
00233     {
00234       // Pixel Top Right      = LL - LH + HL - HH
00235       y=y>>1;x=x>>1;
00236       return (unsigned char)((int)image[y][0][x] - (int)image[y][3][x] - 128 + (int)image[y][4][x] - 128 - (int)image[y][5][x] - 128);
00237     }
00238     else
00239     {
00240       // Pixel Bottom Right   = LL + LH + HL + HH
00241       y=y>>1;x=x>>1;
00242       return (unsigned char)((int)image[y][0][x] + (int)image[y][3][x] - 128 + (int)image[y][4][x] - 128 + (int)image[y][5][x] - 128);
00243     }
00244 }
00245 
00246 void Image::setHighResY(int x, int y, unsigned char tl, unsigned char bl, unsigned char tr, unsigned char br) 
00247 {
00248   image[y][0][x] = ((int) tl + (int)bl + (int)tr + (int)br) / 4;
00249   image[y][3][x] = ((int)-tl + (int)bl - (int)tr + (int)br) / 4 + 128;
00250   image[y][4][x] = ((int)-tl - (int)bl + (int)tr + (int)br) / 4 + 128;
00251   image[y][5][x] = ((int) tl - (int)bl - (int)tr + (int)br) / 4 + 128;
00252 }
00253 
00254 Out& operator<<(Out& stream, const Image& image)
00255 {
00256   stream 
00257     << image.cameraInfo.resolutionWidth 
00258     << image.cameraInfo.resolutionHeight 
00259     << image.frameNumber;
00260 
00261   for(int y = 0; y < image.cameraInfo.resolutionHeight; ++y)
00262     for(int c = 0; c < 6; ++c)
00263       stream.write(&image.image[y][c][0], image.cameraInfo.resolutionWidth);
00264 
00265   return stream;
00266 }
00267 
00268 void Image::setCameraInfo()
00269 {
00270   if(cameraInfo.resolutionWidth == cameraResolutionWidth_ERS210)
00271   {
00272     cameraInfo.openingAngleWidth = openingAngleWidth_ERS210;
00273     cameraInfo.openingAngleHeight = openingAngleHeight_ERS210;
00274     cameraInfo.focalLength = focalLength_ERS210;
00275     cameraInfo.opticalCenter.x = opticalCenterX_ERS210;
00276     cameraInfo.opticalCenter.y = opticalCenterY_ERS210;
00277     cameraInfo.secondOrderRadialDistortion = secondOrderRadialDistortion_ERS210;
00278     cameraInfo.fourthOrderRadialDistortion = fourthOrderRadialDistortion_ERS210;
00279   }
00280   else if(cameraInfo.resolutionWidth == cameraResolutionWidth_ERS7)
00281   {
00282     cameraInfo.openingAngleWidth = openingAngleWidth_ERS7;
00283     cameraInfo.openingAngleHeight = openingAngleHeight_ERS7;
00284     cameraInfo.focalLength = focalLength_ERS7;
00285     cameraInfo.opticalCenter.x = opticalCenterX_ERS7;
00286     cameraInfo.opticalCenter.y = opticalCenterY_ERS7;
00287     cameraInfo.secondOrderRadialDistortion = secondOrderRadialDistortion_ERS7;
00288     cameraInfo.fourthOrderRadialDistortion = fourthOrderRadialDistortion_ERS7;
00289   }
00290   else
00291   {
00292     ASSERT(false); // unknown image size
00293   }
00294 #ifdef _WIN32
00295   if(frameNumber > 0x10000000) // is simulated image
00296   {
00297     frameNumber -= 0x10000000;
00298     cameraInfo.focalLength = cameraInfo.resolutionHeight / tan(cameraInfo.openingAngleHeight / 2.0) / 2.0;
00299     cameraInfo.opticalCenter = Vector2<double>(cameraInfo.resolutionWidth / 2, cameraInfo.resolutionHeight / 2);
00300     cameraInfo.secondOrderRadialDistortion = cameraInfo.fourthOrderRadialDistortion = 0;
00301     cameraInfo.simulated = true;
00302   }
00303 #endif
00304   cameraInfo.focalLengthInv = 1/cameraInfo.focalLength;
00305   cameraInfo.focalLenPow2 = cameraInfo.focalLength*cameraInfo.focalLength;  
00306   cameraInfo.focalLenPow4 = cameraInfo.focalLenPow2*cameraInfo.focalLenPow2;
00307 }
00308 
00309 /*
00310  * Change log :
00311  * 
00312  * $Log: Image.cpp,v $
00313  * Revision 1.2  2004/05/26 14:06:32  roefer
00314  * Corrected initialization of addition y channels in default constructor
00315  * Flag for simulated images added
00316  *
00317  * Revision 1.1.1.1  2004/05/22 17:25:50  cvsadm
00318  * created new repository GT2004_WM
00319  *
00320  * Revision 1.13  2004/05/13 06:56:23  roefer
00321  * Simulation of PSDs added
00322  * Special intrisic parameters for simulated images
00323  *
00324  * Revision 1.12  2004/05/07 09:29:55  nistico
00325  * Bug fixed
00326  *
00327  * Revision 1.11  2004/05/01 17:09:33  roefer
00328  * Streamlined HSI stuff
00329  *
00330  * Revision 1.10  2004/04/28 13:24:25  thomas
00331  * modified: conversion from yuv now uses ycbcr-transformation
00332  *
00333  * Revision 1.9  2004/04/27 17:22:06  thomas
00334  * added convertFromYCbCr2RGB for images
00335  *
00336  * Revision 1.8  2004/04/07 13:00:44  risler
00337  * ddd checkin after go04 - second part
00338  *
00339  * Revision 1.5  2004/04/07 11:44:05  risler
00340  * added sending low res images
00341  * added Image::setCameraInfo
00342  *
00343  * Revision 1.4  2004/04/06 13:19:35  risler
00344  * cleaned up and improved high resolution image support
00345  *
00346  * Revision 1.3  2004/03/29 20:45:16  risler
00347  * bugfix getHighResY
00348  *
00349  * Revision 1.2  2004/03/29 15:19:03  Marc
00350  * Intruduced the Black and White Image
00351  * Normal Images (not Jpeg) images were now send as Color Image with BW
00352  *
00353  * Revision 1.7  2004/01/04 16:28:46  juengel
00354  * Conversion methods copy cameraInfo now.
00355  *
00356  * Revision 1.6  2003/12/30 20:12:03  roefer
00357  * Image size is now 208 x 160. Smaller images are placed in the upper left corner
00358  *
00359  * Revision 1.5  2003/12/15 11:47:06  juengel
00360  * Introduced CameraInfo
00361  *
00362  * Revision 1.4  2003/12/09 21:17:55  roefer
00363  * Platform-dependent code moved to GUI (release code) project
00364  *
00365  * Revision 1.3  2003/12/02 19:30:44  roefer
00366  * yuv<->rgb conversion speed improved
00367  *
00368  * Revision 1.2  2003/10/26 01:19:55  kindler
00369  * - fixed a clamping bug in convertFromRGBToYUV()  (an Y was mistyped as a V)
00370  * - tabs converted to spaces
00371  *
00372  * Revision 1.1  2003/10/07 10:09:36  cvsadm
00373  * Created GT2004 (M.J.)
00374  *
00375  * Revision 1.1.1.1  2003/07/02 09:40:22  cvsadm
00376  * created new repository for the competitions in Padova from the 
00377  * tamara CVS (Tuesday 2:00 pm)
00378  *
00379  * removed unused solutions
00380  *
00381  * Revision 1.12  2003/05/05 11:59:21  dueffert
00382  * spelling corrected
00383  *
00384  * Revision 1.11  2003/03/19 17:20:20  roefer
00385  * Nonsense streaming operator removed
00386  *
00387  * Revision 1.10  2003/03/06 11:57:32  dueffert
00388  * re-order warning removed
00389  *
00390  * Revision 1.9  2003/02/24 22:30:54  juengel
00391  * Added convertion methods for TSL and HSI
00392  *
00393  * Revision 1.8  2003/02/19 14:59:54  roefer
00394  * pColorTable -> colorTable
00395  *
00396  * Revision 1.7  2003/02/18 21:29:17  osterhues
00397  * Changed all instances of ColorTable64 to new base class ColorTable
00398  *
00399  * Revision 1.6  2003/02/17 11:06:49  dueffert
00400  * warnings removed, greenshills backport
00401  *
00402  * Revision 1.5  2003/01/09 16:23:58  dueffert
00403  * no message
00404  *
00405  * Revision 1.4  2003/01/09 13:07:16  jhoffman
00406  * no message
00407  *
00408  * Revision 1.3  2002/12/15 23:33:02  dueffert
00409  * rgb-yuv-convertion moved to Image
00410  *
00411  * Revision 1.2  2002/09/17 23:55:20  loetzsch
00412  * - unraveled several datatypes
00413  * - changed the WATCH macro
00414  * - completed the process restructuring
00415  *
00416  * Revision 1.1  2002/09/10 15:26:40  cvsadm
00417  * Created new project GT2003 (M.L.)
00418  * - Cleaned up the /Src/DataTypes directory
00419  * - Removed Challenge Code
00420  * - Removed processing of incoming audio data
00421  * - Renamed AcousticMessage to SoundRequest
00422  *
00423  * Revision 1.4  2002/08/30 13:33:05  dueffert
00424  * removed unused includes
00425  *
00426  * Revision 1.3  2002/08/29 15:28:31  loetzsch
00427  * removed #include <iostream.h>
00428  *
00429  * Revision 1.2  2002/08/29 14:03:12  dueffert
00430  * includes in correct case, system includes in <>
00431  *
00432  * Revision 1.1.1.1  2002/05/10 12:40:13  cvsadm
00433  * Moved GT2002 Project from ute to tamara.
00434  *
00435  * Revision 1.7  2002/04/03 14:18:52  juengel
00436  * camera matrix and odometry data added to streaming operator for images
00437  *
00438  * Revision 1.6  2002/04/02 13:10:18  dueffert
00439  * big change: odometryData and cameraMatrix in image now, old logfiles may be obsolete
00440  *
00441  * Revision 1.5  2002/02/27 07:00:53  roefer
00442  * Image initialized
00443  *
00444  * Revision 1.4  2001/12/14 16:03:58  juengel
00445  * Im Konstruktor werden width( fixed ), height( fixed ), frameNumber(0) gesetzt.
00446  *
00447  * Revision 1.3  2001/12/12 18:08:55  loetzsch
00448  * Streaming- Operatoren für Bilder eingebaut, DebugKeyTable nicht- statisch gemacht, Debuggin Mechanismen weitergemacht, Bilder aus Logfiles in RobotControl anzeigen, Logfiles in HU1/Debug auf den Stick schreiben
00449  *
00450  * Revision 1.2  2001/12/10 17:47:05  risler
00451  * change log added
00452  *
00453  */

Generated on Thu Sep 23 19:57:36 2004 for GT2004 by doxygen 1.3.6