constexpr float PI = 3.14159265358979323846f; void undistort_points_pinhole_cpp( const std::vector &K, const std::vector &D, int num_points, std::vector &unit_vector) { std::vector distorted(num_points * 2, 0.f); std::vector undistorted(num_points * 2, 0.f); // Generate distorted points (same as original) for (int y = 0; y < 48; ++y) { for (int x = 0; x < 120; ++x) { int idx = (y * 120 + x) * 2; distorted[idx] = (x + 0.5f); distorted[idx + 1] = (y + 0.5f); } } unit_vector.resize(num_points * 3); float fx = K[0]; float fy = K[4]; float cx = K[2]; float cy = K[5]; float k1 = D[0], k2 = D[1], p1 = D[2], p2 = D[3], k3 = D[4]; for (int idx = 0; idx < num_points; ++idx) { int idx_two = idx * 2; int idx_three = idx * 3; float u = distorted[idx_two + 0]; float v = distorted[idx_two + 1]; //--------------------------------------------------------- // Step 1: Normalize distorted coords //--------------------------------------------------------- float xd = (u - cx) / fx; float yd = (v - cy) / fy; //--------------------------------------------------------- // Step 2: Iteratively solve undistorted x,y (Brown–Conrady) //--------------------------------------------------------- float x = xd; float y = yd; for (int iter = 0; iter < 5; iter++) { float r2 = x * x + y * y; float r4 = r2 * r2; float r6 = r4 * r2; float radial = 1 + k1 * r2 + k2 * r4 + k3 * r6; float x_tangential = 2 * p1 * x * y + p2 * (r2 + 2 * x * x); float y_tangential = p1 * (r2 + 2 * y * y) + 2 * p2 * x * y; float x_est = (xd - x_tangential) / radial; float y_est = (yd - y_tangential) / radial; x = x_est; y = y_est; } //--------------------------------------------------------- // Step 3: Convert to undistorted pixel coords //--------------------------------------------------------- float u_und = fx * x + cx; float v_und = fy * y + cy; undistorted[idx_two + 0] = u_und; undistorted[idx_two + 1] = v_und; //--------------------------------------------------------- // Step 4: Compute camera-frame unit vector //--------------------------------------------------------- float X = x; float Y = y; float Z = 1.0f; float norm = std::sqrt(X * X + Y * Y + Z * Z); //--------------------------------------------------------- // Optional ellipse mask (unchanged) //--------------------------------------------------------- // float ra = 1.f / (cx - 3); // float rb = 1.f / (cy + 4); // float mask = ((u - cx)*(u - cx)*ra*ra + // (v - cy)*(v - cy)*rb*rb - 1.f) < 0.f ? 1.f : 0.f; float mask = 1; unit_vector[idx_three + 0] = mask * (X / norm); unit_vector[idx_three + 1] = mask * (Y / norm); unit_vector[idx_three + 2] = mask * (Z / norm); } } void tof_to_xyz( const std::vector &unit_vector, const std::vector &tof, int num_points, std::vector &points3D) { points3D.resize(num_points * 3); for (int i = 0; i < num_points; ++i) { int idx3 = i * 3; float d = tof[i]; points3D[idx3 + 0] = unit_vector[idx3 + 0] * d; points3D[idx3 + 1] = unit_vector[idx3 + 1] * d; points3D[idx3 + 2] = unit_vector[idx3 + 2] * d; } } void depth_to_xyz( const std::vector &unit_vector, const std::vector &depth, int num_points, std::vector &points3D) { points3D.resize(num_points * 3); for (int i = 0; i < num_points; ++i) { int idx3 = i * 3; float d = depth[i]; points3D[idx3 + 0] = unit_vector[idx3 + 0]/ unit_vector[idx3 + 2] * d; points3D[idx3 + 1] = unit_vector[idx3 + 1]/ unit_vector[idx3 + 2] * d; points3D[idx3 + 2] = d; } } int main() { int WIDTH = 40; int HEIGHT = 30; int num_points = WIDTH * HEIGHT; std::vector unit_vector(num_points * 3, 0.f); std::vector depth(num_points , 0.f); std::vector points3D(num_points * 3 , 0.f); // 改成 *3 // 内参 float fx = 37; float fy = 37; float cx = 20; float cy = 15; // 畸变参数 float k1 = 0.f; float k2 = 0.f; float p1 = 0.f; float p2 = 0.f; float k3 = 0.f; std::vector K = {fx , 0.f, cx , 0.f, fy , cy , 0.f, 0.f, 1.f}; std::vector D = {k1, k2, p1, p2, k3}; // 生成 unit_vector undistort_points_pinhole_cpp(K, D, num_points, unit_vector); // 将 depth 转成相机坐标系 depth_to_xyz(unit_vector, depth, num_points, points3D); return 0; }