static void convertRGB( Image & luv, const Image & rgb ) { if( rgb.C()!= 3 ) throw std::invalid_argument( "RGB image required!" ); const int W = rgb.W(), H = rgb.H(); luv.create( W, H, 3 ); int i; for( i=0; i+3<W*H; i+=4 ) { __m128 r,g,b,l,u,v; float * rr = (float*)&r, * gg = (float*)&g, * bb = (float*)&b; float * ll = (float*)&l, * uu = (float*)&u, * vv = (float*)&v; for( int k=0; k<4; k++ ){ rr[k] = rgb[3*(i+k)+0]; gg[k] = rgb[3*(i+k)+1]; bb[k] = rgb[3*(i+k)+2]; } convertRGB<SRGB,type>( l, u, v, r, g, b ); for( int k=0; k<4; k++ ){ luv[3*(i+k)+0] = ll[k]; luv[3*(i+k)+1] = uu[k]; luv[3*(i+k)+2] = vv[k]; } } for( ; i<W*H; i++ ) convertRGB<SRGB,type>( luv[3*i+0],luv[3*i+1],luv[3*i+2], rgb[3*i+0],rgb[3*i+1],rgb[3*i+2] ); }
static Image convert( const Image & image ) { if( image.C() != 3 ) throw std::invalid_argument( "3-channel image required" ); Image r( image.W(), image.H(), 3 ); cfun[T]( r, image ); return r; }
void rgb2hsv( Image & hsv, const Image & rgb ) { if( rgb.C()!= 3 ) throw std::invalid_argument( "RGB image required!" ); const int W = rgb.W(), H = rgb.H(); hsv.create( W, H, 3 ); const int N = W*H; for( int i=0; i<N; i++ ) { float s,v; hsv[3*i+2] = v = std::max(rgb[3*i+0],std::max(rgb[3*i+1],rgb[3*i+2])); hsv[3*i+1] = s = v-std::min(rgb[3*i+0],std::min(rgb[3*i+1],rgb[3*i+2])); if( v == rgb[3*i+0] ) hsv[3*i+0] = (rgb[3*i+1] - rgb[3*i+2]) / (6.*s+1e-10); else if( v == rgb[3*i+1] ) hsv[3*i+0] = (2+rgb[3*i+2] - rgb[3*i+0]) / (6.*s+1e-10); else if( v == rgb[3*i+2] ) hsv[3*i+0] = (4+rgb[3*i+0] - rgb[3*i+1]) / (6.*s+1e-10); if( hsv[3*i+0] < 0 ) hsv[3*i+0] += 1; } }
static void convertRGB( Image & luv, const Image & rgb ) { if( rgb.C()!= 3 ) throw std::invalid_argument( "RGB image required!" ); const int W = rgb.W(), H = rgb.H(); luv.create( W, H, 3 ); int i; for( i=0; i+3<W*H; i+=4 ) { __m128 r = _mm_set_ps( rgb[3*i+0], rgb[3*(i+1)+0], rgb[3*(i+2)+0], rgb[3*(i+3)+0] ); __m128 g = _mm_set_ps( rgb[3*i+1], rgb[3*(i+1)+1], rgb[3*(i+2)+1], rgb[3*(i+3)+1] ); __m128 b = _mm_set_ps( rgb[3*i+2], rgb[3*(i+1)+2], rgb[3*(i+2)+2], rgb[3*(i+3)+2] ); __m128 l,u,v; convertRGB<SRGB,type>( l, u, v, r, g, b ); float * ll = (float*)&l, * uu = (float*)&u, * vv = (float*)&v; for( int k=0; k<4; k++ ){ luv[3*(i+k)+0] = ll[k]; luv[3*(i+k)+1] = uu[k]; luv[3*(i+k)+2] = vv[k]; } } for( i=0; i<W*H; i++ ) convertRGB<SRGB,type>( luv[3*i+0],luv[3*i+1],luv[3*i+2], rgb[3*i+0],rgb[3*i+1],rgb[3*i+2] ); }
static np::ndarray extractBoxes( const Image &im, const RMatrixXi & b, int W, int H ) { // Create the output array const int C = im.C(); const int im_W = im.W(); np::ndarray res = np::empty( make_tuple( b.rows(), H, W, C ), np::dtype::get_builtin<float>() ); const float * pim = (const float *)im.data(); float * pres = (float *)res.get_data(); #pragma omp parallel for for( int i=0; i<b.rows(); i++ ) { // Build the lerp lookup table const float Y0=b(i,0), X0=b(i,1); const float dy=b(i,2)-Y0-1, dx=b(i,3)-X0-1; std::vector< int > x0( W ), y0( H ), x1( W ), y1( H ); std::vector< float > wx( W ), wy( H ); for( int j=0; j<H; j++ ) { float p = Y0 + j*dy/(H-1); y0[j] = floor(p); y1[j] = ceil(p); wy[j] = y1[j]-p; } for( int j=0; j<W; j++ ) { float p = X0 + j*dx/(W-1); x0[j] = floor(p); x1[j] = ceil(p); wx[j] = x1[j]-p; } // Run the lerp float * pr = pres + i*H*W*C; for( int j=0; j<H; j++ ) for( int i=0; i<W; i++ ) for( int k=0; k<C; k++ ) pr[ (j*W+i)*C+k ] = wx[i] * wy[j] *pim[ ( y0[j]*im_W+x0[i] )*C+k ] + wx[i] *(1-wy[j])*pim[ ( y1[j]*im_W+x0[i] )*C+k ] +(1-wx[i])* wy[j] *pim[ ( y0[j]*im_W+x1[i] )*C+k ] +(1-wx[i])*(1-wy[j])*pim[ ( y1[j]*im_W+x1[i] )*C+k ]; } return res; }