title: Essential matrix estimates movements in a wrong axis
body: <p>I'm trying to estimate the pose of a monocular camera but when I use the recoverPose function I'm getting most movements along z axis while I'm only moving the camera horizontally. In my aplication we need to recover the pose so that we can generate a 3D model of the recorded scenario.</p>
  <p>Actually we are using a depth camera to generate 3D points but when we tried to use PnP to compute the Translation it lead to horrible results. As the Essential matrix only provides an unitari displacement we computed an scaling factor by comparing distances between two pairs of points.</p>
  <p>In order to accumulate the movement we multiplied the homogeneous transformation between each consecutive camera pose and then for each frame we multiply the XYZ1 vector by this homogeneous transformation.</p>
  <p>We have tried to change the pose estimation algorithm to one of those embeded in solvePnP functions with depth sensor. Aparently the feature matching is pretty robust, and as we are computing them between consecutive frames of a 30fps image stream.</p>
  <p>When multiplying the transformation I think that the matrix given by recoverPose should be inverted, but in neither case it gives good results.</p>
  <h1>Extracting features</h1>
  <pre class="lang-py prettyprint-override"><code>def find_correspondence(old_ip,old_features, new_ip, new_features):
      # BFMatcher with default params
      #Flag per si estem perduts, actualment es salta la foto i pasa a la seguent pero probablement funcioni millor
      # si tornem enrere i agafem el u~ltim frame amb una bona transformada com a nova referencia
      bf=cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)
      matches = bf.match(old_features,new_features)    #debugat una mica aquesta part, feia el tonto amb alguns vectors
      matches=sorted(matches, key = lambda x:x.distance)
      old_ip_loc= [old_ip[mat.queryIdx].pt for mat in matches]
      new_ip_loc= [new_ip[mat.trainIdx].pt for mat in matches]
      old_ip_loc=np.round(old_ip_loc)# without round
      new_ip_loc=np.round(new_ip_loc)# without round
      return old_ip_loc.astype(int),new_ip_loc.astype(int)
  </code></pre>
  <h1>Computing essential matrix</h1>
  <pre class="lang-py prettyprint-override"><code>#find correspondence to the first image database with the last photo recorded
      points1,points2=find_correspondence(PointDatabase[counterframe-1],FeatureDatabase[counterframe-1],int_points, features)
  
      
  
  if flag==False:# normal proces, the image is not required to be avoid
          #Esential Matrix
          E,mask=cv.findEssentialMat(points1, points2, focallength,PPCam, cv.RANSAC, 0.099, 1.0)
          #Get pose refered to the first photo database
          _, R, t, mask = cv.recoverPose(E,points1,points2,focal=focallength,pp=PPCam)
          #Save the pose matrix
          PoseNoScale=np.concatenate((R,t),1)
  
  </code></pre>
  <h1>Computing correction</h1>
  <pre class="lang-py prettyprint-override"><code>
  for var in range (0,len(points1commun)-1):
  
      Pospoint1btw21 = cv.triangulatePoints(Poses3x4[counterframe-1],Poses3x4[counterframe-2], points2commun[var], points1commun[var])
      Pospoint2btw21 = cv.triangulatePoints(Poses3x4[counterframe-1],Poses3x4[counterframe-2], points2commun[var+1], points1commun[var+1])
      Pospoint1btw23 = cv.triangulatePoints(Poses3x4[counterframe-1], PoseNoScale, points2commun[var], points3commun[var])
      Pospoint2btw23 = cv.triangulatePoints(Poses3x4[counterframe-1], PoseNoScale, points2commun[var+1], points3commun[var+1])
  
                  Pospoint1btw21X.append(Pospoint1btw21[0]/Pospoint1btw21[3])
                  Pospoint2btw21X.append(Pospoint2btw21[0]/Pospoint2btw21[3])
                  Pospoint1btw23X.append(Pospoint1btw23[0]/Pospoint1btw23[3])
                  Pospoint2btw23X.append(Pospoint2btw23[0]/Pospoint2btw23[3])
                  #4 check if the distance between two keypoints remain the same if its the case, the scale is 1 otherwise correct the scale
                  
  ComputeScale.append(abs(scale*(Pospoint1btw23X[var]-Pospoint2btw23X[var])/((Pospoint1btw21X[var]-Pospoint2btw21X[var]))))
  
  #5 Reject outliers
          ComputeScaleClean=[]
      meanscale=np.mean(ComputeScale)
              
      for var2 in range (0,len(ComputeScale)):
          #the scale has to be low
          if ComputeScale[var2]&lt;meanscale:
  #the points has to be more or less similar so de difference of distance is *10 or /10
                  if ComputeScale[var2]&gt;=0.1 and ComputeScale[var2]&lt;=10 :
                          ComputeScaleClean.append(ComputeScale[var2])
                  
      if len(ComputeScaleClean)&gt;=1:
          scale=np.median(ComputeScaleClean)
      else:
          # reset scale
          scale=scale
  
  </code></pre>
  <p>As the movement is horizontal we expected a great variation on one axis and close to zero variation in Z axis but actually we obtained big variations in both x,z which is clearly wrong.</p>
  <p>Thank you in advance!</p>