         }
     }
 
-    float chosen_bin = xcoord[maxbin[0]];
+    float chosen_bin = refined_angle[maxbin[0]];
     if( chosen_bin >= ORI_NBINS ) chosen_bin -= ORI_NBINS;
 
     float th = __fdividef(M_PI2 * chosen_bin , ORI_NBINS) - M_PI;

        if( prev1 < 0 )          prev1 += ORI_NBINS;
        if( next1 >= ORI_NBINS ) next1 -= ORI_NBINS;
        if( next2 >= ORI_NBINS ) next2 -= ORI_NBINS;
        xcoord[bin] = (   hist[prev2] + hist[next2]
                      + ( hist[prev1] + hist[next1] ) * 4.0f
                      +   hist[bin] * 6.0f ) / 16.0f;
    }
    for(int bin = 0; bin < ORI_NBINS; bin++) {
        hist[bin] = xcoord[bin];
    }
#endif // V2_WITH_OPENCV_SMOOTHING


    __syncthreads();

    // sub-cell refinement of the histogram cell index, yielding the angle
    // __shared__ float refined_angle[ORI_NBINS];
    // __shared__ float yval[ORI_NBINS];
    __shared__ float refined_angle[64];
    __shared__ float yval[64];

    for( int bin = threadIdx.x; __any( bin < ORI_NBINS ); bin += blockDim.x ) {
        if( bin < ORI_NBINS ) {
            const int prev = bin == 0 ? ORI_NBINS-1 : bin-1;
            const int next = bin == ORI_NBINS-1 ? 0 : bin+1;

            bool predicate = ( sm_hist[bin] > max( sm_hist[prev], sm_hist[next] ) );

            const float num  = predicate ? 3.0f *   sm_hist[prev] - 4.0f * sm_hist[bin] + sm_hist[next]   : 0.0f;
            const float denB = predicate ? 2.0f * ( sm_hist[prev] - 2.0f * sm_hist[bin] + sm_hist[next] ) : 1.0f;

            const float newbin = __fdividef( num, denB );

            predicate   = ( predicate && newbin >= 0.0f && newbin <= 2.0f );

            refined_angle[bin] = predicate ? prev + newbin : -1;
            yval[bin]          = predicate ?  -(num*num) / (4.0f * denB) + sm_hist[prev] : -INFINITY;
        } else {
            refined_angle[bin] = -1;
            yval[bin]          = -INFINITY;
        }
    }
    __syncthreads();

    int2 best_index = make_int2( threadIdx.x, threadIdx.x + 32 );

    BitonicSort::Warp32<float> sorter( yval );
    sorter.sort64( best_index );
    __syncthreads();

    // All threads retrieve the yval of thread 0, the largest
    // of all yvals.
    const float best_val = yval[best_index.x];
    const float yval_ref = 0.8f * __shfl( best_val, 0 );
    const bool  valid    = ( yval[best_index.x]  >= yval_ref );
    bool        written  = false;

    if( threadIdx.x < ORIENTATION_MAX_COUNT ) {
        if( valid ) {
            float chosen_bin = refined_angle[best_index.x];
            if( chosen_bin >= ORI_NBINS ) chosen_bin -= ORI_NBINS;
            float th = __fdividef(M_PI2 * chosen_bin , ORI_NBINS) - M_PI;
            ext->orientation[threadIdx.x] = th;
