📄 color.h
字号:
case 2: write_2_bytes(x,out); write_2_bytes(y,out); write_2_bytes(z,out); return; case 4: write_4_bytes(x,out); write_4_bytes(y,out); write_4_bytes(z,out); return; default: Message::error<<"Basic_color::write_to_bytes : sizeof(component_type) = "<<size <<" non implemented"<<Message::done; } return;}template<typename RGB_converter>voidBasic_color<RGB_converter>::read_from_bytes(std::istream& in){ using namespace IO_tools; int size = sizeof(component_type); switch (size){ case 2: read_2_bytes(&x,in); read_2_bytes(&y,in); read_2_bytes(&z,in); return; case 4: read_4_bytes(&x,in); read_4_bytes(&y,in); read_4_bytes(&z,in); return; default: Message::error<<"Basic_color::read_to_bytes : sizeof(component_type) = "<<size <<" non implemenrted"<<Message::done; }}template<typename RGB_converter>typename Basic_color<RGB_converter>::distance_typeBasic_color<RGB_converter>::square_distance(const Basic_color<RGB_converter>& c1, const Basic_color<RGB_converter>& c2){ const distance_type dx = c1.x - c2.x; const distance_type dy = c1.y - c2.y; const distance_type dz = c1.z - c2.z; return (dx*dx + dy*dy + dz*dz);}/*! Slower than square_distance(). Use sqrtf() to be improved for 'double'.*/template<typename RGB_converter>typename Basic_color<RGB_converter>::distance_typeBasic_color<RGB_converter>::distance(const Basic_color<RGB_converter>& c1, const Basic_color<RGB_converter>& c2){ return sqrtf(square_distance(c1,c2));}template<typename RGB_converter>template<typename Basic_color_iterator>voidBasic_color<RGB_converter>::mean(Basic_color_iterator first, Basic_color_iterator last, Basic_color<RGB_converter>* const result){ unsigned int n = 0; result->x = 0; result->y = 0; result->z = 0; for(Basic_color_iterator c=first;c!=last;c++){ result->x += c->x; result->y += c->y; result->z += c->z; n++; } result->x /= n; result->y /= n; result->z /= n;}template<typename RGB_converter>template<typename Basic_color_iterator,typename Weight_iterator>voidBasic_color<RGB_converter>::mean(Basic_color_iterator first_clr, Basic_color_iterator last_clr, Weight_iterator first_w, Weight_iterator last_w, Basic_color<RGB_converter>* const result){ component_type n = 0; result->x = 0; result->y = 0; result->z = 0; Basic_color_iterator c; Weight_iterator w; for(c=first_clr,w=first_w; (c!=last_clr)&&(w!=last_w); c++,w++){ result->x += c->x * (*w); result->y += c->y * (*w); result->z += c->z * (*w); n += (*w); } if (n==0){ Message::warning<<"Basic_color::mean : the weight sum is null\n"<<Message::done; *result = Basic_color<RGB_converter>(); } else{ result->x /= n; result->y /= n; result->z /= n; }}template<typename RGB_converter>template<typename Basic_color_iterator>voidBasic_color<RGB_converter>::robust_mean(Basic_color_iterator first, Basic_color_iterator last, Basic_color<RGB_converter>* const result, const unsigned int n_iter){ mean(first,last,result); if (n_iter==0){ return; } int n = 0; distance_type sum = 0; std::list<distance_type> dist; // Compute the variamce. for(Basic_color_iterator c=first;c!=last;c++){ distance_type sq = square_distance(*c,*result); dist.push_back(sq); sum += sq; n++; } distance_type sq_dev; if (n>0) { sq_dev = (sum/n); }#ifndef WITHOUT_LIMITS else{ sq_dev = std::numeric_limits<distance_type>::signaling_NaN(); Message::warning<<"no color to compute the variance"<<Message::done; }#endif // Keep only the nearest ones. typedef typename std::iterator_traits<Basic_color_iterator>::value_type color_type; std::list<color_type> near_one; n = 0; Basic_color_iterator c; typename std::list<distance_type>::iterator d; for(c=first,d=dist.begin();c!=last;c++,d++){ if ((*d)<=sq_dev){ near_one.push_back(*c); n++; } } robust_mean(near_one.begin(),near_one.end(),result,n_iter-1);}template<typename RGB_converter>template<typename Basic_color_iterator,typename Weight_iterator>voidBasic_color<RGB_converter>::robust_mean(Basic_color_iterator first_clr, Basic_color_iterator last_clr, Weight_iterator first_w, Weight_iterator last_w, Basic_color<RGB_converter>* const result, const unsigned int n_iter){ mean(first_clr,last_clr,first_w,last_w,result); if (n_iter==0){ return; } component_type n = 0; distance_type sum = 0; std::list<distance_type> dist; // Compute the variance. Basic_color_iterator c; Weight_iterator w; for(c=first_clr,w=first_w; (c!=last_clr)&&(w!=last_w); c++,w++){ distance_type sq = square_distance(*c,*result); dist.push_back(sq); sum += (*w) * sq; n += *w; } distance_type sq_dev; if (n>0) { sq_dev = (sum/n); }#ifndef WITHOUT_LIMITS else{ sq_dev = std::numeric_limits<distance_type>::signaling_NaN(); Message::warning<<"no color to compute the variance"<<Message::done; }#endif // Keep only the nearest one. typedef typename std::iterator_traits<Basic_color_iterator>::value_type color_type; typedef typename std::iterator_traits<Weight_iterator>::value_type weight_type; std::list<color_type> near_clr; std::list<weight_type> near_w; n = 0; typename std::list<distance_type>::iterator d; for(c=first_clr, w=first_w, d=dist.begin(); (c != last_clr) && (w != last_w); c++, w++, d++){ if ((*d)<=sq_dev){ near_clr.push_back(*c); near_w.push_back(*w); n++; } } robust_mean(near_clr.begin(),near_clr.end(), near_w.begin(),near_w.end(), result,n_iter-1);}template<typename RGB_converter>template<typename Basic_color_iterator>typename Basic_color<RGB_converter>::distance_typeBasic_color<RGB_converter>::square_deviation(Basic_color_iterator first, Basic_color_iterator last){ Basic_color<RGB_converter> mean_color; return square_deviation(first,last,&mean_color);}template<typename RGB_converter>template<typename Basic_color_iterator>typename Basic_color<RGB_converter>::distance_typeBasic_color<RGB_converter>::square_deviation(Basic_color_iterator first, Basic_color_iterator last, Basic_color<RGB_converter>* const mean_color){ mean(first,last,mean_color); int n = 0; distance_type sum = 0; for(Basic_color_iterator c=first;c!=last;c++){ sum += square_distance(*c,*mean_color); n++; }#ifndef WITHOUT_LIMITS return ((n>0)?(sum/n):(std::numeric_limits<distance_type>::signaling_NaN()));#else return (sum/n);#endif}template<typename RGB_converter>voidBasic_color<RGB_converter>::main_conversion_output(std::ostream& out){ Basic_color<RGB_converter> clr; component_type r,g,b; clr = white; clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl; clr = grey; clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl; clr = black; clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl; clr = red; clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl; clr = green; clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl; clr = blue; clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl; clr = cyan; clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl; clr = magenta; clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl; clr = yellow; clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl; char one = 1; clr = Basic_color<RGB_converter>(one,one,one); clr.get_RGB(&r,&g,&b); out<<"r: "<<r<<"\tg: "<<g<<"\tb: "<<b<<"\n" <<"->\tx: "<<clr.x<<"\ty: "<<clr.y<<"\tz: "<<clr.z<<"\n"<<std::endl;}template<typename RGB_converter>const Basic_color<RGB_converter>Basic_color<RGB_converter>::white(1.0f, 1.0f, 1.0f);template<typename RGB_converter>const Basic_color<RGB_converter>Basic_color<RGB_converter>::grey(0.5f, 0.5f, 0.5f);template<typename RGB_converter>const Basic_color<RGB_converter>Basic_color<RGB_converter>::black(0.0f, 0.0f, 0.0f);template<typename RGB_converter>const Basic_color<RGB_converter>Basic_color<RGB_converter>::red(1.0f, 0.0f, 0.0f);template<typename RGB_converter>const Basic_color<RGB_converter>Basic_color<RGB_converter>::green(0.0f, 1.0f, 0.0f);template<typename RGB_converter>const Basic_color<RGB_converter>Basic_color<RGB_converter>::blue(0.0f, 0.0f, 1.0f);template<typename RGB_converter>const Basic_color<RGB_converter>Basic_color<RGB_converter>::cyan(0.0f, 1.0f, 1.0f);template<typename RGB_converter>const Basic_color<RGB_converter>Basic_color<RGB_converter>::magenta(1.0f, 0.0f, 1.0f);template<typename RGB_converter>const Basic_color<RGB_converter>Basic_color<RGB_converter>::yellow(1.0f, 1.0f, 0.0f);template<typename RGB_converter>voidBasic_color<RGB_converter>::cycle(const double alpha, Basic_color<RGB_converter>* const result, const Basic_color<RGB_converter>& clr_0, const Basic_color<RGB_converter>& clr_1, const Basic_color<RGB_converter>& clr_2, const Basic_color<RGB_converter>& clr_3){ const double a = alpha - floor(alpha/(2.0*M_PI))*2.0*M_PI; std::vector<Basic_color<RGB_converter> > color(2); std::vector<double> weight(2); if ((a<0) || (a>2.0*M_PI)){ Message::error<<"Basic_color<RGB_converter>::cycle : valeur de a" <<" non valable : "<<a<<Message::done; } if ((a>=0) && (a<=M_PI_2)){ color[0] = clr_0; weight[0] = M_PI_2 - a; color[1] = clr_1; weight[1] = M_PI_2 - weight[0]; } if ((a>M_PI_2) && (a<=M_PI)){ color[0] = clr_1; weight[0] = M_PI - a; color[1] = clr_2; weight[1] = M_PI_2 - weight[0]; } if ((a>M_PI) && (a<=1.5*M_PI)){ color[0] = clr_2; weight[0] = 1.5*M_PI - a; color[1] = clr_3; weight[1] = M_PI_2 - weight[0]; } if ((a>1.5*M_PI) && (a<=2.0*M_PI)){ color[0] = clr_3; weight[0] = 2*M_PI - a; color[1] = clr_0; weight[1] = M_PI_2 - weight[0]; } mean(color.begin(),color.end(),weight.begin(),weight.end(),result);}/* ############################## # class RGB_converter_to_HSV # ##############################*/template<typename Real>voidRGB_converter_to_HSV<Real>::from_RGB_to_cartesian(const double r, const double g, const double b, component_type* const x, component_type* const y, component_type* const z){ double h,s,v; RGB_to_HSV(r,g,b,&h,&s,&v);#ifndef M_PI const double theta = 2 * 3.14159265358979323846 * h;#else const double theta = 2 * M_PI * h;#endif const float f = s*v; *x = static_cast<component_type>(f * cos(theta)); *y = static_cast<component_type>(f * sin(theta)); *z = static_cast<component_type>(v);}template<typename Real>voidRGB_converter_to_HSV<Real>::from_cartesian_to_RGB(const component_type x, const component_type y, const component_type z, double* const r, double* const g, double* const b){ const double X = static_cast<double>(x); const double Y = static_cast<double>(y); const double f = sqrt(X*X + Y*Y); const double v = static_cast<double>(z); const double s = (v>0.0)?(f/v):(0.0);#ifndef M_PI double theta = atan2(Y,X) / (2 * 3.14159265358979323846);#else double theta = atan2(Y,X) / (2 * M_PI);#endif const double h = (theta>0) ? theta : (theta + 1); HSV_to_RGB(h,s,v,r,g,b);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -