Skip to main content

ColorChecker camera calibration: detect, solve, apply. Log-polynomial tone curve + CCM via Ceres, OCIO 3D LUT export.

Project description

chromacal

License: MIT

ColorChecker camera calibration with correct color science. Detect the chart, solve for a color profile, apply it — three functions, one library.

What it does

chromacal fits a log-polynomial tone curve + 3x3 color correction matrix to ColorChecker patch measurements using non-linear optimization. Unlike OpenCV's basic ccm module, chromacal:

  • Jointly fits tone curve and CCM — no need to manually linearize first
  • Weights by measurement uncertainty — per-patch covariance (Mahalanobis distance) so noisy patches matter less
  • Down-weights bad patches — a robust per-patch reliability score (outlier fraction vs. the chi-square expectation) lets the solver gracefully discount patches with specular reflections or occlusions, without discarding them; an optional normality filter is also available for pristine captures
  • Perceptually weights — darker and more saturated colors get higher weight (where cameras struggle most)
  • Generates OCIO 3D LUTs — apply calibration via OpenColorIO for GPU-accelerated or batch processing

Example

Before and after calibration on a GoPro Hero10 frame (ColorChecker visible in scene):

Before After
Before calibration After calibration

Detected patches: 24 of 24

Fitted tone curve coefficients: [1.377, 3.479, 0.739, 0.072]

Fitted color correction matrix:

[[ 1.586  -0.638  -0.214]
 [-0.303   1.826  -0.294]
 [-0.014  -0.449   3.000]]

The off-diagonal entries show the GoPro sensor has significant blue-channel crosstalk that the CCM corrects. The tone curve coefficients (far from the identity [0, 1, 0, 0]) indicate the camera's built-in processing applies a heavy tonal response.

Patch comparison

Detected patch colors before and after calibration, compared to ground truth:

Patch comparison

The "after" row closely matches the reference — saturated colors are recovered and the grayscale ramp is neutral.

Re-detection identity check

Detecting the ColorChecker in the corrected image and solving again should produce a near-identity transform, confirming the calibration was applied correctly:

# Apply calibration
corrected = solver.infer(rgb_image)  # linear RGB float64

# detect() requires uint8, so we must quantize. Linear values in 8-bit
# have poor precision in the darks (causing patch detection failures),
# so we apply the sRGB transfer function before quantizing.
corrected_srgb = linear_to_srgb(corrected)
corrected_8bit = (corrected_srgb * 255).astype(np.uint8)

# Re-detect and re-solve on the corrected image
patches2 = chromacal.detect(cv2.cvtColor(corrected_8bit, cv2.COLOR_RGB2BGR))
solver2 = chromacal.Solver()
solver2.solve(patches2)

print(solver2.get_ccm())        # near identity
print(solver2.get_luma_params()) # absorbs sRGB transfer function

Re-detection CCM (24/24 patches):

[[ 1.006  -0.011   0.013]
 [-0.003   0.999   0.010]
 [ 0.005  -0.001   0.999]]

Re-detection tone curve: [0.013, 2.316, 0.116, 0.018]

The CCM is within 1.3% of the identity matrix — the color correction has already been applied. The tone curve departs from [0, 1, 0, 0] because it absorbs the sRGB transfer function applied during the uint8 quantization step.

Usage

Python

import chromacal
import cv2

image = cv2.imread("colorchecker.jpg")

# 1. Detect — find the chart and extract patch statistics
patches = chromacal.detect(image)
# (optional) cull patches up front on pristine captures:
#   patches = chromacal.filter_normal(patches)

# 2. Solve — fit the color profile (down-weights unreliable patches internally)
solver = chromacal.Solver()
solver.solve(patches)
solver.save("calibration.yml")

# 3. Apply — correct any image from this camera
lut = chromacal.create_lut(solver)
corrected = chromacal.apply_lut(image, lut)  # float32 RGB

C++

#include <chromacal/chromacal.h>

cv::Mat image = cv::imread("colorchecker.jpg");

// Detect
auto patches = chromacal::detect(image);
// (optional) patches = chromacal::filter_normal(patches);

// Solve — down-weights unreliable patches internally
chromacal::Solver solver;
solver.solve(patches);
solver.save("calibration.yml");

// Apply via OCIO 3D LUT
auto lut = chromacal::create_lut(solver);
cv::Mat corrected = chromacal::apply_lut(rgb_image, lut);

As a CMake dependency

include(FetchContent)
FetchContent_Declare(
    chromacal
    GIT_REPOSITORY https://github.com/kmatzen/chromacal.git
    GIT_TAG main
)
FetchContent_MakeAvailable(chromacal)

target_link_libraries(your_target PRIVATE chromacal::chromacal)

The algorithm

  1. Detection: OpenCV's MCC24 detector locates the ColorChecker. Per-patch pixel statistics (mean, covariance) are computed after rejecting saturated pixels.

  2. Reliability scoring: Each patch gets a robust reliability weight from the fraction of its pixels that are multivariate outliers (Mahalanobis distance beyond the chi-square expectation). This flags genuine contamination (specular highlights, occlusions) while tolerating mild gradients and 8-bit quantization, and — unlike a normality hypothesis test — it is stable with respect to the number of pixels in a patch. (An optional filter_normal step using Shapiro-Francia / Mardia / Henze-Zirkler tests is available for pristine, high-bit-depth captures.)

  3. Optimization: Ceres Solver minimizes the perceptually-weighted Mahalanobis distance between predicted and reference colors (CIE Lab D50). The model has 13 parameters: 4 log-polynomial tone curve coefficients + 9 CCM entries. Huber loss reduces outlier influence, and each patch's residual is additionally scaled by its reliability weight. Neutral patches (18-23) get an auxiliary white balance constraint.

  4. Application: The solver is baked into a 129^3 OCIO 3D LUT for fast per-pixel application. Input: gamma-encoded RGB. Output: linear RGB at reference exposure.

Requirements

  • C++17 compiler
  • OpenCV 4.x (with mcc contrib module)
  • Ceres Solver
  • OpenColorIO
  • Eigen3
  • pybind11 (optional, for Python bindings)

Building

# C++ only
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

# With Python bindings
cmake -B build -DCHROMACAL_BUILD_PYTHON=ON
cmake --build build

API

detect(image, exposure=1.0)

Detect a ColorChecker in a BGR image and return patch statistics. Each returned patch carries a reliability weight in (0, 1]; Solver.solve uses it to down-weight contaminated patches automatically, so no explicit filtering step is required.

filter_normal(patches) (optional)

Remove patches that fail multivariate normality tests (Shapiro-Francia, Mardia, Henze-Zirkler). This is an opt-in, aggressive cull intended for pristine, high-bit-depth captures with flat, evenly-lit patches. Because goodness-of-fit tests grow more sensitive with sample size, patches with many pixels — or any 8-bit/compressed/downscaled image (such as the web-sized docs/before.png example) — are frequently rejected as non-Gaussian even when their mean color is perfectly usable. Prefer the built-in reliability weighting (above) for most workflows.

Solver

Method Description
solve(patches) Fit the tone curve + CCM to patch data
infer(image) Apply calibration to an image (CV_64FC3 RGB)
get_ccm() Get the 3x3 color correction matrix
get_luma_params() Get the 4 log-polynomial coefficients
save(path) / load(path) Serialize to/from YAML

create_lut(solver, lut_size=129)

Bake the calibration into an OCIO 3D LUT for fast application.

apply_lut(image, lut)

Apply the 3D LUT to an image. Returns float32 RGB.

write_cube(solver, path, lut_size=33, title="chromacal")

Write the calibration as an Iridas/Resolve .cube 3D LUT file, independent of OpenColorIO. Drop the result into a DaVinci Resolve or Premiere/Lumetri LUT slot. Input domain is gamma-encoded RGB in [0, 1]; output is linear RGB at the reference exposure (written unclamped, so values may exceed [0, 1]).

Premiere Pro / After Effects plugin

A native video effect (plugin/) brings Resolve-style ColorChecker calibration to Premiere: an After Effects-style effect with an Analyze button that detects the chart and applies the tone curve + CCM live in the render pipeline. It can also Export a .cube for Lumetri's Input LUT (the effect's exact transform; Premiere applies an Input LUT directly, so it matches the effect — measured ~0.5% mean over the chart).

The SDK-free engine and a headless CLI build with no Adobe SDK at all:

cmake -B build -DCHROMACAL_BUILD_PPRO=ON
cmake --build build --target chromacal_solve
./build/plugin/chromacal_solve frame.png out.cube

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

chromacal-0.1.0.tar.gz (1.6 MB view details)

Uploaded Source

Built Distributions

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

chromacal-0.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (29.4 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

chromacal-0.1.0-cp314-cp314t-macosx_14_0_arm64.whl (80.7 MB view details)

Uploaded CPython 3.14tmacOS 14.0+ ARM64

chromacal-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (29.4 MB view details)

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

chromacal-0.1.0-cp314-cp314-macosx_14_0_arm64.whl (80.6 MB view details)

Uploaded CPython 3.14macOS 14.0+ ARM64

chromacal-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (29.4 MB view details)

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

chromacal-0.1.0-cp313-cp313-macosx_14_0_arm64.whl (80.6 MB view details)

Uploaded CPython 3.13macOS 14.0+ ARM64

chromacal-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (29.4 MB view details)

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

chromacal-0.1.0-cp312-cp312-macosx_14_0_arm64.whl (80.6 MB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

chromacal-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (29.4 MB view details)

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

chromacal-0.1.0-cp311-cp311-macosx_14_0_arm64.whl (80.6 MB view details)

Uploaded CPython 3.11macOS 14.0+ ARM64

chromacal-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (29.4 MB view details)

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

chromacal-0.1.0-cp310-cp310-macosx_14_0_arm64.whl (80.6 MB view details)

Uploaded CPython 3.10macOS 14.0+ ARM64

chromacal-0.1.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (29.4 MB view details)

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

chromacal-0.1.0-cp39-cp39-macosx_14_0_arm64.whl (80.6 MB view details)

Uploaded CPython 3.9macOS 14.0+ ARM64

File details

Details for the file chromacal-0.1.0.tar.gz.

File metadata

  • Download URL: chromacal-0.1.0.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for chromacal-0.1.0.tar.gz
Algorithm Hash digest
SHA256 09171d3a549b79f05240da17f45c193e882e189cbac1df133d598acce161402b
MD5 7e7565d942f223acbd1d3efb3de5d844
BLAKE2b-256 6bc5a99824be75dce29715bcce4f663bdae251fe397c1cccabe8573fbf7f5fe7

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0.tar.gz:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a5c734b00ea37f5b35ac405753436ffa1da88a3add056f7951b894b4c360dc34
MD5 54f8d6b219278fce8b1126f3329a0adf
BLAKE2b-256 ba1ada5dde033c88b99bd0f5180c6ec1c67b9ae8b3de8d58c8cd9ece1e93154b

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp314-cp314t-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp314-cp314t-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 0ac3606dc70096ac52c394ab4f7d9a41f3359ae4e57dde6e35bd6e8b01d855e8
MD5 fb87e7e5625f711dfa52933f9e653ee4
BLAKE2b-256 996fcd47d047fe840d58a49aa5f2b84b58b570fdf9c89ea9363b18ac06e6f686

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp314-cp314t-macosx_14_0_arm64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 25a9734a486ed6373587261fdbd19fcc8c418ce135c1011b41aae3296c2f82e6
MD5 405f6271540fc53b219b4992c1d97c91
BLAKE2b-256 80474ec56d903a2d3e1b4e42e096796f9c1e51b67d1a5681d45dd4bb6efae86e

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp314-cp314-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp314-cp314-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 13649fe2284e05a4583003d7b476ad487feffc808aa6bd02fc96823978fcd49a
MD5 aa702861206e0329dafcd7f222a45bf8
BLAKE2b-256 cb14b9718243077646235e5b37fbd5319acd62482eb79b5a3c51bfcf021ccaee

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp314-cp314-macosx_14_0_arm64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f4d443c076e80c75f0efb7a7f96f484576afd6bc43ea801268bec656665bb0c9
MD5 a257a35193fdeb0dfc6c0c2be8301376
BLAKE2b-256 77261aa404917e79dfebf77d2e441ea38a49de66e97ba4289c69b0d25d1b88c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp313-cp313-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 a47be86e2c9a4d2aa0a51ad8e21dc0b130891e424572eafb9cd11345ec828cf6
MD5 1b84530c36e9a9555e8b53cc281c2aa8
BLAKE2b-256 3a593b27d32e82408a5953963ca22bd3bb9366fb298163f5f26f3ad8bc23e899

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp313-cp313-macosx_14_0_arm64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6777b48829441a52bec6d74fc226c8cd5a6a391307597cdcc62dafeaf612d0dd
MD5 de54f13186aaaede7d4d5dc23ca5217d
BLAKE2b-256 1ac6e1044f32b490220889e5b2bb4950d87bb034aa9928406ad47b9cc98494f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 1651b679be099e183c540e56c837f673526c3d162f3922560ddc09c899842a69
MD5 fc5dcb26040db7f9c0e063a09d97d89f
BLAKE2b-256 107ed40b6a40fe8bada6c1737469b1c4a64beda3308015904425012f00fd64b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp312-cp312-macosx_14_0_arm64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 251fb459ad7e17e5295d8f25bac23c382965e14fe80ebccf678592b00d4e13b7
MD5 ba18a94eed0567f40e12650e7a3797c7
BLAKE2b-256 1e091760170999c5d898f0260dcde823a3d63216a8e81bfbf52e58982b741cf2

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp311-cp311-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp311-cp311-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 d1fee65b5ae23415bb91612558aa59737fc7b8f5bc1267675707a2e6430863cd
MD5 310ec25220c69ce5b54e5b9a727e21fd
BLAKE2b-256 d17b633c3d3453b79c3805f7e2302cee54ef067c94e4399c883e1672be9d8928

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp311-cp311-macosx_14_0_arm64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 aa5990563d92fed721095dee87efbdb278e1e2844322165e7aa4b9f47882eb7b
MD5 cbcf9d4c5985227477ec3ed199c87ad0
BLAKE2b-256 52831f8e311effc4e33401fee9e06da01e2965ad2eea14f2fda46625e5bdba5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp310-cp310-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp310-cp310-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 4223b1ef5b88e7216ee748e385dde20c02d42111b3da816a8c524ee6e650518d
MD5 c29faefe21c4ca738d64ec4a85357f7f
BLAKE2b-256 fbb02c5379a8bf413c4fbc841a5bab252ad671949a6d09ec87452fc112133138

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp310-cp310-macosx_14_0_arm64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b0e17839b0287324c9154b10102a8836ab2beb78bf2a22d2f5aab42c38d7bbef
MD5 ce1c2f65db9141db5f30032fb7b098c5
BLAKE2b-256 e2cd26449ede32ef73e37392be6c99d12d391a0b265bfc99b9dfeedc2d75165d

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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

File details

Details for the file chromacal-0.1.0-cp39-cp39-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for chromacal-0.1.0-cp39-cp39-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 12beba1a52b3f7b711449144ab33f5d7cae3a6aaf3a4d2fdbe2c5551fd38ee2d
MD5 caca2971c9590f4534c86f07b012d377
BLAKE2b-256 a20eec62cd51a600036d88dca434f8bfa4583ee76ccec8e0b4db1c69b3f7ba87

See more details on using hashes here.

Provenance

The following attestation bundles were made for chromacal-0.1.0-cp39-cp39-macosx_14_0_arm64.whl:

Publisher: wheels.yml on kmatzen/chromacal

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