Drop default arguments in Image Embedder C API
This commit is contained in:
		
							parent
							
								
									60fcfa74cc
								
							
						
					
					
						commit
						197358dfee
					
				| 
						 | 
					@ -108,28 +108,28 @@ struct ImageEmbedderOptions {
 | 
				
			||||||
// Creates an ImageEmbedder from provided `options`.
 | 
					// Creates an ImageEmbedder from provided `options`.
 | 
				
			||||||
// Returns a pointer to the image embedder on success.
 | 
					// Returns a pointer to the image embedder on success.
 | 
				
			||||||
// If an error occurs, returns `nullptr` and sets the error parameter to an
 | 
					// If an error occurs, returns `nullptr` and sets the error parameter to an
 | 
				
			||||||
// an error message (if `error_msg` is not nullptr). You must free the memory
 | 
					// an error message (if `error_msg` is not `nullptr`). You must free the memory
 | 
				
			||||||
// allocated for the error message.
 | 
					// allocated for the error message.
 | 
				
			||||||
MP_EXPORT void* image_embedder_create(struct ImageEmbedderOptions* options,
 | 
					MP_EXPORT void* image_embedder_create(struct ImageEmbedderOptions* options,
 | 
				
			||||||
                                      char** error_msg = nullptr);
 | 
					                                      char** error_msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Performs embedding extraction on the input `image`. Returns `0` on success.
 | 
					// Performs embedding extraction on the input `image`. Returns `0` on success.
 | 
				
			||||||
// If an error occurs, returns an error code and sets the error parameter to an
 | 
					// If an error occurs, returns an error code and sets the error parameter to an
 | 
				
			||||||
// an error message (if `error_msg` is not nullptr). You must free the memory
 | 
					// an error message (if `error_msg` is not `nullptr`). You must free the memory
 | 
				
			||||||
// allocated for the error message.
 | 
					// allocated for the error message.
 | 
				
			||||||
MP_EXPORT int image_embedder_embed_image(void* embedder, const MpImage* image,
 | 
					MP_EXPORT int image_embedder_embed_image(void* embedder, const MpImage* image,
 | 
				
			||||||
                                         ImageEmbedderResult* result,
 | 
					                                         ImageEmbedderResult* result,
 | 
				
			||||||
                                         char** error_msg = nullptr);
 | 
					                                         char** error_msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MP_EXPORT int image_embedder_embed_for_video(void* embedder,
 | 
					MP_EXPORT int image_embedder_embed_for_video(void* embedder,
 | 
				
			||||||
                                             const MpImage* image,
 | 
					                                             const MpImage* image,
 | 
				
			||||||
                                             int64_t timestamp_ms,
 | 
					                                             int64_t timestamp_ms,
 | 
				
			||||||
                                             ImageEmbedderResult* result,
 | 
					                                             ImageEmbedderResult* result,
 | 
				
			||||||
                                             char** error_msg = nullptr);
 | 
					                                             char** error_msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MP_EXPORT int image_embedder_embed_async(void* embedder, const MpImage* image,
 | 
					MP_EXPORT int image_embedder_embed_async(void* embedder, const MpImage* image,
 | 
				
			||||||
                                         int64_t timestamp_ms,
 | 
					                                         int64_t timestamp_ms,
 | 
				
			||||||
                                         char** error_msg = nullptr);
 | 
					                                         char** error_msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Frees the memory allocated inside a ImageEmbedderResult result.
 | 
					// Frees the memory allocated inside a ImageEmbedderResult result.
 | 
				
			||||||
// Does not free the result pointer itself.
 | 
					// Does not free the result pointer itself.
 | 
				
			||||||
| 
						 | 
					@ -137,9 +137,9 @@ MP_EXPORT void image_embedder_close_result(ImageEmbedderResult* result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Frees image embedder.
 | 
					// Frees image embedder.
 | 
				
			||||||
// If an error occurs, returns an error code and sets the error parameter to an
 | 
					// If an error occurs, returns an error code and sets the error parameter to an
 | 
				
			||||||
// an error message (if `error_msg` is not nullptr). You must free the memory
 | 
					// an error message (if `error_msg` is not `nullptr`). You must free the memory
 | 
				
			||||||
// allocated for the error message.
 | 
					// allocated for the error message.
 | 
				
			||||||
MP_EXPORT int image_embedder_close(void* embedder, char** error_msg = nullptr);
 | 
					MP_EXPORT int image_embedder_close(void* embedder, char** error_msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Utility function to compute cosine similarity [1] between two embeddings.
 | 
					// Utility function to compute cosine similarity [1] between two embeddings.
 | 
				
			||||||
// May return an InvalidArgumentError if e.g. the embeddings are of different
 | 
					// May return an InvalidArgumentError if e.g. the embeddings are of different
 | 
				
			||||||
| 
						 | 
					@ -148,7 +148,7 @@ MP_EXPORT int image_embedder_close(void* embedder, char** error_msg = nullptr);
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// [1]: https://en.wikipedia.org/wiki/Cosine_similarity
 | 
					// [1]: https://en.wikipedia.org/wiki/Cosine_similarity
 | 
				
			||||||
MP_EXPORT int cosine_similarity(const Embedding& u, const Embedding& v,
 | 
					MP_EXPORT int cosine_similarity(const Embedding& u, const Embedding& v,
 | 
				
			||||||
                                double* similarity, char** error_msg = nullptr);
 | 
					                                double* similarity, char** error_msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}  // extern C
 | 
					}  // extern C
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,8 @@ TEST(ImageEmbedderTest, ImageModeTest) {
 | 
				
			||||||
      {/* l2_normalize= */ true,
 | 
					      {/* l2_normalize= */ true,
 | 
				
			||||||
       /* quantize= */ false}};
 | 
					       /* quantize= */ false}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void* embedder = image_embedder_create(&options);
 | 
					  void* embedder = image_embedder_create(&options,
 | 
				
			||||||
 | 
					                                         /* error_msg */ nullptr);
 | 
				
			||||||
  EXPECT_NE(embedder, nullptr);
 | 
					  EXPECT_NE(embedder, nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const MpImage mp_image = {
 | 
					  const MpImage mp_image = {
 | 
				
			||||||
| 
						 | 
					@ -83,11 +84,12 @@ TEST(ImageEmbedderTest, ImageModeTest) {
 | 
				
			||||||
          .height = image->GetImageFrameSharedPtr()->Height()}};
 | 
					          .height = image->GetImageFrameSharedPtr()->Height()}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ImageEmbedderResult result;
 | 
					  ImageEmbedderResult result;
 | 
				
			||||||
  image_embedder_embed_image(embedder, &mp_image, &result);
 | 
					  image_embedder_embed_image(embedder, &mp_image, &result,
 | 
				
			||||||
 | 
					                             /* error_msg */ nullptr);
 | 
				
			||||||
  CheckMobileNetV3Result(result, false);
 | 
					  CheckMobileNetV3Result(result, false);
 | 
				
			||||||
  EXPECT_NEAR(result.embeddings[0].float_embedding[0], -0.0142344, kPrecision);
 | 
					  EXPECT_NEAR(result.embeddings[0].float_embedding[0], -0.0142344, kPrecision);
 | 
				
			||||||
  image_embedder_close_result(&result);
 | 
					  image_embedder_close_result(&result);
 | 
				
			||||||
  image_embedder_close(embedder);
 | 
					  image_embedder_close(embedder, /* error_msg */ nullptr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(ImageEmbedderTest, SucceedsWithCosineSimilarity) {
 | 
					TEST(ImageEmbedderTest, SucceedsWithCosineSimilarity) {
 | 
				
			||||||
| 
						 | 
					@ -106,7 +108,8 @@ TEST(ImageEmbedderTest, SucceedsWithCosineSimilarity) {
 | 
				
			||||||
      {/* l2_normalize= */ true,
 | 
					      {/* l2_normalize= */ true,
 | 
				
			||||||
       /* quantize= */ false}};
 | 
					       /* quantize= */ false}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void* embedder = image_embedder_create(&options);
 | 
					  void* embedder = image_embedder_create(&options,
 | 
				
			||||||
 | 
					                                         /* error_msg */ nullptr);
 | 
				
			||||||
  EXPECT_NE(embedder, nullptr);
 | 
					  EXPECT_NE(embedder, nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const MpImage mp_image = {
 | 
					  const MpImage mp_image = {
 | 
				
			||||||
| 
						 | 
					@ -129,9 +132,11 @@ TEST(ImageEmbedderTest, SucceedsWithCosineSimilarity) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Extract both embeddings.
 | 
					  // Extract both embeddings.
 | 
				
			||||||
  ImageEmbedderResult image_result;
 | 
					  ImageEmbedderResult image_result;
 | 
				
			||||||
  image_embedder_embed_image(embedder, &mp_image, &image_result);
 | 
					  image_embedder_embed_image(embedder, &mp_image, &image_result,
 | 
				
			||||||
 | 
					                             /* error_msg */ nullptr);
 | 
				
			||||||
  ImageEmbedderResult crop_result;
 | 
					  ImageEmbedderResult crop_result;
 | 
				
			||||||
  image_embedder_embed_image(embedder, &mp_crop, &crop_result);
 | 
					  image_embedder_embed_image(embedder, &mp_crop, &crop_result,
 | 
				
			||||||
 | 
					                             /* error_msg */ nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Check results.
 | 
					  // Check results.
 | 
				
			||||||
  CheckMobileNetV3Result(image_result, false);
 | 
					  CheckMobileNetV3Result(image_result, false);
 | 
				
			||||||
| 
						 | 
					@ -139,12 +144,12 @@ TEST(ImageEmbedderTest, SucceedsWithCosineSimilarity) {
 | 
				
			||||||
  // Check cosine similarity.
 | 
					  // Check cosine similarity.
 | 
				
			||||||
  double similarity;
 | 
					  double similarity;
 | 
				
			||||||
  cosine_similarity(image_result.embeddings[0], crop_result.embeddings[0],
 | 
					  cosine_similarity(image_result.embeddings[0], crop_result.embeddings[0],
 | 
				
			||||||
                    &similarity);
 | 
					                    &similarity, /* error_msg */ nullptr);
 | 
				
			||||||
  double expected_similarity = 0.925519;
 | 
					  double expected_similarity = 0.925519;
 | 
				
			||||||
  EXPECT_LE(abs(similarity - expected_similarity), kPrecision);
 | 
					  EXPECT_LE(abs(similarity - expected_similarity), kPrecision);
 | 
				
			||||||
  image_embedder_close_result(&image_result);
 | 
					  image_embedder_close_result(&image_result);
 | 
				
			||||||
  image_embedder_close_result(&crop_result);
 | 
					  image_embedder_close_result(&crop_result);
 | 
				
			||||||
  image_embedder_close(embedder);
 | 
					  image_embedder_close(embedder, /* error_msg */ nullptr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(ImageEmbedderTest, VideoModeTest) {
 | 
					TEST(ImageEmbedderTest, VideoModeTest) {
 | 
				
			||||||
| 
						 | 
					@ -161,7 +166,8 @@ TEST(ImageEmbedderTest, VideoModeTest) {
 | 
				
			||||||
      {/* l2_normalize= */ true,
 | 
					      {/* l2_normalize= */ true,
 | 
				
			||||||
       /* quantize= */ false}};
 | 
					       /* quantize= */ false}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void* embedder = image_embedder_create(&options);
 | 
					  void* embedder = image_embedder_create(&options,
 | 
				
			||||||
 | 
					                                         /* error_msg */ nullptr);
 | 
				
			||||||
  EXPECT_NE(embedder, nullptr);
 | 
					  EXPECT_NE(embedder, nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const auto& image_frame = image->GetImageFrameSharedPtr();
 | 
					  const auto& image_frame = image->GetImageFrameSharedPtr();
 | 
				
			||||||
| 
						 | 
					@ -174,13 +180,14 @@ TEST(ImageEmbedderTest, VideoModeTest) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < kIterations; ++i) {
 | 
					  for (int i = 0; i < kIterations; ++i) {
 | 
				
			||||||
    ImageEmbedderResult result;
 | 
					    ImageEmbedderResult result;
 | 
				
			||||||
    image_embedder_embed_for_video(embedder, &mp_image, i, &result);
 | 
					    image_embedder_embed_for_video(embedder, &mp_image, i, &result,
 | 
				
			||||||
 | 
					                                   /* error_msg */ nullptr);
 | 
				
			||||||
    CheckMobileNetV3Result(result, false);
 | 
					    CheckMobileNetV3Result(result, false);
 | 
				
			||||||
    EXPECT_NEAR(result.embeddings[0].float_embedding[0], -0.0142344,
 | 
					    EXPECT_NEAR(result.embeddings[0].float_embedding[0], -0.0142344,
 | 
				
			||||||
                kPrecision);
 | 
					                kPrecision);
 | 
				
			||||||
    image_embedder_close_result(&result);
 | 
					    image_embedder_close_result(&result);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  image_embedder_close(embedder);
 | 
					  image_embedder_close(embedder, /* error_msg */ nullptr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A structure to support LiveStreamModeTest below. This structure holds a
 | 
					// A structure to support LiveStreamModeTest below. This structure holds a
 | 
				
			||||||
| 
						 | 
					@ -222,7 +229,8 @@ TEST(ImageEmbedderTest, LiveStreamModeTest) {
 | 
				
			||||||
      /* result_callback= */ LiveStreamModeCallback::Fn,
 | 
					      /* result_callback= */ LiveStreamModeCallback::Fn,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void* embedder = image_embedder_create(&options);
 | 
					  void* embedder = image_embedder_create(&options,
 | 
				
			||||||
 | 
					                                         /* error_msg */ nullptr);
 | 
				
			||||||
  EXPECT_NE(embedder, nullptr);
 | 
					  EXPECT_NE(embedder, nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const auto& image_frame = image->GetImageFrameSharedPtr();
 | 
					  const auto& image_frame = image->GetImageFrameSharedPtr();
 | 
				
			||||||
| 
						 | 
					@ -234,9 +242,11 @@ TEST(ImageEmbedderTest, LiveStreamModeTest) {
 | 
				
			||||||
                      .height = image_frame->Height()}};
 | 
					                      .height = image_frame->Height()}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < kIterations; ++i) {
 | 
					  for (int i = 0; i < kIterations; ++i) {
 | 
				
			||||||
    EXPECT_GE(image_embedder_embed_async(embedder, &mp_image, i), 0);
 | 
					    EXPECT_GE(image_embedder_embed_async(embedder, &mp_image, i,
 | 
				
			||||||
 | 
					                                         /* error_msg */ nullptr),
 | 
				
			||||||
 | 
					              0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  image_embedder_close(embedder);
 | 
					  image_embedder_close(embedder, /* error_msg */ nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Due to the flow limiter, the total of outputs might be smaller than the
 | 
					  // Due to the flow limiter, the total of outputs might be smaller than the
 | 
				
			||||||
  // number of iterations.
 | 
					  // number of iterations.
 | 
				
			||||||
| 
						 | 
					@ -274,7 +284,8 @@ TEST(ImageEmbedderTest, FailedEmbeddingHandling) {
 | 
				
			||||||
       /* quantize= */ false},
 | 
					       /* quantize= */ false},
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void* embedder = image_embedder_create(&options);
 | 
					  void* embedder = image_embedder_create(&options,
 | 
				
			||||||
 | 
					                                         /* error_msg */ nullptr);
 | 
				
			||||||
  EXPECT_NE(embedder, nullptr);
 | 
					  EXPECT_NE(embedder, nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const MpImage mp_image = {.type = MpImage::GPU_BUFFER, .gpu_buffer = {}};
 | 
					  const MpImage mp_image = {.type = MpImage::GPU_BUFFER, .gpu_buffer = {}};
 | 
				
			||||||
| 
						 | 
					@ -283,7 +294,7 @@ TEST(ImageEmbedderTest, FailedEmbeddingHandling) {
 | 
				
			||||||
  image_embedder_embed_image(embedder, &mp_image, &result, &error_msg);
 | 
					  image_embedder_embed_image(embedder, &mp_image, &result, &error_msg);
 | 
				
			||||||
  EXPECT_THAT(error_msg, HasSubstr("GPU Buffer not supported yet."));
 | 
					  EXPECT_THAT(error_msg, HasSubstr("GPU Buffer not supported yet."));
 | 
				
			||||||
  free(error_msg);
 | 
					  free(error_msg);
 | 
				
			||||||
  image_embedder_close(embedder);
 | 
					  image_embedder_close(embedder, /* error_msg */ nullptr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user