Home › Forums › Software Development › Getting the Pupillary Distance › Reply To: Getting the Pupillary Distance

Hi,
I downloaded the Tobbi Stream Engine API and wrote a small C++ code.
I succeeded getting the normalized eye position (tobii_eye_position_normalized_t) and the track box dimensions (tobii_track_box_t).
I am trying to un-normalize the eye position and calculate the PD (pupillary distance).
I get a number which seems in the right order, but it is very sensitive to the distance from the Tobii eye tracker (It becomes larger as I get closer to the eye tracker). I guess I need to perform some more distance normalization.
Can you please help me understand which part am I missing?
Here is my C++ code:
#include <tobii/tobii.h>
#include <tobii/tobii_streams.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <windows.h>
#include <assert.h>
tobii_track_box_t track_box;
void eye_position_callback(tobii_eye_position_normalized_t const* eye_pos, void* user_data)
{
if ((eye_pos->left_validity == TOBII_VALIDITY_VALID) && (eye_pos->right_validity == TOBII_VALIDITY_VALID))
{
double N_X_L, N_Y_L, N_Z_L, N_X_R, N_Y_R, N_Z_R, U_X_L, U_Y_L, U_Z_L, U_X_R, U_Y_R, U_Z_R;
N_X_L = eye_pos->left_xyz[0];
N_Y_L = eye_pos->left_xyz[1];
N_Z_L = eye_pos->left_xyz[2];
N_X_R = eye_pos->right_xyz[0];
N_Y_R = eye_pos->right_xyz[1];
N_Z_R = eye_pos->right_xyz[2];
U_X_L = ((track_box.back_lower_left_xyz[0] – track_box.front_upper_right_xyz[0]) * N_X_L);
U_Y_L = ((track_box.back_lower_left_xyz[1] – track_box.front_upper_right_xyz[1]) * N_Y_L);
U_Z_L = ((track_box.back_upper_right_xyz[2] – track_box.front_lower_left_xyz[2]) * N_Z_L);
U_X_R = ((track_box.back_lower_left_xyz[0] – track_box.front_upper_right_xyz[0]) * N_X_R);
U_Y_R = ((track_box.back_lower_left_xyz[1] – track_box.front_upper_right_xyz[1]) * N_Y_R);
U_Z_R = ((track_box.back_lower_left_xyz[2] – track_box.front_upper_right_xyz[2]) * N_Z_R);
double PD = sqrt(pow(U_X_R – U_X_L, 2.0) + pow(U_Y_R – U_Y_L, 2.0) + pow(U_Z_R – U_Z_L, 2.0));
printf(“PD : %f\r”, PD);
}
}
static void url_receiver(char const* url, void* user_data)
{
char* buffer = (char*)user_data;
if (*buffer != ‘\0’) return; // only keep first value
if (strlen(url) < 256)
strcpy(buffer, url);
}
int main()
{
tobii_api_t* api;
tobii_error_t error = tobii_api_create(&api, NULL, NULL);
assert(error == TOBII_ERROR_NO_ERROR);
char url[256] = { 0 };
error = tobii_enumerate_local_device_urls(api, url_receiver, url);
assert(error == TOBII_ERROR_NO_ERROR && *url != ‘\0’);
tobii_device_t* device;
error = tobii_device_create(api, url, &device);
assert(error == TOBII_ERROR_NO_ERROR);
error = tobii_eye_position_normalized_subscribe(device, eye_position_callback, 0);
assert(error == TOBII_ERROR_NO_ERROR);
error = tobii_get_track_box(device, &track_box);
assert(error == TOBII_ERROR_NO_ERROR);
// print just a couple of values of the track box data
printf(“Front upper left is (%f, %f, %f)\n”,
track_box.front_upper_left_xyz[0],
track_box.front_upper_left_xyz[1],
track_box.front_upper_left_xyz[2]);
printf(“Front upper right is (%f, %f, %f)\n”,
track_box.front_upper_right_xyz[0],
track_box.front_upper_right_xyz[1],
track_box.front_upper_right_xyz[2]);
printf(“Front lower left is (%f, %f, %f)\n”,
track_box.front_lower_left_xyz[0],
track_box.front_lower_left_xyz[1],
track_box.front_lower_left_xyz[2]);
printf(“Front lower right is (%f, %f, %f)\n”,
track_box.front_lower_right_xyz[0],
track_box.front_lower_right_xyz[1],
track_box.front_lower_right_xyz[2]);
printf(“Back upper left is (%f, %f, %f)\n”,
track_box.back_upper_left_xyz[0],
track_box.back_upper_left_xyz[1],
track_box.back_upper_left_xyz[2]);
printf(“Back upper right is (%f, %f, %f)\n”,
track_box.back_upper_right_xyz[0],
track_box.back_upper_right_xyz[1],
track_box.back_upper_right_xyz[2]);
printf(“Back lower left is (%f, %f, %f)\n”,
track_box.back_lower_left_xyz[0],
track_box.back_lower_left_xyz[1],
track_box.back_lower_left_xyz[2]);
printf(“Back lower right is (%f, %f, %f)\n”,
track_box.back_lower_right_xyz[0],
track_box.back_lower_right_xyz[1],
track_box.back_lower_right_xyz[2]);
printf(“\n”);
for (;;)
{
error = tobii_wait_for_callbacks(NULL, 1, &device);
assert(error == TOBII_ERROR_NO_ERROR || error == TOBII_ERROR_TIMED_OUT);
error = tobii_device_process_callbacks(device);
assert(error == TOBII_ERROR_NO_ERROR);
if (GetKeyState(VK_ESCAPE) & 0x8000)
break;
}
error = tobii_eye_position_normalized_unsubscribe(device);
assert(error == TOBII_ERROR_NO_ERROR);
error = tobii_device_destroy(device);
assert(error == TOBII_ERROR_NO_ERROR);
error = tobii_api_destroy(api);
assert(error == TOBII_ERROR_NO_ERROR);
return 0;
}
Thanks,
Chaim