2016-10-30 2 views
0

J'ai quelques questions pour faire des projets de flux optique. J'utilise Python 2 (en planifiant d'utiliser des lasagnes pour utiliser le deep learning pour apprendre le flux optique), et je ne sais pas comment convertir les fonctions C++ en python pour la visualisation des flux.flux optique fichiers .flo

  1. J'ai téléchargé (de http://vision.middlebury.edu/flow/data/comp/zip/other-gt-flow.zip) des paires d'images où je dois estimer leur flux optique, et leur flux de vérité au sol (.flo de fichier). Le problème est, quand je lis le fichier .flo dans le programme, c'est un code vectorisé. Comment puis-je les voir comme ils apparaissent sur la page Web (http://vision.middlebury.edu/flow/data/)? J'ai lu de diverses sources et essayé le suivant, mais ne fonctionne pas.

  2. En évaluant EPE (erreur de point final) sous quelle forme dois-je avoir ma prédiction à comparer avec le fichier .flo?

Le code:

################################ Reading flow file ################################ 

f = open('flow10.flo', 'rb') 

x = np.fromfile(f, np.int32, count=1) # not sure what this gives 
w = np.fromfile(f, np.int32, count=1) # width 
h = np.fromfile(f, np.int32, count=1) # height 
print 'x %d, w %d, h %d flo file' % (x, w, h) 

data = np.fromfile(f, np.float32) # vector 

data_2D = np.reshape(data, newshape=(388,584,2)); # convert to x,y - flow 
x = data_2D[...,0]; y = data_2D[...,1]; 

################################ visualising flow file ################################ 
mag, ang = cv2.cartToPolar(x,y) 
hsv = np.zeros_like(x) 
hsv = np.array([ hsv,hsv,hsv ]) 
hsv = np.reshape(hsv, (388,584,3)); # having rgb channel 
hsv[...,1] = 255; # full green channel 
hsv[...,0] = ang*180/np.pi/2 # angle in pi 
hsv[...,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX) # magnitude [0,255] 
bgr = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR) 
bgr = draw_hsv(data_2D) 
cv2.imwrite('opticalhsv.png',bgr) 

Répondre

0

Sur la page de Middlebury il y a un fichier zip appelé code de flux (http://vision.middlebury.edu/flow/code/flow-code.zip), qui fournit un outil appelé color_flow pour convertir les fichiers .flo aux images couleur. D'un autre côté, si vous voulez implémenter votre propre code pour faire la transformation, j'ai ce morceau de code (je ne peux pas fournir l'auteur original, ça fait longtemps) qui vous aide à calculer la couleur :

static Vec3b computeColor(float fx, float fy) 
{ 
static bool first = true; 

// relative lengths of color transitions: 
// these are chosen based on perceptual similarity 
// (e.g. one can distinguish more shades between red and yellow 
// than between yellow and green) 
const int RY = 15; 
const int YG = 6; 
const int GC = 4; 
const int CB = 11; 
const int BM = 13; 
const int MR = 6; 
const int NCOLS = RY + YG + GC + CB + BM + MR; 
static Vec3i colorWheel[NCOLS]; 

if (first) 
{ 
    int k = 0; 

    for (int i = 0; i < RY; ++i, ++k) 
     colorWheel[k] = Vec3i(255, 255 * i/RY, 0); 

    for (int i = 0; i < YG; ++i, ++k) 
     colorWheel[k] = Vec3i(255 - 255 * i/YG, 255, 0); 

    for (int i = 0; i < GC; ++i, ++k) 
     colorWheel[k] = Vec3i(0, 255, 255 * i/GC); 

    for (int i = 0; i < CB; ++i, ++k) 
     colorWheel[k] = Vec3i(0, 255 - 255 * i/CB, 255); 

    for (int i = 0; i < BM; ++i, ++k) 
     colorWheel[k] = Vec3i(255 * i/BM, 0, 255); 

    for (int i = 0; i < MR; ++i, ++k) 
     colorWheel[k] = Vec3i(255, 0, 255 - 255 * i/MR); 

    first = false; 
} 

const float rad = sqrt(fx * fx + fy * fy); 
const float a = atan2(-fy, -fx)/(float)CV_PI; 

const float fk = (a + 1.0f)/2.0f * (NCOLS - 1); 
const int k0 = static_cast<int>(fk); 
const int k1 = (k0 + 1) % NCOLS; 
const float f = fk - k0; 

Vec3b pix; 

for (int b = 0; b < 3; b++) 
{ 
    const float col0 = colorWheel[k0][b]/255.f; 
    const float col1 = colorWheel[k1][b]/255.f; 

    float col = (1 - f) * col0 + f * col1; 

    if (rad <= 1) 
     col = 1 - rad * (1 - col); // increase saturation with radius 
    else 
     col *= .75; // out of range 

    pix[2 - b] = static_cast<uchar>(255.f * col); 
} 

return pix; 
} 

Ensuite, il appelle la fonction ci-dessus pour tous les pixels:

static void drawOpticalFlow(const Mat_<Point2f>& flow, Mat& dst, float maxmotion = -1) 
{ 
dst.create(flow.size(), CV_8UC3); 
dst.setTo(Scalar::all(0)); 

// determine motion range: 
float maxrad = maxmotion; 

if (maxmotion <= 0) 
{ 
    maxrad = 1; 
    for (int y = 0; y < flow.rows; ++y) 
    { 
     for (int x = 0; x < flow.cols; ++x) 
     { 
      Point2f u = flow(y, x); 

      if (!isFlowCorrect(u)) 
       continue; 

      maxrad = max(maxrad, sqrt(u.x * u.x + u.y * u.y)); 
     } 
    } 
} 

for (int y = 0; y < flow.rows; ++y) 
{ 
    for (int x = 0; x < flow.cols; ++x) 
    { 
     Point2f u = flow(y, x); 

     if (isFlowCorrect(u)) 
      dst.at<Vec3b>(y, x) = computeColor(u.x/maxrad, u.y/maxrad); 
    } 
} 
} 

Ceci est pour mon usage dans OpenCV, mais l'aide de code devrait tous ceux qui veulent obtenir quelque chose de similaire.