GDCM
2.2.3
|
00001 /*========================================================================= 00002 00003 Program: GDCM (Grassroots DICOM). A DICOM library 00004 00005 Copyright (c) 2006-2011 Mathieu Malaterre 00006 All rights reserved. 00007 See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. 00008 00009 This software is distributed WITHOUT ANY WARRANTY; without even 00010 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00011 PURPOSE. See the above copyright notice for more information. 00012 00013 =========================================================================*/ 00014 #ifndef GDCMSURFACEHELPER_H 00015 #define GDCMSURFACEHELPER_H 00016 00017 #include "gdcmTypes.h" // for GDCM_EXPORT 00018 00019 #include <vector> 00020 #include <iostream> 00021 00022 namespace gdcm 00023 { 00024 00029 class GDCM_EXPORT SurfaceHelper 00030 { 00031 public: 00032 00033 typedef std::vector< unsigned short > ColorArray; 00034 00046 template <typename T, typename U> 00047 static unsigned short RGBToRecommendedDisplayGrayscale(const std::vector<T> & RGB, 00048 const U rangeMax = 255); 00060 template <typename T, typename U> 00061 static ColorArray RGBToRecommendedDisplayCIELab(const std::vector<T> & RGB, 00062 const U rangeMax = 255); 00074 template <typename T, typename U> 00075 static std::vector<T> RecommendedDisplayCIELabToRGB(const ColorArray & CIELab, 00076 const U rangeMax = 255); 00087 template <typename U> 00088 static std::vector<float> RecommendedDisplayCIELabToRGB(const ColorArray & CIELab, 00089 const U rangeMax = 255); 00090 00091 private: 00092 00093 static std::vector< float > RGBToXYZ(const std::vector<float> & RGB); 00094 00095 static std::vector< float > XYZToRGB(const std::vector<float> & XYZ); 00096 00097 static std::vector< float > XYZToCIELab(const std::vector<float> & XYZ); 00098 00099 static std::vector< float > CIELabToXYZ(const std::vector<float> & CIELab); 00100 }; 00101 00102 template <typename T, typename U> 00103 unsigned short SurfaceHelper::RGBToRecommendedDisplayGrayscale(const std::vector<T> & RGB, 00104 const U rangeMax/* = 255*/) 00105 { 00106 assert(RGB.size() > 2); 00107 00108 unsigned short Grayscale = 0; 00109 00110 const float inverseRangeMax = 1. / (float) rangeMax; 00111 00112 // 0xFFFF "=" 255 "=" white 00113 Grayscale = (unsigned short) ((0.2989 * RGB[0] + 0.5870 * RGB[1] + 0.1140 * RGB[2]) 00114 * inverseRangeMax // Convert to range 0-1 00115 * 0xFFFF); // Convert to range 0x0000-0xFFFF 00116 00117 return Grayscale; 00118 } 00119 00120 template <typename T, typename U> 00121 SurfaceHelper::ColorArray SurfaceHelper::RGBToRecommendedDisplayCIELab(const std::vector<T> & RGB, 00122 const U rangeMax/* = 255*/) 00123 { 00124 assert(RGB.size() > 2); 00125 00126 ColorArray CIELab(3); 00127 std::vector<float> tmp(3); 00128 00129 // Convert to range 0-1 00130 const float inverseRangeMax = 1. / (float) rangeMax; 00131 tmp[0] = (float) (RGB[0] * inverseRangeMax); 00132 tmp[1] = (float) (RGB[1] * inverseRangeMax); 00133 tmp[2] = (float) (RGB[2] * inverseRangeMax); 00134 00135 tmp = SurfaceHelper::XYZToCIELab( SurfaceHelper::RGBToXYZ( tmp ) ); 00136 00137 // Convert to range 0x0000-0xFFFF 00138 // 0xFFFF "=" 127, 0x8080 "=" 0, 0x0000 "=" -128 00139 CIELab[0] = (unsigned short) ( 0xFFFF * (tmp[0]*0.01)); 00140 if(tmp[1] >= -128 && tmp[1] <= 0) 00141 { 00142 CIELab[1] = (unsigned short)(((float)(0x8080)/128.0)*tmp[1] + ((float)0x8080)); 00143 } 00144 else if(tmp[1] <= 127 && tmp[1] > 0) 00145 { 00146 CIELab[1] = (unsigned short)(((float)(0xFFFF - 0x8080)/127.0)*tmp[1] + (float)(0x8080)); 00147 } 00148 if(tmp[2] >= -128 && tmp[2] <= 0) 00149 { 00150 CIELab[2] = (unsigned short)(((float)0x8080/128.0)*tmp[2] + ((float)0x8080)); 00151 } 00152 else if(tmp[2] <= 127 && tmp[2] > 0) 00153 { 00154 CIELab[2] = (unsigned short)(((float)(0xFFFF - 0x8080)/127.0)*tmp[2] + (float)(0x8080)); 00155 } 00156 00157 return CIELab; 00158 } 00159 00160 template <typename T, typename U> 00161 std::vector<T> SurfaceHelper::RecommendedDisplayCIELabToRGB(const ColorArray & CIELab, 00162 const U rangeMax/* = 255*/) 00163 { 00164 assert(CIELab.size() > 2); 00165 00166 std::vector<T> RGB(3); 00167 std::vector<float> tmp(3); 00168 00169 // Convert to range 0-1 00170 00171 tmp[0] = 100.0*CIELab[0] /(float)(0xFFFF); 00172 if(CIELab[1] >= 0x0000 && CIELab[1] <= 0x8080) 00173 { 00174 tmp[1] = (float)(((CIELab[1] - 0x8080) * 128.0)/(float)0x8080); 00175 } 00176 else if(CIELab[1] <= 0xFFFF && CIELab[1] > 0x8080) 00177 { 00178 tmp[1] = (float)((CIELab[1]-0x8080)*127.0 / (float)(0xFFFF - 0x8080)); 00179 } 00180 if(CIELab[2] >= 0x0000 && CIELab[2] <= 0x8080) 00181 { 00182 tmp[2] = (float)(((CIELab[2] - 0x8080) * 128.0)/(float)0x8080); 00183 } 00184 else if(CIELab[2] <= 0xFFFF && CIELab[2] > 0x8080) 00185 { 00186 tmp[2] = (float)((CIELab[2]-0x8080)*127.0 / (float)(0XFFFF - 0x8080)); 00187 } 00188 00189 tmp = SurfaceHelper::XYZToRGB( SurfaceHelper::CIELabToXYZ( tmp ) ); 00190 00191 // Convert to range 0-rangeMax 00192 RGB[0] = (T) (tmp[0] * rangeMax); 00193 RGB[1] = (T) (tmp[1] * rangeMax); 00194 RGB[2] = (T) (tmp[2] * rangeMax); 00195 00196 return RGB; 00197 } 00198 00199 template <typename U> 00200 std::vector<float> SurfaceHelper::RecommendedDisplayCIELabToRGB(const ColorArray & CIELab, 00201 const U rangeMax/* = 255*/) 00202 { 00203 return RecommendedDisplayCIELabToRGB<float>(CIELab, rangeMax); 00204 } 00205 00206 } // end namespace gdcm 00207 00208 #endif // GDCMSURFACEHELPER_H