Preprocess an image: resize to img_size × img_size, convert to float, normalize. Returns a float tensor in [C, H, W] layout (channel-first), range normalized with mean=0.5, std=0.5 → pixel values in [-1, 1].
| 3488 | // Returns a float tensor in [C, H, W] layout (channel-first), range normalized with |
| 3489 | // mean=0.5, std=0.5 → pixel values in [-1, 1]. |
| 3490 | static std::vector<float> sam3_preprocess_image(const sam3_image& image, int img_size) { |
| 3491 | const int C = 3; |
| 3492 | std::vector<float> result(C * img_size * img_size); |
| 3493 | |
| 3494 | // Resize to img_size × img_size via uint8 bilinear (matching torch pipeline) |
| 3495 | std::vector<uint8_t> resized; |
| 3496 | const uint8_t* pixels = image.data.data(); |
| 3497 | int w = image.width, h = image.height; |
| 3498 | |
| 3499 | if (w != img_size || h != img_size) { |
| 3500 | resized.resize(img_size * img_size * 3); |
| 3501 | sam3_resize_bilinear(pixels, w, h, resized.data(), img_size, img_size); |
| 3502 | pixels = resized.data(); |
| 3503 | w = img_size; |
| 3504 | h = img_size; |
| 3505 | } |
| 3506 | |
| 3507 | // Convert to float [C, H, W] with normalization: (pixel / 255.0 - 0.5) / 0.5 |
| 3508 | for (int c = 0; c < C; ++c) { |
| 3509 | for (int y = 0; y < img_size; ++y) { |
| 3510 | for (int x = 0; x < img_size; ++x) { |
| 3511 | float v = pixels[(y * img_size + x) * 3 + c] / 255.0f; |
| 3512 | result[c * img_size * img_size + y * img_size + x] = (v - 0.5f) / 0.5f; |
| 3513 | } |
| 3514 | } |
| 3515 | } |
| 3516 | |
| 3517 | return result; |
| 3518 | } |
| 3519 | |
| 3520 | // SAM2 preprocessing: resize + ImageNet normalization. |
| 3521 | // Returns [C, H, W] float, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]. |
no test coverage detected