diff options
author | cathook <b01902109@csie.ntu.edu.tw> | 2014-06-01 13:56:57 +0800 |
---|---|---|
committer | cathook <b01902109@csie.ntu.edu.tw> | 2014-06-01 13:56:57 +0800 |
commit | d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0 (patch) | |
tree | 16f7920c5079e0aefcf9509d2dbab59c464d42bd /meowpp/colors | |
parent | bd58f63900410ec4764031f2e6de2d75e91434b3 (diff) | |
download | meow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.tar meow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.tar.gz meow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.tar.bz2 meow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.tar.lz meow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.tar.xz meow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.tar.zst meow-d5052f1c296dddf51b3e83d59bf3e3c1952cb2d0.zip |
big chnage
Diffstat (limited to 'meowpp/colors')
-rw-r--r-- | meowpp/colors/!readme.asciidoc | 78 | ||||
-rw-r--r-- | meowpp/colors/Color3_Space.h | 78 | ||||
-rw-r--r-- | meowpp/colors/HSL_Space.h | 188 | ||||
-rw-r--r-- | meowpp/colors/HSV_Space.h | 188 | ||||
-rw-r--r-- | meowpp/colors/RGB_Space.h | 168 | ||||
-rw-r--r-- | meowpp/colors/YUV_Space.h | 131 |
6 files changed, 831 insertions, 0 deletions
diff --git a/meowpp/colors/!readme.asciidoc b/meowpp/colors/!readme.asciidoc new file mode 100644 index 0000000..28b097a --- /dev/null +++ b/meowpp/colors/!readme.asciidoc @@ -0,0 +1,78 @@ + + +一些 *color space* 以及這些space的 *transformate function* 都放在這資料夾下 + +[NOTE] +目前transformation function的準確率還很低, 有待以後加強 + +===== Color3_Space.h + +`class Color3_Space<T>` *Channel Number = 3* 的 Color Space 的共通 *Base class* + +===== RGB_Space.h + +Channel分別是 + +* Red +* Green +* Blue + +.Classes +* `meow::RGBi_Space` 用 'int' 存資料, 每個channel數值合法範圍是 *0~255* +* `meow::RGBf_Space` 用 'double' 存資料, 每個channel數值合法範圍是 *0.0~1.0* + +.Functions +* `meow::colorTransformation(in, *out)` for +** RGBi_Space <--> RGBf_Space + +===== YUV_Space.h + +Channel分別是 + +* Y 明度 +* U 色度 +* V 濃度 + +.Classes +* `meow::YUVf_Space` 用 'double' 存資料, 每個channel數值合法範圍是 *0~1.0* + +.Functions +* `meow::colorTransformation(in, *out)` for +** YUVf_Space <--> RGBi_Space +** YUVf_Space <--> RGBf_Space + +===== HSL_Space.h + +Channel分別是 + +* H 色調 +* S 飽和度 +* L 亮度 + +.Classes +* `meow::HSLf_Space` 用 'double' 存資料, 每個channel數值合法範圍是 *0~1.0* + +.Functions +* `meow::colorTransformation(in, *out)` for +** HSLf_Space <--> RGBi_Space +** HSLf_Space <--> RGBf_Space +** HSLf_Space <--> YUVf_Space + +===== HSV_Space.h + +Channel分別是 + +* H 色調 +* S 飽和度 +* V 亮度 + +.Classes +* `meow::HSVf_Space` 用 'double' 存資料, 每個channel數值合法範圍是 *0~1.0* + +.Functions +* `meow::colorTransformation(in, *out)` for +** HSVf_Space <--> RGBi_Space +** HSVf_Space <--> RGBf_Space +** HSVf_Space <--> YUVf_Space +** HSVf_Space <--> HSLf_Space + diff --git a/meowpp/colors/Color3_Space.h b/meowpp/colors/Color3_Space.h new file mode 100644 index 0000000..87e215b --- /dev/null +++ b/meowpp/colors/Color3_Space.h @@ -0,0 +1,78 @@ +#ifndef colors_Color3_Space_H__ +#define colors_Color3_Space_H__ + +#include <cstdlib> + +#include "../Self.h" +#include "../geo/Vectors.h" +#include "../math/Matrix.h" +#include "../math/utility.h" + +namespace meow { + +/*! + * @brief 以三個channel所組成的色彩空間 + * + * @author cat_leopard + */ +template<class T> +class Color3_Space { +protected: + Vector3D<T> min_; + Vector3D<T> max_; + Vector3D<T> val_; + Color3_Space(Vector3D<T> const& min_bound, + Vector3D<T> const& max_bound, + Vector3D<T> const& init_value) { + min_ = min_bound; + max_ = max_bound; + val_ = init_value; + } + Color3_Space(Color3_Space const& b) { + min_ = b.min_; + max_ = b.max_; + copyFrom(b); + } +public: + virtual ~Color3_Space() { } + Color3_Space<T>& copyFrom(Color3_Space<T> const& b) { + val_ = b.val_; + return *this; + } + template<class T2> + Color3_Space<T>& copyFrom(Color3_Space<T2> const& b) { + for (size_t i = 0; i < 3; i++) { + val(i, ratioMapping((double)b.min(i), (double)b.max(i), (double)b.rgb(i), + (double)min(i), (double)max(i))); + } + } + Vector3D<T> const& minV() const { return min_; } + Vector3D<T> const& maxV() const { return max_; } + Vector3D<T> const& valV() const { return val_; } + Vector3D<T> const& valV(Vector3D<T> const& vv) { val_ = vv; return val(); } + Vector3D<T> & valVGet() { return val_; } + T const& min(size_t id) const { return minV()(id); } + T const& max(size_t id) const { return maxV()(id); } + T const& val(size_t id) const { return valV()(id); } + T const& val(size_t i, T const& c) { + if (i == 0) val_.x(c); + else if (i == 1) val_.y(c); + else if (i == 2) val_.z(c); + return val(i); + } + T& valGet(size_t id) { + if (id == 0) return valVGet().xGet(); + else if (id == 1) return valVGet().yGet(); + else return valVGet().zGet(); + } + Matrix<T> matrix() const { + Matrix<T> ret(3, 1); + for (size_t i = 0; i < 3; i++) { + ret(i, 0, val(i)); + } + } +}; + +} // meow + +#endif // colors_Color3_Space_H__ diff --git a/meowpp/colors/HSL_Space.h b/meowpp/colors/HSL_Space.h new file mode 100644 index 0000000..f70eab1 --- /dev/null +++ b/meowpp/colors/HSL_Space.h @@ -0,0 +1,188 @@ +#ifndef colors_HSL_Space_H__ +#define colors_HSL_Space_H__ + +#include "Color3_Space.h" +#include "../geo/Vectors.h" + +#include "RGB_Space.h" +#include "YUV_Space.h" +#include "../math/utility.h" + +#include <cstdlib> + +namespace meow { + +/*! + * @brief 以浮點數\b Y(亮度), \b U(色度), \b V(濃度) 三個值所組成的色彩空間 + * + * 其中範圍都介於0.0~1.0之間 + * + * @author cat_leopard + */ +class HSLf_Space: public Color3_Space<double> { +public: + HSLf_Space(): Color3_Space<double>(Vector3D<double>( 0.0, 0.0, 0.0), + Vector3D<double>(PI*2.0, 1.0, 1.0), + Vector3D<double>( 0.0, 0.0, 0.0)) { + } + HSLf_Space(double c): Color3_Space<double>(Vector3D<double>( 0.0, 0.0, 0.0), + Vector3D<double>(PI*2.0, 1.0, 1.0), + Vector3D<double>( c, c, c)) + { } + HSLf_Space(Vector3D<double> const& v): + Color3_Space<double>(Vector3D<double>(0.0, 0.0, 0.0), + Vector3D<double>(1.0, 1.0, 1.0), + Vector3D<double>(v)) { + } + HSLf_Space(HSL_Space const& b): Color3_Space<double>(b) { + } + ~HSLf_Space() { + } + double const& hslMin(size_t i) const { return min(i); } + double const& hMin( ) const { return min(0); } + double const& sMin( ) const { return min(1); } + double const& lMin( ) const { return min(2); } + double const& hslMax(size_t i) const { return max(i); } + double const& hMax( ) const { return max(0); } + double const& sMax( ) const { return max(1); } + double const& lMax( ) const { return max(2); } + double const& hsl(size_t i) const { return val(i); } + double const& h( ) const { return hsl(0); } + double const& s( ) const { return hsl(1); } + double const& l( ) const { return hsl(2); } + double const& hsl(size_t i, double c) { return val(i, c); } + double const& h( double c) { return hsl(0, c); } + double const& s( double c) { return hsl(1, c); } + double const& l( double c) { return hsl(2, c); } + double& hslGet(size_t i) { return valGet(i); } + double& hGet( ) { return hslGet(0); } + double& sGet( ) { return hslGet(1); } + double& lGet( ) { return hslGet(2); } + HSLf_Space& operator=(HSLf_Space const& b) { + copyFrom(b); + return *this; + } + HSLf_Space operator+(HSLf_Space const& b) const { + return HSLf_Space(val_ + b.val_); + } + HSLf_Space operator-(HSLf_Space const& b) const { + return HSLf_Space(val_ - b.val_); + } + HSLf_Space operator*(double const& c) const { + return HSLf_Space(val_ * c); + } + HSLf_Space operator/(double const& c) const { + return HSLf_Space(val_ / c); + } + double operator*(HSLf_Space const& b) const { + return val_ * b.val_; + } +}; + +/*! + * @brief \c RGBf_Space to \c HSLf_Space + */ +inline void colorTransformate(RGBf_Space const& rgb, HSLf_Space* hsl) { + double r = normalize(rgb.rMin(), rgb.rMax(), rgb.r()); + double g = normalize(rgb.gMin(), rgb.gMax(), rgb.g()); + double b = normalize(rgb.bMin(), rgb.bMax(), rgb.b()); + double mx = std::max(std::max(r, g), b); + double mn = std::min(std::min(r, g), b); + double h, s, l; + if (mx == mn ) h = 0; + else if(mx == r && g >= b) h = PI/3.0 * (g-b) / (mx-mn); + else if(mx == r && g < b) h = PI/3.0 * (g-b) / (mx-mn) + PI * 2.0; + else if(mx == g ) h = PI/3.0 * (b-r) / (mx-mn) + PI/3.0*2.0; + else h = PI/3.0 * (r-g) / (mx-mn) + PI/3.0*4.0; + l = 0.5 * (mx + mn); + if (l == 0 || mx == mn) s = 0; + else if(l < 0.5 ) s = (mx - mn) / (2.0 * l); + else s = (mx - mn) / (2 - 2.0 * l); + hsl->h(h); + hsl->s(s); + hsl->l(l); +} + +/*! + * @brief \c YUVf_Space to \c HSLf_Space + */ +inline void colorTransformate(YUVf_Space const& yuv, HSLf_Space* hsl) { + RGBf_Space tmp; + colorTransformate(yuv, &tmp); + colorTransformate(tmp, hsl); +} + +/*! + * @brief \c HSLf_Space to \c RGBf_Space + */ +inline void colorTransformate(HSLf_Space const& hsl, RGBf_Space* rgb) { + double h = normalize(hsl.hMin(), hsl.hMax(), hsl.h()); + double s = normalize(hsl.sMin(), hsl.sMax(), hsl.s()); + double l = normalize(hsl.lMin(), hsl.lMax(), hsl.l()); + if(s == 0){ + rgb->r(denormalize(rgb->rMin(), rgb->rMax(), l)); + rgb->g(denormalize(rgb->gMin(), rgb->gMax(), l)); + rgb->b(denormalize(rgb->bMin(), rgb->bMax(), l)); + return ; + } + double q = (l < 0.5 ? (l * (1 + s)) : (l + s - (l * s))); + double p = 2 * l - q; + double t_r = h + 1.0 / 3.0; + double t_g = h; + double t_b = h - 1.0 / 3.0; + if(t_r < 0) t_r = t_r + 1.0; + if(t_r > 1) t_r = t_r - 1.0; + if(t_g < 0) t_g = t_g + 1.0; + if(t_g > 1) t_g = t_g - 1.0; + if(t_b < 0) t_b = t_b + 1.0; + if(t_b > 1) t_b = t_b - 1.0; + double r, g, b; + if (t_r < 1.0 / 6.0) r = p + (q - p) * 6 * t_r; + else if(t_r < 0.5 ) r = q; + else if(t_r < 2.0 / 3.0) r = p + (q - p) * 6 * (2.0 / 3.0 - t_r); + else r = p; + if (t_g < 1.0 / 6.0) g = p + (q - p) * 6 * t_g; + else if(t_g < 0.5 ) g = q; + else if(t_g < 2.0 / 3.0) g = p + (q - p) * 6 * (2.0 / 3.0 - t_g); + else g = p; + if (t_b < 1.0 / 6.0) b = p + (q - p) * 6 * t_b; + else if(t_b < 0.5 ) b = q; + else if(t_b < 2.0 / 3.0) b = p + (q - p) * 6 * (2.0 / 3.0 - t_b); + else b = p; + rgb->r(denormalize(rgb->rMin(), rgb->rMax(), r)); + rgb->g(denormalize(rgb->gMin(), rgb->gMax(), g)); + rgb->b(denormalize(rgb->bMin(), rgb->bMax(), b)); +} + +/*! + * @brief \c HSLf_Space to \c YUVf_Space + */ +inline void colorTransformate(HSLf_Space const& hsl, YUVf_Space* yuv) { + RGBf_Space tmp; + colorTransformate(hsl, &tmp); + colorTransformate(tmp, yuv); +} + +/*! + * @brief \c HSLf_Space to \c RGBi_Space + */ +inline void colorTransformate(HSLf_Space const& hsl, RGBi_Space* rgb) { + RGBf_Space tmp; + colorTransformate(hsl, &tmp); + rgb->copyFrom(tmp); +} + + +/*! + * @brief \c RGBi_Space to \c HSLf_Space + */ +inline void colorTransformate(RGBi_Space const& rgb, HSLf_Space* hsl) { + RGBf_Space tmp; + tmp.copyFrom(rgb); + colorTransformate(rgb, hsl); +} + +} // meow + + +#endif // colors_HSL_Space_H__ diff --git a/meowpp/colors/HSV_Space.h b/meowpp/colors/HSV_Space.h new file mode 100644 index 0000000..96ba33c --- /dev/null +++ b/meowpp/colors/HSV_Space.h @@ -0,0 +1,188 @@ +#ifndef colors_HSV_Space_H__ +#define colors_HSV_Space_H__ + +#include "Color3_Space.h" +#include "../geo/Vectors.h" + +#include "RGB_Space.h" +#include "YUV_Space.h" +#include "HSL_Space.h" +#include "../math/utility.h" + +#include <cstdlib> + +namespace meow { + +/*! + * @brief 以浮點數\b Y(亮度), \b U(色度), \b V(濃度) 三個值所組成的色彩空間 + * + * 其中範圍都介於0.0~1.0之間 + * + * @author cat_leopard + */ +class HSVf_Space: public Color3_Space<double> { +public: + HSVf_Space(): Color3_Space<double>(Vector3D<double>( 0.0, 0.0, 0.0), + Vector3D<double>(PI*2.0, 1.0, 1.0), + Vector3D<double>( 0.0, 0.0, 0.0)) { + } + HSVf_Space(double c): Color3_Space<double>(Vector3D<double>( 0.0, 0.0, 0.0), + Vector3D<double>(PI*2.0, 1.0, 1.0), + Vector3D<double>( c, c, c)) + { } + HSVf_Space(Vector3D<double> const& v): + Color3_Space<double>(Vector3D<double>(0.0, 0.0, 0.0), + Vector3D<double>(1.0, 1.0, 1.0), + Vector3D<double>(v)) { + } + HSVf_Space(HSV_Space const& b): Color3_Space<double>(b) { + } + ~HSVf_Space() { + } + double const& hsvMin(size_t i) const { return min(i); } + double const& hMin( ) const { return min(0); } + double const& sMin( ) const { return min(1); } + double const& vMin( ) const { return min(2); } + double const& hsvMax(size_t i) const { return max(i); } + double const& hMax( ) const { return max(0); } + double const& sMax( ) const { return max(1); } + double const& vMax( ) const { return max(2); } + double const& hsv(size_t i) const { return val(i); } + double const& h( ) const { return hsv(0); } + double const& s( ) const { return hsv(1); } + double const& v( ) const { return hsv(2); } + double const& hsv(size_t i, double c) { return val(i, c); } + double const& h( double c) { return hsv(0, c); } + double const& s( double c) { return hsv(1, c); } + double const& v( double c) { return hsv(2, c); } + double& hsvGet(size_t i) { return valGet(i); } + double& hGet( ) { return hsvGet(0); } + double& sGet( ) { return hsvGet(1); } + double& vGet( ) { return hsvGet(2); } + HSVf_Space& operator=(HSVf_Space const& b) { + copyFrom(b); + return *this; + } + HSVf_Space operator+(HSVf_Space const& b) const { + return HSVf_Space(val_ + b.val_); + } + HSVf_Space operator-(HSVf_Space const& b) const { + return HSVf_Space(val_ - b.val_); + } + HSVf_Space operator*(double const& c) const { + return HSVf_Space(val_ * c); + } + HSVf_Space operator/(double const& c) const { + return HSVf_Space(val_ / c); + } + double operator*(HSVf_Space const& b) const { + return val_ * b.val_; + } +}; + +/*! + * @brief \c RGBf_Space to \c HSVf_Space + */ +inline void colorTransformate(RGBf_Space const& rgb, HSVf_Space* hsv) { + double r = normalize(rgb.rMin(), rgb.rMax(), rgb.r()); + double g = normalize(rgb.gMin(), rgb.gMax(), rgb.g()); + double b = normalize(rgb.bMin(), rgb.bMax(), rgb.b()); + double mx = std::max(std::max(r, g), b); + double mn = std::min(std::min(r, g), b); + double h, s, v; + if (mx == mn ) h = 0; + else if(mx == r && g >= b) h = PI/3.0 * (g-b) / (mx-mn); + else if(mx == r && g < b) h = PI/3.0 * (g-b) / (mx-mn) + PI * 2.0; + else if(mx == g ) h = PI/3.0 * (b-r) / (mx-mn) + PI/3.0*2.0; + else h = PI/3.0 * (r-g) / (mx-mn) + PI/3.0*4.0; + if(mx == 0) s = 0; + else s = 1 - mn / mx; + v = mx; + hsv->h(h); + hsv->s(s); + hsv->v(v); +} + +/*! + * @brief \c YUVf_Space to \c HSVf_Space + */ +inline void colorTransformate(YUVf_Space const& yuv, HSVf_Space* hsv) { + RGBf_Space tmp; + colorTransformate( yuv, &tmp); + colorTransformate(*tmp, hsv); +} + +/*! + * @brief \c HSLf_Space to \c HSVf_Space + */ +inline void colorTransformate(HSLf_Space const& hsl, HSVf_Space* hsv) { + RGBf_Space tmp; + colorTransformate( hsl, &tmp); + colorTransformate(*tmp, hsv); +} + +/*! + * @brief \c HSVf_Space to \c RGBf_Space + */ +inline void colorTransformate(HSVf_Space const& hsv, RGBf_Space* rgb) { + double h = normalize(hsv.hMin(), hsv.hMax(), hsv.h()) * 360; + double s = normalize(hsv.sMin(), hsv.sMax(), hsv.s()); + double v = normalize(hsv.vMin(), hsv.vMax(), hsv.v()); + int hi = (int)h / 60 % 6; + double f = h / 60.0 - hi; + double p = v * (1 - s); + double q = v * (1 - f * s); + double t = v * (1 - (1 - f) * s); + double r, g, b; + if (hi == 0){ r = v; g = t; b = p; } + else if(hi == 1){ r = q; g = v; b = p; } + else if(hi == 2){ r = p; g = v; b = t; } + else if(hi == 3){ r = p; g = q; b = v; } + else if(hi == 4){ r = t; g = p; b = v; } + else { r = v; g = p; b = q; } + rgb->r(denormalize(rgb->rMin(), rgb->rMax(), r)); + rgb->g(denormalize(rgb->gMin(), rgb->gMax(), g)); + rgb->b(denormalize(rgb->bMin(), rgb->bMax(), b)); +} + +/*! + * @brief \c HSVf_Space to \c YUVf_Space + */ +inline void colorTransformate(HSVf_Space const& hsv, YUVf_Space* yuv) { + RGBf_Space tmp; + colorTransformate( hsv, &tmp); + colorTransformate(*tmp, yuv); +} + +/*! + * @brief \c HSVf_Space to \c HSLf_Space + */ +inline void colorTransformate(HSVf_Space const& hsv, HSLf_Space* hsl) { + RGBf_Space tmp; + colorTransformate( hsv, &tmp); + colorTransformate(*tmp, hsl); +} + +/*! + * @brief \c HSVf_Space to \c RGBi_Space + */ +inline void colorTransformate(HSVf_Space const& hsv, RGBi_Space* rgb) { + RGBf_Space tmp; + colorTransformate(hsv, &tmp); + rgb->copyFrom(tmp); +} + + +/*! + * @brief \c RGBi_Space to \c HSVf_Space + */ +inline void colorTransformate(RGBi_Space const& rgb, HSVf_Space* hsv) { + RGBf_Space tmp; + tmp.copyFrom(rgb); + colorTransformate(rgb, hsv); +} + +} // meow + + +#endif // colors_HSV_Space_H__ diff --git a/meowpp/colors/RGB_Space.h b/meowpp/colors/RGB_Space.h new file mode 100644 index 0000000..ea04598 --- /dev/null +++ b/meowpp/colors/RGB_Space.h @@ -0,0 +1,168 @@ +#ifndef colors_RGB_Space_H__ +#define colors_RGB_Space_H__ + +#include "Color3_Space.h" +#include "../geo/Vectors.h" +#include "../math/utility.h" + +#include <cstdlib> + +namespace meow { + +/*! + * @brief 以整數 \b Red, \b Green, \b Blue 三個值所組成的色彩空間 + * + * 其中範圍都介於0~255之間 + * + * @author cat_leopard + */ +class RGBi_Space: public Color3_Space<int> { +public: + RGBi_Space(): Color3_Space<int>(Vector3D<int>( 0, 0, 0), + Vector3D<int>(255, 255, 255), + Vector3D<int>( 0, 0, 0)) { + } + RGBi_Space(int c): Color3_Space<int>(Vector3D<int>( 0, 0, 0), + Vector3D<int>(255, 255, 255), + Vector3D<int>( c, c, c)) { + } + RGBi_Space(Vector3D<int> const& v): + Color3_Space<int>(Vector3D<int>( 0, 0, 0), + Vector3D<int>(255, 255, 255), + Vector3D<int>(v)) { + } + RGBi_Space(RGBi_Space const& b): Color3_Space<int>(b) { + } + ~RGBi_Space() { + } + int const& rgbMin(size_t i) const { return min(i); } + int const& rMin( ) const { return min(0); } + int const& gMin( ) const { return min(1); } + int const& bMin( ) const { return min(2); } + int const& rgbMax(size_t i) const { return max(i); } + int const& rMax( ) const { return max(0); } + int const& gMax( ) const { return max(1); } + int const& bMax( ) const { return max(2); } + int const& rgb(size_t i) const { return val(i); } + int const& r( ) const { return rgb(0); } + int const& g( ) const { return rgb(1); } + int const& b( ) const { return rgb(2); } + int const& rgb(size_t i, int c) { return val(i, c); } + int const& r( int c) { return rgb(0, c); } + int const& g( int c) { return rgb(1, c); } + int const& b( int c) { return rgb(2, c); } + int& rgbGet(size_t i) { return valGet(i); } + int& rGet( ) { return rgbGet(0); } + int& gGet( ) { return rgbGet(1); } + int& bGet( ) { return rgbGet(2); } + RGBi_Space& operator=(RGBi_Space const& b) { + copyFrom(b); + return *this; + } + RGBi_Space operator+(RGBi_Space const& b) const { + return RGBi_Space(val_ + b.val_); + } + RGBi_Space operator-(RGBi_Space const& b) const { + return RGBi_Space(val_ - b.val_); + } + RGBi_Space operator*(int c) const { + return RGBi_Space(val_ * c); + } + RGBi_Space operator/(int c) const { + return RGBi_Space(val_ / c); + } + int operator*(RGBi_Space const& b) const { + return val_ * b.val_; + } +}; + +/*! + * @brief 以浮點數\b Red, \b Green, \b Blue 三個值所組成的色彩空間 + * + * 其中範圍都介於0.0~1.0之間 + * + * @author cat_leopard + */ +class RGBf_Space: public Color3_Space<double> { +public: + RGBf_Space(): Color3_Space<double>(Vector3D<double>(0.0, 0.0, 0.0), + Vector3D<double>(1.0, 1.0, 1.0), + Vector3D<double>(0.0, 0.0, 0.0)) { + } + RGBf_Space(double c): Color3_Space<double>(Vector3D<double>(0.0, 0.0, 0.0), + Vector3D<double>(1.0, 1.0, 1.0), + Vector3D<double>( c, c, c)) { + } + RGBf_Space(Vector3D<double> const& v): + Color3_Space<double>(Vector3D<double>(0.0, 0.0, 0.0), + Vector3D<double>(1.0, 1.0, 1.0), + Vector3D<double>(v)) { + } + RGBf_Space(RGBf_Space const& b): Color3_Space<double>(b) { + } + ~RGBf_Space() { + } + double const& rgbMin(size_t i) const { return min(i); } + double const& rMin( ) const { return min(0); } + double const& gMin( ) const { return min(1); } + double const& bMin( ) const { return min(2); } + double const& rgbMax(size_t i) const { return max(i); } + double const& rMax( ) const { return max(0); } + double const& gMax( ) const { return max(1); } + double const& bMax( ) const { return max(2); } + double const& rgb(size_t i) const { return val(i); } + double const& r( ) const { return rgb(0); } + double const& g( ) const { return rgb(1); } + double const& b( ) const { return rgb(2); } + double const& rgb(size_t i, double c) { return val(i, c); } + double const& r( double c) { return rgb(0, c); } + double const& g( double c) { return rgb(1, c); } + double const& b( double c) { return rgb(2, c); } + double& rgbGet(size_t i) { return valGet(i); } + double& rGet( ) { return rgbGet(0); } + double& gGet( ) { return rgbGet(1); } + double& bGet( ) { return rgbGet(2); } + RGBf_Space& operator=(RGBf_Space const& b) { + copyFrom(b); + return *this; + } + RGBf_Space operator+(RGBf_Space const& b) const { + return RGBf_Space(val_ + b.val_); + } + RGBf_Space operator-(RGBf_Space const& b) const { + return RGBf_Space(val_ - b.val_); + } + RGBf_Space operator*(double const& c) const { + return RGBf_Space(val_ * c); + } + RGBf_Space operator/(double const& c) const { + return RGBf_Space(val_ / c); + } + double operator*(RGBf_Space const& b) const { + return val_ * b.val_; + } +}; + +/*! + * @brief \c RGBi_Space to \c RGBf_Space + */ +inline void colorTransformate(RGBi_Space const& a, RGBf_Space* b) { + for (size_t i = 0; i < 3; ++i) { + b->rgb(i, ratioMapping<double>(a.rgbMin(i), a.rgbMax(i), a.rgb(i), + b->rgbMin(i), b->rgbMax(i))); + } +} + +/*! + * @brief \c RGBf_Space to \c RGBi_Space + */ +inline void colorTransformate(RGBf_Space const& a, RGBi_Space* b) { + for (size_t i = 0; i < 3; ++i) { + b->rgb(i, ratioMapping<double>(a.rgbMin(i), a.rgbMax(i), a.rgb(i), + b->rgbMin(i), b->rgbMax(i))); + } +} + +} // meow + +#endif // colors_RGB_Space_H__ diff --git a/meowpp/colors/YUV_Space.h b/meowpp/colors/YUV_Space.h new file mode 100644 index 0000000..651caaf --- /dev/null +++ b/meowpp/colors/YUV_Space.h @@ -0,0 +1,131 @@ +#ifndef colors_YUV_Space_H__ +#define colors_YUV_Space_H__ + +#include "Color3_Space.h" +#include "../geo/Vectors.h" + +#include "RGB_Space.h" +#include "../math/utility.h" + +#include <cstdlib> + +namespace meow { + +/*! + * @brief 以浮點數\b Y(亮度), \b U(色度), \b V(濃度) 三個值所組成的色彩空間 + * + * 其中範圍都介於0.0~1.0之間 + * + * @author cat_leopard + */ +class YUVf_Space: public Color3_Space<double> { +public: + YUVf_Space(): Color3_Space<double>(Vector3D<double>(0.0, 0.0, 0.0), + Vector3D<double>(1.0, 1.0, 1.0), + Vector3D<double>(0.0, 0.0, 0.0)) { + } + YUVf_Space(double c): Color3_Space<double>(Vector3D<double>(0.0, 0.0, 0.0), + Vector3D<double>(1.0, 1.0, 1.0), + Vector3D<double>( c, c, c)) { + } + YUVf_Space(Vector3D<double> const& v): + Color3_Space<double>(Vector3D<double>(0.0, 0.0, 0.0), + Vector3D<double>(1.0, 1.0, 1.0), + Vector3D<double>(v)) { + } + YUVf_Space(YUV_Space const& b): Color3_Space<double>(b) { + } + ~YUVf_Space() { + } + double const& yuvMin(size_t i) const { return min(i); } + double const& yMin( ) const { return min(0); } + double const& uMin( ) const { return min(1); } + double const& vMin( ) const { return min(2); } + double const& yuvMax(size_t i) const { return max(i); } + double const& yMax( ) const { return max(0); } + double const& uMax( ) const { return max(1); } + double const& vMax( ) const { return max(2); } + double const& yuv(size_t i) const { return val(i); } + double const& y( ) const { return yuv(0); } + double const& u( ) const { return yuv(1); } + double const& v( ) const { return yuv(2); } + double const& yuv(size_t i, double c) { return val(i, c); } + double const& y( double c) { return yuv(0, c); } + double const& u( double c) { return yuv(1, c); } + double const& v( double c) { return yuv(2, c); } + double& yuvGet(size_t i) { return valGet(i); } + double& yGet( ) { return yuvGet(0); } + double& uGet( ) { return yuvGet(1); } + double& vGet( ) { return yuvGet(2); } + YUVf_Space& operator=(YUVf_Space const& b) { + copyFrom(b); + return *this; + } + YUVf_Space operator+(YUVf_Space const& b) const { + return YUVf_Space(val_ + b.val_); + } + YUVf_Space operator-(YUVf_Space const& b) const { + return YUVf_Space(val_ - b.val_); + } + YUVf_Space operator*(double const& c) const { + return YUVf_Space(val_ * c); + } + YUVf_Space operator/(double const& c) const { + return YUVf_Space(val_ / c); + } + double operator*(YUVf_Space const& b) const { + return val_ * b.val_; + } +}; + +/*! + * @brief \c RGBf_Space to \c YUVf_Space + */ +inline void colorTransformate(RGBf_Space const& rgb, YUVf_Space* yuv) { + double r = normalize(rgb.rMin(), rgb.rMax(), rgb.r()); + double g = normalize(rgb.gMin(), rgb.gMax(), rgb.g()); + double b = normalize(rgb.bMin(), rgb.bMax(), rgb.b()); + double y = 0.299 * r + 0.587 * g + 0.114 * b; + double u = -0.169 * r - 0.331 * g + 0.500 * b + 0.5; + double v = 0.500 * r - 0.419 * g - 0.081 * b + 0.5; + yuv->y(denormalize(yuv->yMin(), yuv->yMax(), y)); + yuv->u(denormalize(yuv->uMin(), yuv->uMax(), u)); + yuv->v(denormalize(yuv->vMin(), yuv->vMax(), v)); +} + +/*! + * @brief \c YUVf_Space to \c RGBf_Space + */ +inline void colorTransformate(YUVf_Space const& yuv, RGBf_Space* rgb) { + double y = normalize(yuv.yMin(),yuv.yMax(),yuv.y()); + double u = normalize(yuv.uMin(),yuv.uMax(),yuv.u()); + double v = normalize(yuv.vMin(),yuv.vMax(),yuv.v()); + double r = y - 0.00093 * (u - 0.5) + 1.401687 * (v - 0.5); + double g = y - 0.34370 * (u - 0.5) - 0.714170 * (v - 0.5); + double b = y + 1.77216 * (u - 0.5) - 0.000990 * (v - 0.5); + rgb->r(denormalize(rgb->rMin(), rgb->rMax(), r)); + rgb->g(denormalize(rgb->gMin(), rgb->gMax(), g)); + rgb->b(denormalize(rgb->bMin(), rgb->bMax(), b)); +} + +/*! + * @brief \c RGBi_Space to \c YUVf_Space + */ +inline void colorTransformate(RGBi_Space const& rgb, YUVf_Space* yuv) { + RGBf_Space tmp; + tmp.copyFrom(rgb); + colorTransformate(tmp, yuv); +} + +/*! + * @brief \c YUVf_Space to \c RGBi_Space + */ +inline void colorTransformate(YUVf_Space const& yuv, RGBi_Space* rgb) { + RGBf_Space tmp; + colorTransformate(yuv, &tmp); + rgb->copyFrom(tmp); +} + +} // meow + +#endif // colors_YUV_H__ |