oT* rgbConvert(iT* I, int n, int d, int flag, oT nrm) { oT* J = (oT*)wrMalloc(n * (flag == 0 ? (d == 1 ? 1 : d / 3) : d) * sizeof(oT)); int i, n1 = d * (n < 1000 ? n / 10 : 100); oT thr = oT(1.001); if (flag > 1 && nrm == 1) for (i = 0; i < n1; i++) if (I[i] > thr) wrError("For floats all values in I must be smaller than 1."); bool useSse = n % 4 == 0 && typeid(oT) == typeid(float); if (flag == 2 && useSse) for (i = 0; i < d / 3; i++) rgb2luv_sse(I + i * n * 3, (float*)(J + i * n * 3), n, (float)nrm); else if ((flag == 0 && d == 1) || flag == 1) normalize(I, J, n * d, nrm); else if (flag == 0) for (i = 0; i < d / 3; i++) rgb2gray(I + i * n * 3, J + i * n * 1, n, nrm); else if (flag == 2) for (i = 0; i < d / 3; i++) rgb2luv(I + i * n * 3, J + i * n * 3, n, nrm); else if (flag == 3) for (i = 0; i < d / 3; i++) rgb2hsv(I + i * n * 3, J + i * n * 3, n, nrm); else wrError("Unknown flag."); return J; }
// Convert from rgb to luv using sse template<class iT> void rgb2luv_sse( iT *I, float *J, int n, float nrm ) { const int k=256; float R[k], G[k], B[k]; if( (size_t(R)&15||size_t(G)&15||size_t(B)&15||size_t(I)&15||size_t(J)&15) || n%4>0 ) { rgb2luv(I,J,n,nrm); return; } int i=0, i1, n1; float minu, minv, un, vn, mr[3], mg[3], mb[3]; float *lTable = rgb2luv_setup(nrm,mr,mg,mb,minu,minv,un,vn); while( i<n ) { n1 = i+k; if(n1>n) n1=n; float *J1=J+i; float *R1, *G1, *B1; // convert to floats (and load input into cache) if( typeid(iT) != typeid(float) ) { R1=R; G1=G; B1=B; iT *Ri=I+i, *Gi=Ri+n, *Bi=Gi+n; for( i1=0; i1<(n1-i); i1++ ) { R1[i1] = (float) *Ri++; G1[i1] = (float) *Gi++; B1[i1] = (float) *Bi++; } } else { R1=((float*)I)+i; G1=R1+n; B1=G1+n; } // compute RGB -> XYZ for( int j=0; j<3; j++ ) { __m128 _mr, _mg, _mb, *_J=(__m128*) (J1+j*n); __m128 *_R=(__m128*) R1, *_G=(__m128*) G1, *_B=(__m128*) B1; _mr=SET(mr[j]); _mg=SET(mg[j]); _mb=SET(mb[j]); for( i1=i; i1<n1; i1+=4 ) *(_J++) = ADD( ADD(MUL(*(_R++),_mr), MUL(*(_G++),_mg)),MUL(*(_B++),_mb)); } { // compute XZY -> LUV (without doing L lookup/normalization) __m128 _c15, _c3, _cEps, _c52, _c117, _c1024, _cun, _cvn; _c15=SET(15.0f); _c3=SET(3.0f); _cEps=SET(1e-35f); _c52=SET(52.0f); _c117=SET(117.0f), _c1024=SET(1024.0f); _cun=SET(13*un); _cvn=SET(13*vn); __m128 *_X, *_Y, *_Z, _x, _y, _z; _X=(__m128*) J1; _Y=(__m128*) (J1+n); _Z=(__m128*) (J1+2*n); for( i1=i; i1<n1; i1+=4 ) { _x = *_X; _y=*_Y; _z=*_Z; _z = RCP(ADD(_x,ADD(_cEps,ADD(MUL(_c15,_y),MUL(_c3,_z))))); *(_X++) = MUL(_c1024,_y); *(_Y++) = SUB(MUL(MUL(_c52,_x),_z),_cun); *(_Z++) = SUB(MUL(MUL(_c117,_y),_z),_cvn); } } { // perform lookup for L and finalize computation of U and V for( i1=i; i1<n1; i1++ ) J[i1] = lTable[(int)J[i1]]; __m128 *_L, *_U, *_V, _l, _cminu, _cminv; _L=(__m128*) J1; _U=(__m128*) (J1+n); _V=(__m128*) (J1+2*n); _cminu=SET(minu); _cminv=SET(minv); for( i1=i; i1<n1; i1+=4 ) { _l = *(_L++); *_U = SUB(MUL(_l,*_U),_cminu); _U++; *_V = SUB(MUL(_l,*_V),_cminv); _V++; } } i = n1; } }
LuvColor* create_luv_image(const IplImage *pSrc) { long xstart=0; long deltapos=0; IplImage *temp = const_cast<IplImage*>(pSrc); RgbImage img(temp); int width = pSrc->width; int height = pSrc->height; LuvColor *luvData = new LuvColor[width * height]; for (int i = 0; i < height; i++) { xstart = i*width; for ( int j = 0; j < width; j++) { deltapos = xstart + j; rgb2luv((int)img[i][j].r,(int)img[i][j].g , (int)img[i][j].b, luvData[deltapos] ); } } }
// when there is much color accepted, this function // will lead to an dead loop RgbColor RandomColor::diff_random_color(){ if (_acceptedColors.size() < _defColors.size()) { // usef default color first return _idxDefColors[_acceptedColors.size()]->second; } LuvColor newluv; RgbColor color; while(true){ color = random_color(); newluv = rgb2luv(color); int i = 0; while( i < _acceptedColors.size()) { // condition if(LuvColor::color_distance(newluv, _acceptedColors[i]) < _dist){ break; } i++; } if (i == _acceptedColors.size()) break; } return color; }
LuvColor rgb2luv(const RgbColor &rgb){ LuvColor luvdata; rgb2luv(rgb.r, rgb.g, rgb.b, luvdata); return luvdata; }