|
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
4.58 kB
| # 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`/`W` are 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 use `blobFromImage`: 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]`, descending | |
| - `detection_classes:0` β `[1, 300]`, always `1.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`](https://github.com/gursimarsingh/opencv_zoo/tree/mcc_model/models/macbeth_chart_detector) | |
| β `frozen_inference_graph.pb`, sha1 `fae7dbef14c4ae1fca76f3662220fbd460ed5ed6` | |
| > **`num_detections` is not a detection count.** It reports the post-NMS slot count β 100 on the | |
| > example image, where exactly one chart is present. Threshold on `detection_scores` instead; | |
| > iterating `num_detections` yields 99 phantom boxes. | |
| ## Usage | |
| ### Python | |
| ```bash | |
| 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](./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`. | |
| ```bash | |
| 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](./LICENSE) β Apache License 2.0, taken from the upstream | |
| [opencv_zoo](https://github.com/gursimarsingh/opencv_zoo) repository that distributes the | |
| original frozen graph. | |