This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

VLIB 2.2 using Lucas Kanade

Dear Sirs, Dear Support Team,

 I’m working as an external employee for AUDI a German car manufacturer belonging to Volkswagen (VW).

We have a custom board with DaVinci Processor dm8148. I’m programming vision applications using the DSP C674x of the DaVinci processor and VLIB_2_2 from TI.

Using the function VLIB_trackFeaturesLucasKanade_7x7 to get the optical flow we observe some strange behavior we have no explanation yet.

As a starting-point we used the example “VLIB_testTrackFeaturesLucasKanade_7x7.c” which comes together with the VLIB_testExamples. We created our own little patterns using the following two functions to create previous image and next image. Both are of size 64x64 with a white square on black background.

static void CreatePattern3(unsigned char *p)

{

      int i,j;

      for (i = 0; i < 64*64; i++)

      {

            p[i]=0;

      }

 

      for( j = 16; j<48; j++)

      {

            for (i = 16; i < 48; i++)

            {    

                        p[j*64 + i]=255;

            }

      }

}

 

static void CreatePattern4(unsigned char *p)

{

      int i,j;

      for (i = 0; i < 64*64; i++)

      {

            p[i]=0;

      }

 

      for( j = 21; j<53; j++)

      {

            for (i = 21; i < 53; i++)

            {

                        p[j*64 + i]=255;

            }

      }

}

The refined points : { 1.9,17.3}  {59.8, 3.6}  { 1.9,45.8}  {27.0,27.0} are nonsense. But when we lower the contrast between foreground and background using

 

static void CreatePattern3(unsigned char *p)

{

      int i,j;

      for (i = 0; i < 64*64; i++)

      {

            p[i]=0;

      }

 

      for( j = 16; j<48; j++)

      {

            for (i = 16; i < 48; i++)

            {    

                        p[j*64 + i]=16;

            }

      }

}

 

static void CreatePattern4(unsigned char *p)

{

      int i,j;

      for (i = 0; i < 64*64; i++)

      {

            p[i]=0;

      }

 

      for( j = 21; j<53; j++)

      {

            for (i = 21; i < 53; i++)

            {

                        p[j*64 + i]=16;

            }

      }

}

 

We get perfect results:

refined points : {21.0,21.0}  {49.8,21.2}  {21.2,49.8}  {51.9,51.9}

 

For completeness the whole code:

#include <stdio.h>

#include <VLIB_prototypes.h>

 

static unsigned char IMAGE1[64*64];

static unsigned char IMAGE2[64*64];

static short GRADX[64*64];

static short GRADY[64*64];

static short GRADMAG[64*64];

 

#define NFEATURES 4

 

int VLIB_testTrackFeaturesLucasKanade_7x7(void)

{    

 

   short X[NFEATURES] = {16.0f*16, 47.0f * 16, 16.0f * 16, 47.0f * 16};

   short Y[NFEATURES] = {16.0f*16, 16.0f * 16, 47.0f * 16, 47.0f * 16};

 

   short mX[NFEATURES];

   short mY[NFEATURES];

 

   unsigned char BUFFER[384];

 

   int i, size;

   int errorCount = 0;

 

   // Synthetic motion sequence

   CreatePattern3(IMAGE1);

   CreatePattern4(IMAGE2);

 

   // Initial guesses for the feature points

   for (i = 0; i < NFEATURES; i++)

   {

         mX[i] = X[i];

         mY[i] = Y[i];

   }

 

 

   #ifdef WIN32

   #define VLIB_xyGradientsAndMagnitudeOLD VLIB_xyGradientsAndMagnitude

   #endif  

 

   // Compute the gradient using the library function

   VLIB_xyGradientsAndMagnitude(IMAGE1, GRADX+64+1, GRADY+64+1,                     GRADMAG+64+1, 64, 64); //Pointer starts from the image one row and one column less

 

   printf("Testing VLIB_trackFeaturesLucasKanade_7x7...\n\n");

 

     

   VLIB_trackFeaturesLucasKanade_7x7(IMAGE1, IMAGE2, GRADX, GRADY, 64, 64, NFEATURES, X, Y, mX, mY, 10, BUFFER);

 

     

   printf("previous points: {%d,%d}  {%d,%d}  {%d,%d}  {%d,%d}\n\n",

            X[0]>>4, Y[0]>>4, X[1]>>4, Y[1]>>4, X[2]>>4, Y[2]>>4, X[3]>>4, Y[3]>>4);

 

   printf("refined points : {%4.1f,%4.1f}  {%4.1f,%4.1f}  {%4.1f,%4.1f}  {%4.1f,%4.1f}\n\n", shift(mX[0]), shift(mY[0]), shift(mX[1]), shift(mY[1]), shift(mX[2]), shift(mY[2]), shift(mX[3]), shift(mY[3]));

 

 

   return 0;

}

 

float shift(short in)

{

      float out = ((float) in)  / 16.0f;

 

      return out;

}

 

Are there any requirements for the values of the input image ? Do they have to be scaled in any manner ?

 

Any help is appreciated.

 

Kind regards

 

Stefan