ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

image_geometry projectPixelTo3dRay World Coordinates

asked 2016-01-12 12:17:46 -0500

Gren8 gravatar image

Good evening, i have a problem and i need help as fast as possible. For a tracking program i try to subscribe from two image_rect_color + their camera_infos. i have already calibrated the cameras with the ros package camera_calibration and i stored in the camera_info file. Now i am trying to get real world coordinates with the image_geometry package.

Put if i pick a pixel point (98,200) and compute it via projectPixelTo3dRayit only gives me strange values and z is always 1. Example: point (98,200) = [-0.269315, -0.0648566, 1]. Do i understand something wrong? What else can I do to get real world coordinates? The intrinsic and extrinsic values are stored in the camera_info.

Please help its important for me!

image_geometry::PinholeCameraModel model1;
image_geometry::PinholeCameraModel model2;

void callback(const ImageConstPtr& sub1, const CameraInfoConstPtr& cam_info1,const ImageConstPtr& sub2 , const CameraInfoConstPtr& cam_info2){


    double stamp_1 =sub1->header.stamp.toSec();
    double stamp_2 =sub2->header.stamp.toSec();
    ROS_INFO("\nCALLBACK GETS CALLED\n TIME_STAMP_IMAGE1: %f\n TIME_STAMP_IMAGE2: %f\n", stamp_1, stamp_2);
    model1.fromCameraInfo(cam_info1);
    model2.fromCameraInfo(cam_info2);
    cv::Point2d pixel_point(98, 200);
    cv::Point3d xyz = model1.projectPixelTo3dRay(pixel_point);
    cout << "point (3D) = " << xyz << endl << endl;


}

int main(int argc, char** argv) {

    ros::init( argc, argv, "sync_test" );
    ros::NodeHandle nh;
    //namedWindow("window1", CV_WINDOW_NORMAL);
    //namedWindow("window2", CV_WINDOW_NORMAL);
    //cv::startWindowThread();

    message_filters::Subscriber<Image> sub1(nh, "/usb_cam/image_rect_color", 5);
    message_filters::Subscriber<CameraInfo> info_sub1(nh, "/usb_cam/camera_info", 5);
    message_filters::Subscriber<Image> sub2(nh, "/usb_cam/image_rect_color", 5);
    message_filters::Subscriber<CameraInfo> info_sub2(nh, "/usb_cam/camera_info", 5);


    typedef sync_policies::ApproximateTime<Image,CameraInfo,Image,CameraInfo> MySyncPolicy;
    // ApproximateTime takes a queue size as its constructor argument, hence MySyncPolicy(10)

    Synchronizer<MySyncPolicy> sync(MySyncPolicy(10), sub1,info_sub1, sub2,info_sub2);
    //sync.setAgePenalty(1.0);
    sync.registerCallback(boost::bind(&callback, _1, _2,_3,_4));

    ros::spin();

    return 0;

}
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
2

answered 2016-01-12 12:25:57 -0500

NEngelhard gravatar image

updated 2016-01-12 12:28:28 -0500

The pixel corresponds to a ray that starts at your camera position and passes through the point (-0.269315, -0.0648566, 1) (in your camera frame). If you pass the center point of your image, the point should be (0,0,1). z = 1 is just a random point on this line.

The docu is also very helpful: http://docs.ros.org/jade/api/image_ge...

http://docs.ros.org/jade/api/image_ge...

edit flag offensive delete link more

Comments

thanks for the answer! If i take a random point (400,56) the output is [0.102615, -0.244058, ] Could you give me an example of how i get my real world coordinates in mm now? I know its in the link you posted but i don't really understand it.

Gren8 gravatar image Gren8  ( 2016-01-12 12:44:00 -0500 )edit
1

The point is in m, so just multiply with 1000?

NEngelhard gravatar image NEngelhard  ( 2016-01-12 13:33:00 -0500 )edit

but if my output is a unit vector [0.102615, -0.244058, 1 ] and i multiply it by 1000 why do i get a negative mm value?

Gren8 gravatar image Gren8  ( 2016-01-12 13:55:06 -0500 )edit
1

why do you expect positive values for all axis?

NEngelhard gravatar image NEngelhard  ( 2016-01-12 15:08:10 -0500 )edit
0

answered 2022-12-08 06:37:39 -0500

We have K, P, R and D What they mean

We need translation matrix t

To understand more

Translation matrix

t = Kinv * last column of P

T = Kinv ( 3 x 3) X P_last (3 x 1) = 3 x 1

E = [ R T ]

Sharing the python code to get intrinsic and extrinsic values.

import numpy as np
K = np.array(K)
P = np.array(P)
R = np.array(R)

K.resize(3,3)
P.resize(3,4)
R.resize(3,3)

# Inverse of K
Kinv = np.linalg.inv(np.array(K))
print("K inverse shape",Kinv.shape)

# t the translation matrix equals Kinv * last column of P
t = np.matmul(Kinv, P[:,-1])
print(t)
t.reshape(3,1)

print("T shape",t.shape)

# Extrinsic matrix equals [R t]
Ext = np.append(R, t.reshape(3,1), axis=1)
Ext = np.append(Ext,E_l, axis=0)
print("Extrinsic matrix shape",Ext.shape)
print("Extrinsic value")
print(Ext)

#Intrinsic matrix is K 
# Itx = np.expand_dims(K, axis=1)
Itx = np.append(K, np.zeros((3,1)), axis=1)

print("Intrinsic matrix shape",Itx.shape)
print("Intrinsic value")
print(Itx)


# K inverse shape (3, 3)
# [0. 0. 0.]
# T shape (3,)
# Extrinsic matrix shape (4, 4)
# Extrinsic value
# [[0. 0. 0. 0.]
#  [0. 0. 0. 0.]
#  [0. 0. 0. 0.]
#  [0. 0. 0. 1.]]
# Intrinsic matrix shape (3, 4)
# Intrinsic value
# [[1.47189169e+03 0.00000000e+00 6.12685607e+02 0.00000000e+00]
#  [0.00000000e+00 1.45716331e+03 3.62717679e+02 0.00000000e+00]
#  [0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00]]
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-01-12 12:17:46 -0500

Seen: 2,552 times

Last updated: Dec 08 '22