Download macbeth_chart_detector/README.md from opencv/opencv_contribution: direct link, hf CLI and curl.
- Browser
- Download file 4.58 kB
-
https://huggingface.co/opencv/opencv_contribution/resolve/main/macbeth_chart_detector/README.md
- Command line
-
hf download hf://opencv/opencv_contribution/macbeth_chart_detector/README.md
-
curl -L -o README.md https://huggingface.co/opencv/opencv_contribution/resolve/main/macbeth_chart_detector/README.md
Macbeth Chart Detector
Detects a Macbeth / ColorChecker Classic colour chart in a photograph and returns its bounding
box. This is the detection model used by OpenCV's mcc colour-correction code
(objdetect, checker_detector.cpp) to locate a chart before reading its patches.
The model is a Faster R-CNN with an Inception V2 backbone, trained as a single-class detector
with the TensorFlow Object Detection API. It was originally distributed as a frozen TensorFlow
graph (frozen_inference_graph.pb) and converted to ONNX for use with OpenCV's DNN module.
Model Details
- Architecture: Faster R-CNN, Inception V2 backbone, one class (the chart)
- Input:
image_tensor:0, NHWC[1, H, W, 3], raw uint8 RGB (0-255, no scaling and no mean subtraction).H/Ware dynamic β feed the image at its own resolution. The graph resizes internally (keep aspect ratio, min side 768, max side 1024), so do not pre-resize, and do not useblobFromImage: that produces NCHW. - Outputs (all four must be requested together):
detection_boxes:0β[1, 300, 4], normalized,[ymin, xmin, ymax, xmax](y first)detection_scores:0β[1, 300], descendingdetection_classes:0β[1, 300], always1.0(single class, so it carries no information)num_detections:0β[1]
- Framework: ONNX (converted from the TensorFlow frozen graph via tf2onnx, opset 18)
- Original weights: gursimarsingh/opencv_zoo @
mcc_modelβfrozen_inference_graph.pb, sha1fae7dbef14c4ae1fca76f3662220fbd460ed5ed6
num_detectionsis not a detection count. It reports the post-NMS slot count β 100 on the example image, where exactly one chart is present. Threshold ondetection_scoresinstead; iteratingnum_detectionsyields 99 phantom boxes.
Usage
Python
python demo.py --model macbeth_chart_detector_2026sep.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png --conf 0.3
On the provided example_outputs/input_image.png (900x463) it reports one detection:
macbeth_chart_detector 1 detections
0.582 x1=237 y1=79 x2=650 y2=368
demo.py requires OpenCV 5.1 or newer, for cv.dnn.ENGINE_OPENCV. On OpenCV 5.0 that constant
does not exist (it has ENGINE_CLASSIC / ENGINE_NEW); drop the second argument to
readNetFromONNX to use the default engine instead.
Conversion
Exported from the frozen TensorFlow graph with tf2onnx (opset 18) via
convert_to_onnx.py β input image_tensor:0, outputs
detection_boxes:0, detection_scores:0, detection_classes:0, num_detections:0.
Requires tensorflow, tf2onnx and onnx.
python convert_to_onnx.py --pb frozen_inference_graph.pb
The graph needs no special handling: its weights are plain float32 (no quantize_weights /
Dequantize nodes) and all four detection heads are present in the frozen graph.
Conversion accuracy
Verified against the original .pb under TensorFlow 2.15.1, feeding both the identical uint8
buffer:
| top score | box | |
|---|---|---|
TensorFlow .pb |
0.582205 | 0.171078 0.263475 0.794357 0.721806 |
| ONNX (onnxruntime) | 0.582205 | 0.171078 0.263475 0.794356 0.721806 |
The conversion is faithful to within one float32 ULP.
Known issue: OpenCV's DNN engine
The conversion is correct, but OpenCV's built-in DNN engine cannot currently run this model. On OpenCV 5.0.0 it aborts before producing output:
net_impl2.cpp: (-215:Assertion failed) buf.shape() == m.shape() in function 'forwardGraph'
The same failure affects the other converted Faster R-CNN / Mask R-CNN models in this
repository, so it is a limitation of the engine's handling of these graphs rather than
something specific to this model. On builds where the graph does run, the score comes out
around 0.02 instead of 0.582, because Resize with
coordinate_transformation_mode="tf_crop_and_resize" and a dynamic ROI β the ROI-pooling step
of the second stage β is not evaluated correctly, so every region proposal is classified from
the wrong features.
Until that is fixed in modules/dnn, treat the ONNX file as correct (onnxruntime and
TensorFlow agree exactly) and the OpenCV-engine results as unreliable.
License
See LICENSE β Apache License 2.0, taken from the upstream opencv_zoo repository that distributes the original frozen graph.