diff --git a/mediapipe/calculators/util/BUILD b/mediapipe/calculators/util/BUILD
index ea593aa3d..4c92e9492 100644
--- a/mediapipe/calculators/util/BUILD
+++ b/mediapipe/calculators/util/BUILD
@@ -929,6 +929,17 @@ cc_library(
     alwayslink = 1,
 )
 
+cc_test(
+    name = "landmarks_smoothing_calculator_utils_test",
+    size = "small",
+    srcs = ["landmarks_smoothing_calculator_utils_test.cc"],
+    deps = [
+        ":landmarks_smoothing_calculator_utils",
+        "//mediapipe/framework/formats:landmark_cc_proto",
+        "//mediapipe/framework/port:gtest_main",
+    ],
+)
+
 cc_library(
     name = "multi_landmarks_smoothing_calculator",
     srcs = ["multi_landmarks_smoothing_calculator.cc"],
diff --git a/mediapipe/calculators/util/landmarks_smoothing_calculator_utils.cc b/mediapipe/calculators/util/landmarks_smoothing_calculator_utils.cc
index 7e275807e..a381c823a 100644
--- a/mediapipe/calculators/util/landmarks_smoothing_calculator_utils.cc
+++ b/mediapipe/calculators/util/landmarks_smoothing_calculator_utils.cc
@@ -14,6 +14,8 @@
 
 #include "mediapipe/calculators/util/landmarks_smoothing_calculator_utils.h"
 
+#include <iostream>
+
 #include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h"
 #include "mediapipe/framework/formats/landmark.pb.h"
 #include "mediapipe/framework/formats/rect.pb.h"
@@ -260,8 +262,18 @@ void NormalizedLandmarksToLandmarks(
     landmark->set_y(norm_landmark.y() * image_height);
     // Scale Z the same way as X (using image width).
     landmark->set_z(norm_landmark.z() * image_width);
-    landmark->set_visibility(norm_landmark.visibility());
-    landmark->set_presence(norm_landmark.presence());
+
+    if (norm_landmark.has_visibility()) {
+      landmark->set_visibility(norm_landmark.visibility());
+    } else {
+      landmark->clear_visibility();
+    }
+
+    if (norm_landmark.has_presence()) {
+      landmark->set_presence(norm_landmark.presence());
+    } else {
+      landmark->clear_presence();
+    }
   }
 }
 
@@ -277,8 +289,18 @@ void LandmarksToNormalizedLandmarks(const LandmarkList& landmarks,
     norm_landmark->set_y(landmark.y() / image_height);
     // Scale Z the same way as X (using image width).
     norm_landmark->set_z(landmark.z() / image_width);
-    norm_landmark->set_visibility(landmark.visibility());
-    norm_landmark->set_presence(landmark.presence());
+
+    if (landmark.has_presence()) {
+      norm_landmark->set_presence(landmark.presence());
+    } else {
+      norm_landmark->clear_presence();
+    }
+
+    if (landmark.has_visibility()) {
+      norm_landmark->set_visibility(landmark.visibility());
+    } else {
+      norm_landmark->clear_visibility();
+    }
   }
 }
 
diff --git a/mediapipe/calculators/util/landmarks_smoothing_calculator_utils_test.cc b/mediapipe/calculators/util/landmarks_smoothing_calculator_utils_test.cc
new file mode 100644
index 000000000..2404beb1a
--- /dev/null
+++ b/mediapipe/calculators/util/landmarks_smoothing_calculator_utils_test.cc
@@ -0,0 +1,118 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "mediapipe/calculators/util/landmarks_smoothing_calculator_utils.h"
+
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/port/gmock.h"
+#include "mediapipe/framework/port/gtest.h"
+
+namespace mediapipe {
+namespace landmarks_smoothing {
+namespace {
+
+TEST(LandmarksSmoothingCalculatorUtilsTest, NormalizedLandmarksToLandmarks) {
+  NormalizedLandmarkList norm_landmarks;
+  NormalizedLandmark* norm_landmark = norm_landmarks.add_landmark();
+  norm_landmark->set_x(0.1);
+  norm_landmark->set_y(0.2);
+  norm_landmark->set_z(0.3);
+  norm_landmark->set_visibility(0.4);
+  norm_landmark->set_presence(0.5);
+
+  LandmarkList landmarks;
+  NormalizedLandmarksToLandmarks(norm_landmarks, /*image_width=*/10,
+                                 /*image_height=*/10, landmarks);
+
+  EXPECT_EQ(landmarks.landmark_size(), 1);
+  Landmark landmark = landmarks.landmark(0);
+  EXPECT_NEAR(landmark.x(), 1.0, 1e-6);
+  EXPECT_NEAR(landmark.y(), 2.0, 1e-6);
+  EXPECT_NEAR(landmark.z(), 3.0, 1e-6);
+  EXPECT_NEAR(landmark.visibility(), 0.4, 1e-6);
+  EXPECT_NEAR(landmark.presence(), 0.5, 1e-6);
+}
+
+TEST(LandmarksSmoothingCalculatorUtilsTest,
+     NormalizedLandmarksToLandmarks_EmptyVisibilityAndPresence) {
+  NormalizedLandmarkList norm_landmarks;
+  NormalizedLandmark* norm_landmark = norm_landmarks.add_landmark();
+  norm_landmark->set_x(0.1);
+  norm_landmark->set_y(0.2);
+  norm_landmark->set_z(0.3);
+  norm_landmark->clear_visibility();
+  norm_landmark->clear_presence();
+
+  LandmarkList landmarks;
+  NormalizedLandmarksToLandmarks(norm_landmarks, /*image_width=*/10,
+                                 /*image_height=*/10, landmarks);
+
+  EXPECT_EQ(landmarks.landmark_size(), 1);
+  Landmark landmark = landmarks.landmark(0);
+  EXPECT_NEAR(landmark.x(), 1.0, 1e-6);
+  EXPECT_NEAR(landmark.y(), 2.0, 1e-6);
+  EXPECT_NEAR(landmark.z(), 3.0, 1e-6);
+  EXPECT_FALSE(landmark.has_visibility());
+  EXPECT_FALSE(landmark.has_presence());
+}
+
+TEST(LandmarksSmoothingCalculatorUtilsTest, LandmarksToNormalizedLandmarks) {
+  LandmarkList landmarks;
+  Landmark* landmark = landmarks.add_landmark();
+  landmark->set_x(1.0);
+  landmark->set_y(2.0);
+  landmark->set_z(3.0);
+  landmark->set_visibility(0.4);
+  landmark->set_presence(0.5);
+
+  NormalizedLandmarkList norm_landmarks;
+  LandmarksToNormalizedLandmarks(landmarks, /*image_width=*/10,
+                                 /*image_height=*/10, norm_landmarks);
+
+  EXPECT_EQ(norm_landmarks.landmark_size(), 1);
+  NormalizedLandmark norm_landmark = norm_landmarks.landmark(0);
+  EXPECT_NEAR(norm_landmark.x(), 0.1, 1e-6);
+  EXPECT_NEAR(norm_landmark.y(), 0.2, 1e-6);
+  EXPECT_NEAR(norm_landmark.z(), 0.3, 1e-6);
+  EXPECT_NEAR(norm_landmark.visibility(), 0.4, 1e-6);
+  EXPECT_NEAR(norm_landmark.presence(), 0.5, 1e-6);
+}
+
+TEST(LandmarksSmoothingCalculatorUtilsTest,
+     LandmarksToNormalizedLandmarks_EmptyVisibilityAndPresence) {
+  LandmarkList landmarks;
+  Landmark* landmark = landmarks.add_landmark();
+  landmark->set_x(1.0);
+  landmark->set_y(2.0);
+  landmark->set_z(3.0);
+  landmark->clear_visibility();
+  landmark->clear_presence();
+
+  NormalizedLandmarkList norm_landmarks;
+  LandmarksToNormalizedLandmarks(landmarks, /*image_width=*/10,
+                                 /*image_height=*/10, norm_landmarks);
+
+  EXPECT_EQ(norm_landmarks.landmark_size(), 1);
+  NormalizedLandmark norm_landmark = norm_landmarks.landmark(0);
+  EXPECT_NEAR(norm_landmark.x(), 0.1, 1e-6);
+  EXPECT_NEAR(norm_landmark.y(), 0.2, 1e-6);
+  EXPECT_NEAR(norm_landmark.z(), 0.3, 1e-6);
+  EXPECT_FALSE(norm_landmark.has_visibility());
+  EXPECT_FALSE(norm_landmark.has_presence());
+}
+
+}  // namespace
+}  // namespace landmarks_smoothing
+}  // namespace mediapipe