Skip to main content

Image-to-body coordinate transformations with zero-copy NumPy/SciPy interop

Project description

image-to-body-math

Header-only C++23 library for pixel-to-body coordinate conversions, with zero-copy Python bindings (NumPy/SciPy).

Converts between image pixel coordinates, tangent-space, body-frame, and NED direction representations using camera parameters and attitude quaternions.

Features

  • Pixel-to-tangent conversion via FOV or pixel-to-tangent factor
  • Body-space pipeline — full pixel-to-NED and NED-to-pixel conversion through camera and attitude quaternions
  • Pixel stabilization — 6-stage pipeline compensating for body rotation changes
  • Camera installation — camera-to-body quaternion from installation tilt angle
  • Azimuth/elevation — conversions between NED vectors and azimuth/elevation angles or tangents
  • Boundary checking — pixel-in-frame and NED-in-frame tests with absolute or fractional margins
  • Elevation projection — project a pixel to a target elevation while preserving azimuth
  • NED angle in pixels — angular separation between two NED vectors expressed as pixel distance
  • Dead-zone clipping for center-pixel suppression
  • Type-safe angles via linalg3d (Radians vs Degrees at the type level)
  • Type-safe pixel math via strong-typesPixelTan, PixelToTan, NormalizedPixel, ClipThreshold prevent argument mix-ups at compile time
  • constexpr where possible — pure arithmetic operations evaluate at compile time
  • Python bindings via nanobind — zero-copy NumPy arrays, scipy.spatial.transform.Rotation interop, vectorized batch operations

Install

Python (from PyPI)

pip install image-to-body-math

Python (from source)

Requires a C++23 compiler (GCC 13+, Clang 17+).

pip install ".[test]"

C++ (CMake)

Requires CMake 3.25+ and a C++23 compiler. Dependencies (linalg3d, strong-types, gcem, fmt, doctest) are fetched automatically via FetchContent.

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir build

Python API

All vectors are NumPy arrays. Quaternions use [w, x, y, z] order and accept scipy.spatial.transform.Rotation directly.

Quick start

import numpy as np
from scipy.spatial.transform import Rotation
import image_to_body_math as p2b

identity = np.array([1.0, 0.0, 0.0, 0.0])
p2t = p2b.pixel_to_tan_from_fov(640, 480, np.radians(90))

# Pixel → NED direction (returns numpy array)
ned = p2b.pixel_to_ned(320, 240, 640, 480, p2t, identity, identity)
# array([1., 0., 0.])

# scipy Rotation accepted directly
ned = p2b.pixel_to_ned(320, 240, 640, 480, p2t,
    identity, Rotation.from_euler('z', 45, degrees=True))

# NED → pixel
row, col = p2b.ned_to_pixel(ned, 640, 480, p2t, identity, identity)

Batch operations (zero-copy)

# 10,000 pixels → NED directions in one call
rows = np.arange(10000, dtype=np.uint64) % 640
cols = np.arange(10000, dtype=np.uint64) % 480
neds = p2b.pixel_to_ned_batch(rows, cols, 640, 480, p2t, identity, identity)
# neds.shape == (10000, 3), dtype=float64, C-contiguous

# NED directions → pixels (input array reinterpreted as Vector3* — zero copy)
pixels = p2b.ned_to_pixel_batch(neds, 640, 480, p2t, identity, identity)
# pixels.shape == (10000, 2), dtype=uint64

# Full numpy interop — dot products, cross products, norms
down = np.array([0.0, 0.0, -1.0])
elevations = neds @ down  # (10000,) array

All functions

Function Description
pixel_tan_from_fov Pixel index → angular tangent via FOV
tan_to_pixel_by_fov Tangent → pixel index via FOV
pixel_tan_by_pixel_to_tan Pixel index → tangent via conversion factor
angle_tan_to_pixel Angular tangent → pixel index
pixel_tan_by_pixel_to_tan_clipped Pixel → tangent with dead-zone clipping
tan_to_pixel_by_pixel_to_tan Tangent → pixel (round or truncate)
pixel_to_tan_from_fov Compute conversion factor from FOV
cam_to_body_from_angle Camera-to-body quaternion from tilt angle
tangents_to_ned / ned_to_tangents Tangent pair ↔ NED direction
ned_to_azimuth_elevation / azimuth_elevation_to_ned NED ↔ azimuth/elevation
warp_image_to_body / warp_body_to_image Image tangents ↔ body-frame direction
pixel_to_ned / ned_to_pixel Full pixel ↔ NED pipeline
pixel_after_rotation Pixel position after body rotation change
is_pixel_inside_frame Boundary check with safety margin
is_ned_inside_frame NED visibility check
pixel_at_elevation Project pixel to target elevation
ned_angle_in_pixels Angular separation as pixel distance
pixel_to_ned_batch Batch pixel → NED
ned_to_pixel_batch Batch NED → pixel (zero-copy input)
pixel_after_rotation_batch Batch rotation compensation
warp_image_to_body_batch Batch image → body warp

C++ API

Headers

Header Purpose
types.hpp Strong type definitions, ImageSize, PixelIndex
math.hpp 1D pixel-to-tangent conversions (FOV and pixel-to-tan factor)
body_space.hpp 2D image-to-body-to-NED pipeline, rotation stabilization

Strong Types

All bare double parameters are replaced with tagged strong types:

Type Represents
PixelTan Tangent of a pixel's angular offset from image center
PixelToTan Conversion factor: tangent-per-pixel-offset
NormalizedPixel Normalized pixel coordinate in [-1, 1]
ClipThreshold Dead-zone threshold as fraction of half-width

Type algebra enforces correct conversions:

NormalizedPixel * PixelToTan -> PixelTan   // offset * factor = tangent
PixelTan / PixelToTan -> NormalizedPixel   // inverse

Mixing incompatible types is a compile error:

PixelTan pt{0.1};
PixelToTan ptt{0.0025};
auto ok = pt / ptt;       // NormalizedPixel
auto bad = pt + ptt;      // compile error -- no tag_sum_result defined

Usage

Pixel-to-tangent (1D)

#include <image-to-body-math/math.hpp>
using namespace p2b;

auto tan = pixel_tan_from_fov(PixelIndex{15}, ImageSize{20, 10}, Degrees{30}.to_radians());
auto pixel = tan_to_pixel_by_fov(PixelTan{0.1}, ImageSize{640, 480}, Degrees{60}.to_radians());

Pixel-to-NED (full pipeline)

#include <image-to-body-math/body_space.hpp>
using namespace p2b;

const ImageSize size{640, 480};
const auto ptt = pixel_to_tan_from_fov(size, Degrees{60}.to_radians());
const auto cam_q = cam_to_body_from_angle(Degrees{15}.to_radians());
const auto attitude = Quaternion::identity();

// Pixel to NED direction
auto ned = pixel_to_ned(PixelIndex{400}, PixelIndex{300}, size, ptt, cam_q, attitude);

// NED direction back to pixel
auto [row, col] = ned_to_pixel(ned, size, ptt, cam_q, attitude);

Pixel stabilization (rotation compensation)

// Where does pixel (400, 300) end up after the body rotates from q_old to q_new?
auto [new_row, new_col] = pixel_after_rotation(
    PixelIndex{400}, PixelIndex{300}, size, ptt, cam_q, q_old, q_new);

NED queries

// Is a NED direction visible in the current frame?
bool visible = is_ned_inside_frame(ned, size, ptt, cam_q, attitude, 0.1);

// Project pixel to a target elevation (e.g. horizon line at 0 degrees)
auto [r, c] = pixel_at_elevation(
    PixelIndex{400}, PixelIndex{300}, size, ptt, cam_q, attitude, Radians{0.0});

// Angular separation between two NED vectors in pixel units
double px_dist = ned_angle_in_pixels(ned1, ned2, ptt);

Examples

Image stabilization during flight

Compensate camera image for body rotation between consecutive frames. Each tracked pixel is re-projected through NED space to find its new position.

#include <image-to-body-math/body_space.hpp>
using namespace p2b;

// Camera setup (done once)
const ImageSize frame{1920, 1080};
const auto ptt = pixel_to_tan_from_fov(frame, Degrees{60}.to_radians());
const auto cam_q = cam_to_body_from_angle(Degrees{15}.to_radians()); // 15 deg down-tilt

// Per-frame: get attitude from IMU (scalar-first quaternion: w, x, y, z)
const Quaternion q_prev{0.998, 0.01, 0.02, 0.05};
const Quaternion q_curr{0.997, 0.01, 0.03, 0.06};

// Stabilize a feature point at pixel (960, 400)
auto [new_row, new_col] = pixel_after_rotation(
    PixelIndex{960}, PixelIndex{400}, frame, ptt, cam_q, q_prev, q_curr);
// new_row/new_col = where (960, 400) moved to in the new frame

Target tracking: pixel to world direction

Convert a detected object's bounding box center to a NED direction vector for geo-referencing or multi-sensor fusion.

// Detection at pixel (1200, 600) in a 1920x1080 frame
auto target_ned = pixel_to_ned(
    PixelIndex{1200}, PixelIndex{600}, frame, ptt, cam_q, attitude);

// Get azimuth and elevation of the target
auto [az, el] = ned_to_azimuth_elevation(target_ned);
// az = bearing from north, el = angle above horizon

// Later: project back to pixel when attitude changes
auto [px_row, px_col] = ned_to_pixel(target_ned, frame, ptt, cam_q, new_attitude);

Horizon line detection

Find where the horizon (0 deg elevation) falls in the image. Useful for sky/ground segmentation or flight display overlays.

// Where does the horizon appear at the image center column?
auto [h_row, h_col] = pixel_at_elevation(
    PixelIndex{960}, PixelIndex{540}, frame, ptt, cam_q, attitude, Radians{0.0});
// h_col = vertical pixel position of the horizon at image center

// Check if a tracked target is still visible with 10% margin
bool in_view = is_ned_inside_frame(target_ned, frame, ptt, cam_q, attitude, 0.1);

Measuring angular distance between detections

Compute the angular separation between two detections in pixel units, useful for clustering or duplicate rejection.

auto ned_a = pixel_to_ned(PixelIndex{500}, PixelIndex{300}, frame, ptt, cam_q, attitude);
auto ned_b = pixel_to_ned(PixelIndex{520}, PixelIndex{310}, frame, ptt, cam_q, attitude);

double px_distance = ned_angle_in_pixels(ned_a, ned_b, ptt);
// px_distance ~ 22 pixels (angular separation expressed as pixels)

Performance

pixel_to_ned full pipeline (pixel → tangent → body → NED), 640x480 image, identity quaternions. Benchmarked on x86_64 Linux.

Batch throughput (nanobind vs pure NumPy)

N pixels p2b batch pure NumPy speedup
100 16 us 180 us 11x
1,000 69 us 266 us 3.9x
10,000 607 us 1,637 us 2.7x
100,000 3,749 us 12,657 us 3.4x

Single-call latency

Function Latency
pixel_to_ned 2.3 us
ned_to_pixel 2.5 us
pixel_after_rotation 2.5 us
tangents_to_ned 624 ns
cam_to_body_from_angle 612 ns
pixel_to_tan_from_fov 152 ns
is_pixel_inside_frame 157 ns

Run benchmarks: python tests/python/bench.py

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

image_to_body_math-1.1.1.tar.gz (31.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

image_to_body_math-1.1.1-cp313-cp313-win_amd64.whl (79.7 kB view details)

Uploaded CPython 3.13Windows x86-64

image_to_body_math-1.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (84.0 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

image_to_body_math-1.1.1-cp313-cp313-macosx_11_0_arm64.whl (69.6 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

image_to_body_math-1.1.1-cp312-cp312-win_amd64.whl (79.7 kB view details)

Uploaded CPython 3.12Windows x86-64

image_to_body_math-1.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (84.0 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

image_to_body_math-1.1.1-cp312-cp312-macosx_11_0_arm64.whl (69.6 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

image_to_body_math-1.1.1-cp311-cp311-win_amd64.whl (80.5 kB view details)

Uploaded CPython 3.11Windows x86-64

image_to_body_math-1.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (85.2 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

image_to_body_math-1.1.1-cp311-cp311-macosx_11_0_arm64.whl (70.7 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

image_to_body_math-1.1.1-cp310-cp310-win_amd64.whl (80.6 kB view details)

Uploaded CPython 3.10Windows x86-64

image_to_body_math-1.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (85.5 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

image_to_body_math-1.1.1-cp310-cp310-macosx_11_0_arm64.whl (71.0 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file image_to_body_math-1.1.1.tar.gz.

File metadata

  • Download URL: image_to_body_math-1.1.1.tar.gz
  • Upload date:
  • Size: 31.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for image_to_body_math-1.1.1.tar.gz
Algorithm Hash digest
SHA256 238ad2fa0d6978d2d56338cab76e60cd8ded72a8d421bedf56c01611ff17e94f
MD5 3c7dcb83aaa4a02aec12f9a82d6dacd2
BLAKE2b-256 1e174a8e282970e13aeabd68f3758dc9dd252f2e20a20cf6af76a81bf1e7dae6

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1.tar.gz:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 fcbf47d26ff923e954c7cde4867ddce56dec353939c3401da29a947a66e2e6bf
MD5 c1678f42ab436693645b4d2fbc6eac9a
BLAKE2b-256 4a480cca5ac6e80d9b77d191e68538a70d343945449c31824ede68cf8efd0a0d

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp313-cp313-win_amd64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 be5bcf2a5b433c4cc243b5d2c204dbe6be0d9c381af9baa035402c38e61eb07c
MD5 c408194b267f2be875104d6ee78b85de
BLAKE2b-256 8ab40b1bbef2d754ec826a9abe597504f42bae103738364b239d22ba340e5c1e

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 87473a6ab87126d3d261049426432207a4ec2210977fc72db1658a8a459b0e79
MD5 5e2e9aef9153d2db52fd4e962be7f00a
BLAKE2b-256 876d676ab1563c0b7d7be43acd36f52ca7cf0dd258a48c3ef5bc41a8d81a69aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e6df88030c73cc6f1fb97bfbdf7a72a94a665f6bc189ef2093ab3a6fd9c582d4
MD5 0119a90259cc530cc8053f1b2aafe626
BLAKE2b-256 33c0769df0a3f8a69d4327acdefd7d613b37d74714843eba1666682b13eeed4f

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp312-cp312-win_amd64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 06276f60865dca829afec4cc5058bddb04b7044e4219100be50f8b8e5444f4b1
MD5 f816a566cbaa1cb5a35326fd57099c4f
BLAKE2b-256 e62ee64c44c291ae3ea7e18acf166869056d57150a23d073b48bc948339063f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 aeb6330fd8c7c2cc2a5b28fddecf3e695e3a645f16db5a7abea9c596dc5c5e72
MD5 a2403602c0c21a89faad366ea5801565
BLAKE2b-256 ade16b686f22cbb57edc119b84613e10ea9c8b400a461b3cbecd951c80e6af8c

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 f557a8418afc59b928c507ce97b1aeda6bf82ddd67e254b1805057e851fd15ca
MD5 a209b5ba93cded4a59092610bdedb8d3
BLAKE2b-256 7e18ad2a95c446b2752d683e1f1f86abb9231a8c4d13cb07c160adfaa79c333a

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp311-cp311-win_amd64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a091a38b71707b9efb9238146752f0bf1120c9c4fda9fca07ec70c77784e85e0
MD5 de5eaeca088b11411c0a1091103672ff
BLAKE2b-256 62655d7255d708b0ead699d91886cbaa5592c1038c4c3cd9a49ac45533ef696d

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2c5e94b6e7f8f157b35cf1ab858d308d85b5d4c4e10e1238432aec0423d18e18
MD5 402ef1ccfce7fb3f98ae8141ad39c76d
BLAKE2b-256 4ce179883a92f919b729c8515631b08575cb908fb124a114d627386a41ade8bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 1004a32c8bd37ec956c0c260cb23fe1cddcb606d28be287fa0f204af4edf126b
MD5 ef57690112e0f33e61017fdca3a78792
BLAKE2b-256 1b22a4fad86bc59c89be9d578f2b2b51fa7eeff0e8d2cb1e01ee2fef9fd36d48

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp310-cp310-win_amd64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 373fda45c5051753cf2e2c6d326f10dc487b9f4ba7b49f3c7dee360836edba1a
MD5 d6e1c81c3b91e946d6b83ffcfbff8225
BLAKE2b-256 cb30954ab90461505d28f0eafd00ea00295c64ce9209a63ebe4c94f37fbdf98a

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file image_to_body_math-1.1.1-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for image_to_body_math-1.1.1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 95885c8f5a0abbec1785ae32d2016858352917a75aee17843db01de837ba1dbd
MD5 96cc91091d8111125fc37edaccd379f3
BLAKE2b-256 ac9703c742937131c5cb0198f14319223d89dc4dec90eed167702a936466e6a4

See more details on using hashes here.

Provenance

The following attestation bundles were made for image_to_body_math-1.1.1-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: python.yml on PavelGuzenfeld/image-to-body-math

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page