Search code examples
opencv3dcameraprojection

3d points project 2d points error


I'm tried to project human skeleton 3d points to 2d points by using cv2.projectpoints.

Here is my code:

tmp = np.array(data_3d['root'][i]).reshape(1,3)
revc = np.array([0, -15, -25], np.float)  # rotation vector
tvec = np.array([-2, -2, -12], np.float)  # translation vector
fx = fy = 1.0
cx = cy = 0.0
cameraMatrix = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]])
result = cv2.projectPoints(tmp, revc, tvec, cameraMatrix, None)

But I find some strange 2d points during projection.

root:
     X min_max=(-166.92720209469152, 1243.4813901875507)
       mean=4.290786012592475, variance=4722.3197294835645
     Y min_max=(-402.9192018458054,55.87842522603996)
       mean=0.11309526315136062, variance=499.5386080289831
head:
     X min_max=(-1757.835481879438, 425.7047344280786)
       mean=-4.077206416367477, variance=10165.268433754276
     Y min_max=(-426.06627880880535, 104.67033311809274) 
       mean=0.14534586064178603, variance=600.3554834467959

So I print these out

root error

and

head error

As it seems, there is some strange change.

40 => 80 => 190 => 425 => -1757 => -268 => -60 => -33

My question is why this strange thing will happen?

I think it maybe occlusion at first, but head won't be obscured.


Solution

  • The rotation vector rvec is in radians, not degrees. Rather declare it as:

    revc = np.rad2deg(np.array([0, -15, -25], np.float))  # rotation vector
    

    Also, the focal length fx=fx=1 is in meters, and I doubt your camera has a focal length of 1 mm. If your focal length is 1 millimeter, rather say:

    fx = fy = .001 # in meters
    

    If you need more help, rather plot those points on an image, and show us the image. This will also give you a good idea of how your projection looks. This can be done with:

    from matplotlib import pyplot as plt
    plt.scatter(*zip(*result[0][:,0,:]))
    plt.show()
    

    Also, what do you mean with the following?

    As it seems, there is some strange change.

    40 => 80 => 190 => 425 => -1757 => -268 => -60 => -33