img_cs_base.h
Go to the documentation of this file.
00001 #ifndef IMG_CS_BASE_H_
00002 #define IMG_CS_BASE_H_
00003 
00004 // warning: temporary name/location, will change in near future
00005 
00006 #include "img/img.h"
00007 
00008 namespace img {
00009 
00010 // RGB: GAMMA -> LINEAR 
00011 template<int Channels, typename ScalarType1, bool Safe1,typename ScalarType2, bool Safe2> 
00012 inline void convert_gamma_precompensated_rgb_to_linear_rgb(const img::Image<Channels,ScalarType1,Safe1> &gamma_precompensated_rgb_image, img::Image<Channels,ScalarType2,Safe2> &linear_rgb_image)
00013 {
00014   assert(gamma_precompensated_rgb_image.isValid());
00015   assert(!gamma_precompensated_rgb_image.attributes.hasColorspace(SRGB));
00016   assert(gamma_precompensated_rgb_image.attributes.hasRange(0.0,1.0));
00017   ScalarType2 old_gamma;
00018   gamma_precompensated_rgb_image.attributes.getGamma(old_gamma);
00019   assert((old_gamma>0.0)&&(old_gamma<1.0));
00020   if(Safe1 || Safe2){
00021     if(!gamma_precompensated_rgb_image.isValid())  throw ImageException("Invalid rgb image");
00022     if(gamma_precompensated_rgb_image.attributes.hasColorspace(SRGB)) throw ImageException("Invalid colorspace attribute");
00023     if(!gamma_precompensated_rgb_image.attributes.hasRange(0,1)) throw ImageException("Invalid range attribute");
00024     if(!((old_gamma>0.0)&&(old_gamma<1.0))) throw ImageException("Invalid gamma attribute");
00025   }
00026   linear_rgb_image.setZero(gamma_precompensated_rgb_image.width(),gamma_precompensated_rgb_image.height());
00027   linear_rgb_image.attributes=gamma_precompensated_rgb_image.attributes;
00028   
00029   for(int channel=0; channel<Channels; ++channel)
00030     for(int x_coord=0; x_coord<gamma_precompensated_rgb_image.width(); ++x_coord)
00031       for(int y_coord=0; y_coord<gamma_precompensated_rgb_image.height(); ++y_coord){
00032         linear_rgb_image.setValue(x_coord,y_coord,channel, pow(ScalarType2(gamma_precompensated_rgb_image.getValue(x_coord,y_coord,channel)),ScalarType2(1.0)/old_gamma));
00033       }
00034   linear_rgb_image.attributes.setGamma(ScalarType2(1.0));
00035 }
00036 
00037 // RGB: LINEAR -> GAMMA
00038 // when converting from linear to gamma precompensated the gamma parameter mus be in range (0.0,1.0)
00039 template<int Channels, typename ScalarType1, bool Safe1,typename ScalarType2, bool Safe2> 
00040 inline void convert_linear_rgb_to_gamma_precompensated_rgb(const img::Image<Channels,ScalarType1,Safe1> &linear_rgb_image, img::Image<Channels,ScalarType2,Safe2> &gamma_precompensated_rgb_image, ScalarType2 gamma=ScalarType2(1.0/2.2))
00041 {
00042   assert(linear_rgb_image.isValid());
00043   assert(!linear_rgb_image.attributes.hasColorspace(SRGB));
00044   assert(linear_rgb_image.attributes.hasRange(0.0,1.0));
00045   assert(linear_rgb_image.attributes.hasGamma(1.0));
00046   assert((gamma>0.0)&&(gamma<1.0));
00047   if(Safe1 || Safe2){
00048     if(!linear_rgb_image.isValid())  throw img::ImageException("Invalid rgb image");
00049     if(linear_rgb_image.attributes.hasColorspace(SRGB)) throw ImageException("Invalid colorspace attribute");
00050     if(!linear_rgb_image.attributes.hasRange(0.0,1.0)) throw ImageException("Invalid range attribute");
00051     if(!linear_rgb_image.attributes.hasGamma(1.0)) throw ImageException("Invalid gamma attribute");
00052     if(!((gamma>0.0)&&(gamma<1.0))) throw ImageException("Invalid gamma parameter");
00053   }
00054   gamma_precompensated_rgb_image.setZero(linear_rgb_image.width(),linear_rgb_image.height());
00055   gamma_precompensated_rgb_image.attributes=linear_rgb_image.attributes;
00056   
00057   for(int channel=0; channel<Channels; ++channel)
00058     for(int x_coord=0; x_coord<linear_rgb_image.width(); ++x_coord)
00059       for(int y_coord=0; y_coord<linear_rgb_image.height(); ++y_coord){
00060         gamma_precompensated_rgb_image.setValue(x_coord,y_coord,channel, pow(ScalarType2(linear_rgb_image.getValue(x_coord,y_coord,channel)),gamma));
00061       }
00062   gamma_precompensated_rgb_image.attributes.setGamma(gamma);
00063 }
00064 
00065 // SRGB: GAMMA -> LINEAR 
00066 template<int Channels, typename ScalarType1, bool Safe1,typename ScalarType2, bool Safe2> 
00067 inline void convert_gamma_precompensated_srgb_to_linear_srgb(const img::Image<Channels,ScalarType1,Safe1> &gamma_precompensated_srgb_image, img::Image<Channels,ScalarType2,Safe2> &linear_srgb_image)
00068 {
00069   assert(gamma_precompensated_srgb_image.isValid());
00070   assert(gamma_precompensated_srgb_image.attributes.hasColorspace(SRGB));
00071   assert(gamma_precompensated_srgb_image.attributes.hasRange(0.0,1.0));
00072   assert(!gamma_precompensated_srgb_image.attributes.hasGamma(1.0));
00073   if(Safe1 || Safe2){
00074     if(!gamma_precompensated_srgb_image.isValid())  throw ImageException("Invalid rgb image");
00075     if(!gamma_precompensated_srgb_image.attributes.hasColorspace(SRGB)) throw ImageException("Invalid colorspace attribute");
00076     if(!gamma_precompensated_srgb_image.attributes.hasRange(0,1)) throw ImageException("Invalid range attribute");
00077     if(gamma_precompensated_srgb_image.attributes.hasGamma(1.0)) throw ImageException("Invalid gamma attribute");
00078   }
00079   linear_srgb_image.setZero(gamma_precompensated_srgb_image.width(),gamma_precompensated_srgb_image.height());
00080   linear_srgb_image.attributes=gamma_precompensated_srgb_image.attributes;
00081   
00082   for(int channel=0; channel<Channels; ++channel)
00083     for(int x_coord=0; x_coord<gamma_precompensated_srgb_image.width(); ++x_coord)
00084       for(int y_coord=0; y_coord<gamma_precompensated_srgb_image.height(); ++y_coord){
00085         ScalarType2 value = ScalarType2(gamma_precompensated_srgb_image.getValue(x_coord,y_coord,channel));
00086         if(value<=ScalarType2(0.04045))
00087           value = value / ScalarType2(12.92);
00088         else
00089           value = pow( (value+ScalarType2(0.055)) / ScalarType2(1.055), ScalarType2(2.4) );
00090         linear_srgb_image.setValue(x_coord, y_coord, channel, value);
00091       }
00092   linear_srgb_image.attributes.setGamma(ScalarType2(1.0));
00093 }
00094 
00095 // SRGB: LINEAR -> GAMMA
00096 template<int Channels, typename ScalarType1, bool Safe1,typename ScalarType2, bool Safe2> 
00097 inline void convert_linear_srgb_to_gamma_precompensated_srgb(const img::Image<Channels,ScalarType1,Safe1> &linear_srgb_image, img::Image<Channels,ScalarType2,Safe2> &gamma_precompensated_srgb_image)
00098 {
00099   assert(linear_srgb_image.isValid());
00100   assert(linear_srgb_image.attributes.hasColorspace(SRGB));
00101   assert(linear_srgb_image.attributes.hasRange(0.0,1.0));
00102   assert(linear_srgb_image.attributes.hasGamma(1.0));
00103   if(Safe1 || Safe2){
00104     if(!linear_srgb_image.isValid())  throw img::ImageException("Invalid rgb image");
00105     if(!linear_srgb_image.attributes.hasColorspace(SRGB)) throw ImageException("Invalid colorspace attribute");
00106     if(!linear_srgb_image.attributes.hasRange(0.0,1.0)) throw ImageException("Invalid range attribute");
00107     if(!linear_srgb_image.attributes.hasGamma(1.0)) throw ImageException("Invalid gamma attribute");
00108   }
00109   gamma_precompensated_srgb_image.setZero(linear_srgb_image.width(),linear_srgb_image.height());
00110   gamma_precompensated_srgb_image.attributes=linear_srgb_image.attributes;
00111   
00112   for(int channel=0; channel<Channels; ++channel)
00113     for(int x_coord=0; x_coord<linear_srgb_image.width(); ++x_coord)
00114       for(int y_coord=0; y_coord<linear_srgb_image.height(); ++y_coord){
00115         ScalarType2 value = ScalarType2(linear_srgb_image.getValue(x_coord,y_coord,channel));
00116         if(value<=ScalarType2(0.0031308))
00117           value =  value * ScalarType2(12.92);
00118         else
00119           value = (ScalarType2(1.055) * pow(value, ScalarType2(1.0/2.4))) - ScalarType2(0.055);
00120         gamma_precompensated_srgb_image.setValue(x_coord, y_coord, channel, value);
00121       }
00122   gamma_precompensated_srgb_image.attributes.setGamma(ScalarType2(2.2)); // approssimation
00123 }
00124 
00125 // SRGB -> XYZ
00126 template<typename ScalarType1, bool Safe1,typename ScalarType2, bool Safe2> 
00127 inline void convert_srgb_to_xyz(const img::Image<3,ScalarType1,Safe1> &rgb_image, img::Image<3,ScalarType2,Safe2> &xyz_image)
00128 {
00129   assert( rgb_image.isValid());
00130   assert( rgb_image.attributes.hasRange(0.0,1.0));
00131   assert( rgb_image.attributes.hasGamma(1.0));
00132   assert( rgb_image.attributes.hasColorspace(img::RGB) );
00133   if(Safe1 || Safe2){
00134     if(!rgb_image.isValid())  throw img::ImageException("Invalid rgb image");
00135     if(!rgb_image.attributes.hasRange(0.0,1.0))  throw img::ImageException("Invalid range attribute");
00136     if(!rgb_image.attributes.hasGamma(1.0))  throw img::ImageException("Invalid gamma attribute");
00137     if(!rgb_image.attributes.hasColorspace(img::RGB))  throw img::ImageException("Invalid colorspace attribute");
00138   }
00139   xyz_image.setZero(rgb_image.width(),rgb_image.height());
00140   xyz_image.attributes=rgb_image.attributes;
00141 
00142   for(int x_coord=0; x_coord<rgb_image.width(); ++x_coord)
00143     for(int y_coord=0; y_coord<rgb_image.height(); ++y_coord){
00144       const ScalarType2 R = static_cast<ScalarType2>(rgb_image.getValue(x_coord,y_coord,0));
00145       const ScalarType2 G = static_cast<ScalarType2>(rgb_image.getValue(x_coord,y_coord,1));
00146       const ScalarType2 B = static_cast<ScalarType2>(rgb_image.getValue(x_coord,y_coord,2));
00147 
00148       xyz_image.setValue(x_coord,y_coord,0, ( 0.412453f*R + 0.357580f*G + 0.180423f*B ) );
00149       xyz_image.setValue(x_coord,y_coord,1, ( 0.212671f*R + 0.715160f*G + 0.072169f*B ) );
00150       xyz_image.setValue(x_coord,y_coord,2, ( 0.019334f*R + 0.119193f*G + 0.950227f*B ) );
00151     }
00152     xyz_image.setColorspace(img::CIE_XYZ);
00153 }
00154 
00155 // XYZ -> SRGB
00156 template<typename ScalarType1, bool Safe1,typename ScalarType2, bool Safe2> 
00157 inline void convert_xyz_to_rgb(const img::Image<3,ScalarType1,Safe1> &xyz_image, img::Image<3,ScalarType2,Safe2> &rgb_image)
00158 {
00159   assert( xyz_image.isValid());
00160   assert( xyz_image.attributes.hasRange(0.0,1.0));
00161   assert( xyz_image.attributes.hasGamma(1.0));
00162   assert( xyz_image.attributes.hasColorspace(img::CIE_XYZ) );
00163   
00164   if(Safe1 || Safe2){
00165     if(!xyz_image.isValid())  throw img::ImageException("Invalid xyz image");
00166     if(!xyz_image.attributes.hasRange(0.0,1.0))  throw img::ImageException("Invalid range attribute");
00167     if(!xyz_image.attributes.hasGamma(1.0))  throw img::ImageException("Invalid gamma attribute");
00168     if(!rgb_image.attributes.hasColorspace(img::CIE_XYZ))  throw img::ImageException("Invalid colorspace attribute");
00169   }
00170   rgb_image.setZero(xyz_image.width(),xyz_image.height());
00171   rgb_image.attributes=xyz_image.attributes;
00172 
00173   for(int x=0; x<xyz_image.width(); ++x)
00174     for(int y=0; y<xyz_image.height(); ++y){
00175       const ScalarType2 X = static_cast<ScalarType2>(xyz_image.getValue(x,y,0));
00176       const ScalarType2 Y = static_cast<ScalarType2>(xyz_image.getValue(x,y,1));
00177       const ScalarType2 Z = static_cast<ScalarType2>(xyz_image.getValue(x,y,2));
00178       
00179       const ScalarType2 R = 3.240479f*X + -1.537150f*Y + -0.498535f*Z;
00180       const ScalarType2 G = -0.969256f*X + 1.875992f*Y + 0.041556f*Z;
00181       const ScalarType2 B = 0.055648f*X + -0.204043f*Y + 1.057311f*Z;
00182       
00183       rgb_image.setValue(x,y,0, ( R<0.0f?0.0f:(R>1.0f?1.0f:R) ) );
00184       rgb_image.setValue(x,y,1, ( G<0.0f?0.0f:(G>1.0f?1.0f:G) ) );
00185       rgb_image.setValue(x,y,2, ( B<0.0f?0.0f:(B>1.0f?1.0f:B) ) );
00186     }
00187     rgb_image.setColorspace(img::RGB);
00188 }
00189 
00195 //template<typename ScalarType1, bool Safe1,typename ScalarType2, bool Safe2> 
00196 //inline void convert_xyz_to_lab(const img::Image<3,ScalarType1,Safe1> &xyz_image, img::Image<3,ScalarType2,Safe2> &lab_image)
00197 //{
00198 //  assert(xyz_image.isValid());
00199 //  if(Safe1 || Safe2){
00200 //    if(!xyz_image.isValid())  throw img::ImageException("Invalid xyz image");
00201 //  }
00202 //  lab_image.setZero(xyz_image.width(),xyz_image.height());
00203 //  
00204 //  const ScalarType2 one_third=0.33333333333333333333333333333333333333333333333333333333333333f;
00205 //  const ScalarType2 Xn = 0.9513f;
00206 //  const ScalarType2 Yn = 1.000f;
00207 //  const ScalarType2 Zn = 1.0886f;
00208 //  
00209 //  for(int x=0; x<xyz_image.width(); ++x)
00210 //    for(int y=0; y<xyz_image.height(); ++y){
00211 //      const ScalarType2 X_third = pow(static_cast<ScalarType2>(xyz_image.getValue(x,y,0))/Xn,one_third);
00212 //      const ScalarType2 Y = static_cast<ScalarType2>(xyz_image.getValue(x,y,1))/Yn;
00213 //      const ScalarType2 Y_third = pow(Y,one_third);
00214 //      const ScalarType2 Z_third = pow(static_cast<ScalarType2>(xyz_image.getValue(x,y,2))/Zn,one_third);
00215 //
00216 //      lab_image.setValue(x,y,0, (Y > 0.008856f)?((116.0f*(Y_third)) - 16.0f):(903.3f*Y) );
00217 //      lab_image.setValue(x,y,1, 500.0f * ((X_third) - (Y_third)) );
00218 //      lab_image.setValue(x,y,2, 200.0f * ((Y_third) - (Z_third)) );
00219 //    }
00220 //}
00221 //
00222 //template<typename ScalarType1, bool Safe1,typename ScalarType2, bool Safe2> 
00223 //inline void convert_lab_to_xyz(const img::Image<3,ScalarType1,Safe1> &lab_image, img::Image<3,ScalarType2,Safe2> &xyz_image)
00224 //{
00225 //  assert(0); // sistemare attributi
00226 //  assert(lab_image.isValid());
00227 //  if(Safe1 || Safe2){
00228 //    if(!lab_image.isValid())  throw img::ImageException("Invalid lab image");
00229 //  }
00230 //  xyz_image.setZero(lab_image.width(),lab_image.height());
00231 //
00232 //  const ScalarType2 Xn = 0.9513f;
00233 //  const ScalarType2 Yn = 1.000f;
00234 //  const ScalarType2 Zn = 1.0886f;
00235 //
00236 //  for(int x=0; x<lab_image.width(); ++x)
00237 //    for(int y=0; y<lab_image.height(); ++y){
00238 //      const ScalarType2 P = (static_cast<ScalarType2>(lab_image.getValue(x,y,0))+16.0f)/116.0f;
00239 //
00240 //      xyz_image.setValue(x,y,0, Xn * pow(P + (lab_image.getValue(x,y,1)/500.0f), 3.0f) );
00241 //      xyz_image.setValue(x,y,1, Yn * pow(P, 3.0f) );
00242 //      xyz_image.setValue(x,y,2, Zn * pow(P - (lab_image.getValue(x,y,2)/200.0f), 3.0f) );
00243 //    }
00244 //}
00245 
00246 } // end namespace img
00247 
00248 #endif /*IMG_CS_BASE_H_*/


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:31:54