Questions about the source code of the LK optical flow algorithm

#define  CV_DESCALE(x,n)     (((x) + (1 << ((n)-1))) >> (n))

float a = prevPt.x - iprevPt.x;
float b = prevPt.y - iprevPt.y;
const int W_BITS = 14, W_BITS1 = 14;
const float FLT_SCALE = 1.f/(1 << 20);
int iw00 = cvRound((1.f - a)*(1.f - b)*(1 << W_BITS));
int iw01 = cvRound(a*(1.f - b)*(1 << W_BITS));
int iw10 = cvRound((1.f - a)*b*(1 << W_BITS));
int iw11 = (1 << W_BITS) - iw00 - iw01 - iw10;


for( ; x < winSize.width*cn; x++, dsrc += 2, dIptr += 2 )
                int ival = CV_DESCALE(src[x]*iw00 + src[x+cn]*iw01 +
                                      src[x+stepI]*iw10 + src[x+stepI+cn]*iw11, W_BITS1-5);
                int ixval = CV_DESCALE(dsrc[0]*iw00 + dsrc[cn2]*iw01 +
                                       dsrc[dstep]*iw10 + dsrc[dstep+cn2]*iw11, W_BITS1);
                int iyval = CV_DESCALE(dsrc[1]*iw00 + dsrc[cn2+1]*iw01 + dsrc[dstep+1]*iw10 +
                                       dsrc[dstep+cn2+1]*iw11, W_BITS1);

                Iptr[x] = (short)ival;
                dIptr[0] = (short)ixval;
                dIptr[1] = (short)iyval;

                iA11 += (itemtype)(ixval*ixval);
                iA12 += (itemtype)(ixval*iyval);
                iA22 += (itemtype)(iyval*iyval);

I encountered a question while studying the LK sparse optical flow algorithm in OpenCV and reading the source code. In the code snippet, the coefficient iw is left-shifted by W_BITS units (14) for convenience in calculation. However, in the for loop, the value of ival is scaled and rounded using CV_DESCALE. I don’t understand why the second parameter is W_BITS - 5 (9), and why do we need to subtract 5?

I’m guessing that will leave five fractional bits in the result, while calculation happens with 14 fractional bits. I give no warranty. this is numerical code without comments. you’ll have to track down who wrote it and convince them with a chainsaw to add some comments.

thx u!
Hope to get more people’s help and reply!

int ival = CV_DESCALE(src[x]*iw00 + src[x+cn]*iw01 +
src[x+stepI]*iw10 + src[x+stepI+cn]*iw11, W_BITS1-5);

In the implementation of the calcOpticalFlowPyrLK function, I can understand the principle of the LK optical flow algorithm, and have no objection to the implementation in the LKTrackerInvoker function. But in the code, during the calculation process, why does the second parameter of DESCALE need to subtract 5 from W_BITS, that is, 9. I’ve been confused by this for days and don’t understand why. Please help me to answer.

When I use W_BITS as the second parameter, or for example W_BITS-2, there is a problem with the image results of optical flow tracking. Why do we have to use 5?

This post was flagged by the community and is temporarily hidden.