Skip to content

recipe: opencv-contrib-python 5.0.0.93#110

Merged
ndonkoHenri merged 4 commits into
mainfrom
machine/opencv-contrib-python
Jul 17, 2026
Merged

recipe: opencv-contrib-python 5.0.0.93#110
ndonkoHenri merged 4 commits into
mainfrom
machine/opencv-contrib-python

Conversation

@ndonkoHenri

@ndonkoHenri ndonkoHenri commented Jul 17, 2026

Copy link
Copy Markdown

Adds opencv-contrib-python — OpenCV plus the opencv_contrib extra modules — for iOS and Android, as a twin of the already-landed opencv-python 5.0.0.93.

Requested by flet-dev/flet#4712

What it adds over opencv-python

The opencv_contrib modules: aruco (AR markers), face, tracking, ximgproc (edge-aware filters, superpixels), wechat_qrcode, img_hash, xfeatures2d (non-free off), dnn_superres, and more — the same importable cv2, just with these extra namespaces available.

Shape

The contrib sdist ships the identical opencv/ source tree (it only ADDS opencv_contrib/ and points the extra-modules path at it), so the recipe is a byte-for-byte twin of opencv-python: meta.yaml and mobile.patch mirror it, and the v5 patch (14 files) applies unchanged — verified by real-applying to the opencv-contrib-python-5.0.0.93 sdist. Same Flet 0.86 cv2 loader fix (find_spec('cv2.cv2')ExtensionFileLoader('cv2', origin) + extract_packages: [cv2]), same iOS MLAS gate.

One contrib-only iOS detail: the rgbd module's hand-written pyopencv_linemod.hpp uses a bare Ptr<> that clashes with Apple's <MacTypes.h> under using namespace cv, so the iOS lane sets -DBUILD_opencv_rgbd=OFF. Android has no MacTypes.h and keeps rgbd. Restoring it on iOS is a 4-line cv::Ptr follow-up.

Consumer notes (usage & recommendations)

opencv-contrib-python is OpenCV with the opencv_contrib extra modules folded into the same import cv2 — aruco, face, tracking, ximgproc, wechat_qrcode, img_hash and more, on top of everything the base OpenCV gives you.

Install

numpy comes in automatically as an OpenCV dependency:

# pyproject.toml
dependencies = [
    "flet",
    "opencv-contrib-python",
]

[tool.flet.android]
extract_packages = ["cv2"]

Minimal app

Run a real cv2 pipeline and show the result. There's no GUI on a phone, so display images through Flet controls rather than cv2.imshow:

import flet as ft
import cv2
import numpy as np


def main(page: ft.Page):
    img = np.zeros((200, 200, 3), dtype=np.uint8)
    cv2.circle(img, (100, 100), 70, (0, 140, 255), -1)
    edges = cv2.Canny(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY), 50, 150)
    ok, png = cv2.imencode(".png", edges)

    page.add(
        ft.Text(
            f"cv2 {cv2.__version__}: {int((edges > 0).sum())} edge pixels",
            weight=ft.FontWeight.BOLD,
        ),
        ft.Image(src=png.tobytes(), width=200, height=200),  # src takes bytes
    )


ft.run(main)

For live/streaming frames (video, real-time filters, per-frame detection), ft.RawImage is a better fit than ft.Image — it takes a NumPy array directly (no per-frame PNG encode) and streams frames over a data channel at interactive rates. One caveat: OpenCV is BGR, RawImage expects RGB, so convert first:

raw = ft.RawImage(width=320, height=240)
page.add(raw)
for frame in your_frames():                        # BGR uint8 arrays
    await raw.render(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))   # numpy straight in

Recommendations

  • Don't install both opencv-python/opencv-contrib-python (or their headless variants) — all provide the cv2 module and will collide. Pick one; use contrib only if you actually need the extra modules.
  • cv2.rgbd / cv2.linemod are Android-only in this build (the iOS gate above). Everything else — aruco, face, ximgproc, wechat_qrcode, img_hash, dnn_superres, … — is on both platforms.
  • No GUI callscv2.imshow/waitKey don't apply; render via ft.Image(src=<png bytes>) or ft.RawImage as shown.
  • Heavy processing off the UI thread — wrap long pipelines in page.run_thread(...).

The contrib twin of opencv-python 5.0.0.93 — same importable cv2, with the
opencv_contrib modules folded in (aruco, face, tracking, ximgproc,
wechat_qrcode, img_hash, xfeatures2d [non-free off], dnn_superres, ...).

The contrib sdist ships the identical opencv/ source tree (it only ADDS
opencv_contrib/ and points the extra-modules path at it), so the recipe is a
byte-for-byte twin: meta.yaml and mobile.patch mirror opencv-python's, and the
14-file patch real-applies clean to the contrib sdist. gen2.py's generated-
binding fix covers the contrib modules generically.

One contrib-only iOS wrinkle: rgbd's hand-written pyopencv_linemod.hpp uses
bare std::vector<Ptr<...>>, which hits the Apple <MacTypes.h> Ptr clash. Gated
with -DBUILD_opencv_rgbd=OFF on the iOS lane only (Android has no MacTypes.h and
keeps rgbd); restoring rgbd on iOS is a 4-line cv::Ptr follow-up.

Tests de-versioned per convention; test_contrib_module_works proves a
contrib-only module (img_hash perceptual hash) actually loads and runs on
device.
Cosmetic: '14 hunks' -> '14 files (38 hunks)'. Text-before-first-diff, no
build impact — the running CI is unaffected.
…MAKE_ARGS scalar [skip ci]

All 3 iOS legs failed with 'ValueError: No closing quotation' (android green).
Cause: the explanatory '#' comment I added lived INSIDE the iOS 'CMAKE_ARGS: >-'
folded scalar. YAML only treats '#' as a comment OUTSIDE scalar values, so the
prose (with apostrophes/backticks: MacTypes.h's, `char* Ptr;`) folded into the
CMAKE_ARGS string and forge's shlex.split choked on the unbalanced quotes.
Android has a separate scalar with no comment, hence green.

Moved the rationale to a real YAML comment above the scalar. Verified: the
rendered CMAKE_ARGS now shlex-splits cleanly for all three SDKs, no '#' in the
value, rgbd gate present on iOS only.
@ndonkoHenri
ndonkoHenri merged commit d49704a into main Jul 17, 2026
18 of 24 checks passed
@ndonkoHenri
ndonkoHenri deleted the machine/opencv-contrib-python branch July 17, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant