0

I am attempting to convert some opencv code from python to c++, and am a little lost. The python is:

if 0 < R[1,1] < 1:
    # If it gets here, the pose is flipped.

    # Flip the axes. E.g., Y axis becomes [-y0, -y1, y2].
    R *= np.array([
        [ 1, -1,  1],
        [ 1, -1,  1],
        [-1,  1, -1],
    ])

    # Fixup: rotate along the plane spanned by camera's forward (Z) axis and vector to marker's position
    forward = np.array([0, 0, 1])
    tnorm = T / np.linalg.norm(T)
    axis = np.cross(tnorm, forward)
    angle = -2*math.acos(tnorm @ forward)
    R = cv2.Rodrigues(angle * axis)[0] @ R

So far i have:

cv::Mat R;
if (0 < R.at<double>(1, 1) < 1) {

            // Flip the axes.E.g., Y axis becomes[-y0, -y1, y2].
            float mult[9] = { 1, -1, 1, 1, -1, 1,-1, 1, -1 };

            cv::Mat FlipAxes = cv::Mat(3, 3, CV_32F, mult);

            R *= FlipAxes;

                //# Fixup: rotate along the plane spanned by camera's forward (Z) axis and vector to marker's position
            cv::Vec3d forward(0, 0, 1);
            double tnorm = tvecBest / np.linalg.norm(T)
            axis = np.cross(tnorm, forward)
            angle = -2 * math.acos(tnorm @ forward)
            R = cv2.Rodrigues(angle * axis)[0] * R


        }

I am lost on these lines:

double tnorm = tvecBest / np.linalg.norm(T)
axis = np.cross(tnorm, forward)
angle = -2 * math.acos(tnorm @ forward)

what is the equivalent of np.linalg.norm in c++ opencv?

9
  • There isn't a direct one you can use cv::sqrt() and cv::pow() Commented Aug 22, 2018 at 15:15
  • Would you be able to give me a code example please? Commented Aug 22, 2018 at 15:16
  • How about using norm, or just directly doing normalize? Commented Aug 22, 2018 at 15:20
  • Thanks, can I do this?: cv::Vec3d tvecNorm(tvecBest); cv::normalize(tvecNorm, tvecNorm); Commented Aug 22, 2018 at 15:27
  • @anti Yes, that should work. Commented Aug 22, 2018 at 15:49

1 Answer 1

3

the np.linalg.norm(T) is just the L2 norm :

sqrt(T[0]*T[0]+T[1]*T[1]+T[2]*T[2]) 

np.cross(tnorm, forward) is the cross product:

axis[0] = tnorm[1]*forward[2]-tnorm[2]*forward[1]
axis[1] = -tnorm[0]*forward[2]+tnorm[2]*forward[0]
axis[2] = tnorm[0]*forward[1]-tnorm[1]*forward[0]
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you! So that gives me: cv::Vec3d forward(0, 0, 1); cv::Vec3d T(tvecBest); cv::Vec3d tnorm = sqrt(T[0] * T[0] + T[1] * T[1] + T[2] * T[2]); cv::Vec3d axis; axis[0] = tnorm[1] * forward[2] - tnorm[2] * forward[1]; axis[1] = -tnorm[0] * forward[2] + tnorm[2] * forward[0]; axis[2] = tnorm[0] * forward[1] - tnorm[1] * forward[0];
What is the c++ for : cv::Vec3d angle = -2 * math.acos(tnorm @ forward) ?
the @ is not a mathematical operator in python. Was it / operator ?
from what I read they meant @ to be a dot product : tnorm @ forward -> tnorm[0]*forward [0]+ tnorm[1]*forward [1]+ tnorm[2]*forward [2]
and angle must be a double : double angle = -2 * acos( tnorm[0]*forward [0]+ tnorm[1]*forward [1]+ tnorm[2]*forward [2])
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.