Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-morecvutils for openSUSE:Factory checked in at 2026-03-30 18:31:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-morecvutils (Old) and /work/SRC/openSUSE:Factory/.python-morecvutils.new.1999 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-morecvutils" Mon Mar 30 18:31:20 2026 rev:6 rq:1343496 version:1.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-morecvutils/python-morecvutils.changes 2025-05-09 18:52:47.500656623 +0200 +++ /work/SRC/openSUSE:Factory/.python-morecvutils.new.1999/python-morecvutils.changes 2026-03-30 18:34:29.863081267 +0200 @@ -1,0 +2,7 @@ +Sun Mar 29 18:02:08 UTC 2026 - Dirk Müller <[email protected]> + +- update to 1.1.0: + * modernized package + * typing + +------------------------------------------------------------------- Old: ---- morecvutils-1.0.2.tar.gz New: ---- morecvutils-1.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-morecvutils.spec ++++++ --- /var/tmp/diff_new_pack.jrF5WM/_old 2026-03-30 18:34:30.667114881 +0200 +++ /var/tmp/diff_new_pack.jrF5WM/_new 2026-03-30 18:34:30.671115048 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-morecvutils # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,15 +18,14 @@ %define pythons python3 Name: python-morecvutils -Version: 1.0.2 +Version: 1.1.0 Release: 0 Summary: Computer Vision utilities License: MIT URL: https://github.com/scivision/morecvutils Source: https://github.com/scivision/morecvutils/archive/v%{version}.tar.gz#/morecvutils-%{version}.tar.gz BuildRequires: %{python_module pip >= 10} -BuildRequires: %{python_module pip} -BuildRequires: %{python_module setuptools} +BuildRequires: %{python_module setuptools >= 61.0.0} BuildRequires: %{python_module wheel} BuildRequires: fdupes BuildRequires: python-rpm-macros @@ -56,7 +55,7 @@ %prep %setup -q -n morecvutils-%{version} # no main section: no interpreter -sed -i '1{/env python/d}' morecvutils/calcOptFlow.py +sed -i '1{/env python/d}' src/morecvutils/calcOptFlow.py src/morecvutils/tests/test_blob.py # remove executable bits from Demo files chmod -x Demo* OpticalFlow_Python_vs_Matlab.py @@ -72,10 +71,6 @@ %{?python_compileall} %python_expand %fdupes %{buildroot}%{$python_sitelib} -# Don't put demos in bindir -rm %{buildroot}%{_bindir}/Demo* -rm %{buildroot}%{_bindir}/OpticalFlow_Python_vs_Matlab.py - %check # test uses AVC/AAC file %pytest -k "not test_avi" ++++++ morecvutils-1.0.2.tar.gz -> morecvutils-1.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/.coveragerc new/morecvutils-1.1.0/.coveragerc --- old/morecvutils-1.0.2/.coveragerc 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/.coveragerc 1970-01-01 01:00:00.000000000 +0100 @@ -1,20 +0,0 @@ -[run] -cover_pylib = false -omit = - /home/travis/virtualenv/* - */site-packages/* - */bin/* - -[report] -exclude_lines = - pragma: no cover - def __repr__ - except RuntimeError - except NotImplementedError - except ImportError - except FileNotFoundError - except CalledProcessError - logging.warning - logging.error - logging.critical - if __name__ == .__main__.: \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/.flake8 new/morecvutils-1.1.0/.flake8 --- old/morecvutils-1.0.2/.flake8 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/.flake8 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ -[flake8] -max-line-length = 132 -exclude = .git,__pycache__,.eggs/,doc/,docs/,build/,dist/,archive/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/.gitattributes new/morecvutils-1.1.0/.gitattributes --- old/morecvutils-1.0.2/.gitattributes 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/.gitattributes 1970-01-01 01:00:00.000000000 +0100 @@ -1,20 +0,0 @@ -.gitattributes text eol=lf -.gitignore text eol=lf -Makefile text eol=lf -*.yml text eol=lf -LICENSE text eol=lf -*.ipynb text eol=lf -*.txt text eol=lf -*.py text eol=lf -*.sh text eol=lf -*.c text eol=lf -*.cpp text eol=lf -*.f text eol=lf -*.for text eol=lf -*.f90 text eol=lf -*.md text eol=lf -*.rst text eol=lf -*.csv text eol=lf -*.m text eol=lf -*.grc text eol=lf -*.pas text eol=lf diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/.github/FUNDING.yml new/morecvutils-1.1.0/.github/FUNDING.yml --- old/morecvutils-1.0.2/.github/FUNDING.yml 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/.github/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,4 +0,0 @@ -# These are supported funding model platforms - -github: [scivision] -ko_fi: scivision diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/.github/workflows/ci_python.yml new/morecvutils-1.1.0/.github/workflows/ci_python.yml --- old/morecvutils-1.0.2/.github/workflows/ci_python.yml 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/.github/workflows/ci_python.yml 2026-03-11 23:03:53.000000000 +0100 @@ -6,21 +6,19 @@ - "**.py" - ".github/workflows/ci_python.yml" pull_request: - paths: - - "**.py" - - ".github/workflows/ci_python.yml" jobs: linux: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/setup-python@v1 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 with: - python-version: '3.7' - - run: pip install .[tests,lint,opencv] - - run: flake8 - - run: mypy . + python-version: '3.10' + + - run: pip install .[tests,opencv] + + - run: mypy --install-types --non-interactive + - run: pytest - working-directory: tests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/.github/workflows/publish-python-package.yml new/morecvutils-1.1.0/.github/workflows/publish-python-package.yml --- old/morecvutils-1.0.2/.github/workflows/publish-python-package.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/morecvutils-1.1.0/.github/workflows/publish-python-package.yml 2026-03-11 23:03:53.000000000 +0100 @@ -0,0 +1,34 @@ +# https://docs.pypi.org/trusted-publishers/using-a-publisher/ + +name: publish + +on: + release: + types: [published] + +jobs: + release: + + runs-on: ubuntu-latest + + environment: release + + permissions: + id-token: write + + steps: + - uses: actions/checkout@v5 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Install builder + run: pip install build + + - name: Build package + run: python -m build + + - name: Publish package + uses: pypa/gh-action-pypi-publish@release/v1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/.pre-commit-config.yaml new/morecvutils-1.1.0/.pre-commit-config.yaml --- old/morecvutils-1.0.2/.pre-commit-config.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/morecvutils-1.1.0/.pre-commit-config.yaml 2026-03-11 23:03:53.000000000 +0100 @@ -0,0 +1,28 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: mixed-line-ending + args: [--fix=lf] + - id: check-yaml + - id: check-toml + - id: check-json + - id: check-case-conflict + - id: check-illegal-windows-names + - id: destroyed-symlinks + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.15.5 + hooks: + # Run the linter. + - id: ruff-check + args: [ --fix ] + # Run the formatter. + - id: ruff-format + + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.19.1 + hooks: + - id: mypy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/DemoConnectedComponentsBlob.py new/morecvutils-1.1.0/DemoConnectedComponentsBlob.py --- old/morecvutils-1.0.2/DemoConnectedComponentsBlob.py 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/DemoConnectedComponentsBlob.py 2026-03-11 23:03:53.000000000 +0100 @@ -6,7 +6,7 @@ from morecvutils.connectedComponents import setupblob, doblob -def gen_patterns(x: int, y: int, dtype=np.uint8, add_noise: float = 0.0) -> np.ndarray: +def gen_patterns(x: int, y: int, dtype=np.uint8, add_noise: float = 0.0): if dtype == np.uint8: V = 255 @@ -34,7 +34,7 @@ im[190:220:1, 120:200:1] = V if add_noise > 0: - im = random_noise(im, 's&p', amount=add_noise).astype('uint8') * V + im = random_noise(im, "s&p", amount=add_noise).astype("uint8") * V return im @@ -45,13 +45,13 @@ x = y = 256 img_area = x * y - print(f'area of the {x} x {y} image is {img_area} pixels') + print(f"area of the {x} x {y} image is {img_area} pixels") # set some arbitrary parameters max_blob = img_area // 4 min_blob = img_area // 1000 - print(f'Minimum and maximum blob areas: {min_blob}, {max_blob}') + print(f"Minimum and maximum blob areas: {min_blob}, {max_blob}") im1 = gen_patterns(x, y, np.uint8, 0.0) @@ -59,11 +59,11 @@ labeled_img, label_sizes = doblob(im1, blob) - cv2.imshow('Labeled Image', labeled_img) - print('press any key to exit') + cv2.imshow("Labeled Image", labeled_img) + print("press any key to exit") cv2.waitKey(0) cv2.destroyAllWindows() -if __name__ == '__main__': +if __name__ == "__main__": main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/DemoMedianFilter.py new/morecvutils-1.1.0/DemoMedianFilter.py --- old/morecvutils-1.0.2/DemoMedianFilter.py 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/DemoMedianFilter.py 2026-03-11 23:03:53.000000000 +0100 @@ -3,12 +3,9 @@ import numpy as np from skimage.util import random_noise from matplotlib.pyplot import figure, show -from typing import Tuple -def gen_patterns( - x: int, y: int, dtype=np.uint8, noise: float = 0.0 -) -> Tuple[np.ndarray, np.ndarray]: +def gen_patterns(x: int, y: int, dtype=np.uint8, noise: float = 0.0) -> tuple: if dtype == np.uint8: V = 255 @@ -34,38 +31,38 @@ im[21:24:2, 21:24:2] = V if noise > 0: - im = random_noise(im, 's&p', amount=noise).astype('uint8') * V + im = random_noise(im, "s&p", amount=noise).astype("uint8") * V - im2 = np.zeros((y, x), dtype='uint8') + im2 = np.zeros((y, x), dtype="uint8") im2[4:7, 4:7] = V im2[4, 8] = V return im, im2 -def plot_panel(fg, im: np.ndarray): +def plot_panel(fg, im): ax = fg.add_subplot(1, 4, 1) - ax.imshow(im, cmap='gray_r', interpolation='none', origin='bottom') - ax.set_title('original') + ax.imshow(im, cmap="gray_r", interpolation="none", origin="bottom") + ax.set_title("original") imfilt = cv2.medianBlur(im, 3) ax = fg.add_subplot(1, 4, 2) - ax.imshow(imfilt, cmap='gray_r', interpolation='none', origin='bottom') - ax.set_title('median filtered') + ax.imshow(imfilt, cmap="gray_r", interpolation="none", origin="bottom") + ax.set_title("median filtered") openrad = 3 kern = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (openrad, openrad)) ax = fg.add_subplot(1, 4, 3) - ax.imshow(cv2.erode(im, kern), cmap='gray_r', interpolation='none', origin='bottom') - ax.set_title('erosion') + ax.imshow(cv2.erode(im, kern), cmap="gray_r", interpolation="none", origin="bottom") + ax.set_title("erosion") ax = fg.add_subplot(1, 4, 4) ax.imshow( - cv2.erode(imfilt, kern), cmap='gray_r', interpolation='none', origin='bottom' + cv2.erode(imfilt, kern), cmap="gray_r", interpolation="none", origin="bottom" ) - ax.set_title('erosion median filtered') + ax.set_title("erosion median filtered") # for a in ax: # a.set_xlim((0, im.shape[1])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/DemoOptFlow.m new/morecvutils-1.1.0/DemoOptFlow.m --- old/morecvutils-1.0.2/DemoOptFlow.m 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/DemoOptFlow.m 2026-03-11 23:03:53.000000000 +0100 @@ -1,7 +1,5 @@ -function flows = test_optflow(I) -if verLessThan('matlab','R2015a') - error('this Python Matlab Engine demo requires Matlab >= R2015a') -end +function flows = DemoOptFlow(I) + if nargin==0 I = genuint8(); end @@ -13,7 +11,7 @@ flows = nan(size(I),'single'); for i = 1:size(I,1) - + F = estimateFlow(of, squeeze(I(i,:,:))); flows(i,:,:) = F.Magnitude; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/LICENSE.txt new/morecvutils-1.1.0/LICENSE.txt --- old/morecvutils-1.0.2/LICENSE.txt 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/LICENSE.txt 2026-03-11 23:03:53.000000000 +0100 @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2017 Michael Hirsch, Ph.D. +Copyright (c) 2014-2017 SciVision Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/MANIFEST.in new/morecvutils-1.1.0/MANIFEST.in --- old/morecvutils-1.0.2/MANIFEST.in 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/MANIFEST.in 2026-03-11 23:03:53.000000000 +0100 @@ -1,2 +1,2 @@ include LICENSE.txt -recursive-include tests *.py *.png \ No newline at end of file +recursive-include tests *.py *.png diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/OpticalFlow_Python_vs_Matlab.py new/morecvutils-1.1.0/OpticalFlow_Python_vs_Matlab.py --- old/morecvutils-1.0.2/OpticalFlow_Python_vs_Matlab.py 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/OpticalFlow_Python_vs_Matlab.py 2026-03-11 23:03:53.000000000 +0100 @@ -1,7 +1,6 @@ #!/usr/bin/env python from pathlib import Path import imageio -from typing import Sequence import numpy as np from matplotlib.pyplot import figure, draw, pause, show @@ -9,39 +8,39 @@ from morecvutils.calcOptFlow import setupuv, optflowHornSchunk -def plotflow(mag, matmag): +def plotflow(im, mag, matmag): fg = figure(figsize=(12, 5)) ax = fg.subplots(1, 2) - for i in range(I.shape[0] - 1): + for i in range(im.shape[0] - 1): if i == 0: hi = ax[0].imshow(mag[0, ...]) - ax[0].set_title('Python optical flow mag') + ax[0].set_title("Python optical flow mag") fg.colorbar(hi, ax=ax[0]) if matmag is not None: hm = ax[1].imshow(matmag[0, ...]) - ax[1].set_title('Matlab Optical flow mag') + ax[1].set_title("Matlab Optical flow mag") fg.colorbar(hm, ax=ax[1]) - hs = fg.suptitle('frame #') + hs = fg.suptitle("frame #") else: hi.set_data(mag[i, ...]) if matmag is not None: hm.set_data(matmag[i, ...]) - hs.set_text('frame # {}'.format(i)) + hs.set_text("frame # {}".format(i)) draw() pause(0.001) -def matlab_flow(I): +def matlab_flow(im): import matlab.engine eng = matlab.engine.start_matlab("-nojvm") - matmag = eng.test_optflow(matlab.uint8(I.tolist())) + matmag = eng.test_optflow(matlab.uint8(im.tolist())) matmag = np.asarray(matmag) eng.quit() @@ -49,19 +48,19 @@ return matmag -def py_flow(I, N, r, c): +def py_flow(im, N, r, c): uv = setupuv((r, c)) mag = np.empty((N, r, c)) # priming read for i in range(N): - flow = optflowHornSchunk(I[i + 1, ...], I[i, ...], uv, smoothing=0.001) + flow = optflowHornSchunk(im[i + 1, ...], im[i, ...], uv, smoothing=0.001) mag[i, ...] = np.hypot(flow[..., 0], flow[..., 1]) return mag -def setup(flist: Sequence[Path]): +def setup(flist: list[Path]): N = len(flist) - 1 r, c = imageio.imread(str(flist[0])).shape im = np.empty((N + 1, r, c), dtype=np.uint8) @@ -72,19 +71,18 @@ return im, N, r, c -if __name__ == '__main__': +if __name__ == "__main__": + flist = sorted(Path("tests/data").glob("*.png")) - flist = sorted(Path('tests/data').glob('*.png')) - - I, N, r, c = setup(flist) + im, N, r, c = setup(flist) # %% python - mag = py_flow(I, N, r, c) + mag = py_flow(im, N, r, c) # %% Matlab try: - matmag = matlab_flow(I) + matmag = matlab_flow(im) except ImportError: matmag = None # %% - plotflow(mag, matmag) + plotflow(im, mag, matmag) show() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/archive/.travis.yml new/morecvutils-1.1.0/archive/.travis.yml --- old/morecvutils-1.0.2/archive/.travis.yml 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/archive/.travis.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,25 +0,0 @@ -language: python -group: travis_latest - -git: - depth: 25 - quiet: true - -python: -- 3.6 - -os: -- linux - -install: -- pip install -e .[tests,cov,opencv] - -script: -- flake8 -- mypy . -- pytest -rsv - - -after_success: -- pytest --cov -- coveralls diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/morecvutils/calcOptFlow.py new/morecvutils-1.1.0/morecvutils/calcOptFlow.py --- old/morecvutils-1.0.2/morecvutils/calcOptFlow.py 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/morecvutils/calcOptFlow.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,65 +0,0 @@ -#!/usr/bin/env python -""" -Michael Hirsch -Example calculations of optical flow, starting with Horn Schunk Optical Flow using OpenCV -""" -import numpy as np - -try: - import cv2 -except ImportError: # NOTE: openCV 3 has legacy code buried in opencv-extra - cv2 = None -from numpy import asarray, dstack - -# -from pyoptflow import HornSchunck - - -def optflowHornSchunk( - new: np.ndarray, ref: np.ndarray, uv, smoothing=0.01 -) -> np.ndarray: - if cv2 is not None: - """ - http://docs.opencv.org/modules/legacy/doc/motion_analysis.html - Note that smoothness parameter for cv.CalcOpticalFlowHS needs to be SMALLER than matlab - to get similar result. Useless when smoothness was 1 in OpenCV, but it's 1 in Matlab! - """ - cvref = cv2.fromarray(ref) - cvnew = cv2.fromarray(new) - # result is placed in u,v - # matlab vision.OpticalFlow Horn-Shunck has default maxiter=10, terminate=eps, smoothness=1 - cv2.CalcOpticalFlowHS( - cvref, - cvnew, - False, - uv[0], - uv[1], - smoothing, - (cv2.CV_TERMCRIT_ITER | cv2.CV_TERMCRIT_EPS, 8, 0.1), - ) - - # reshape to numpy float32, xpix x ypix x 2 - flow = dstack((asarray(uv[0]), asarray(uv[1]))) - else: # use Python method - u, v = HornSchunck(ref, new) - flow = dstack((u, v)) - - return flow - - -def setupuv(rc): - """ - Horn Schunck legacy OpenCV function requires we use these old-fashioned cv matrices, not numpy array - """ - if cv2 is not None: - (r, c) = rc - u = cv2.CreateMat(r, c, cv2.CV_32FC1) - v = cv2.CreateMat(r, c, cv2.CV_32FC1) - return (u, v) - else: - return [None] * 2 - - -def calcofhs(new, ref, smoothing): - uv = setupuv(new.shape) - return optflowHornSchunk(new, ref, uv, smoothing) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/morecvutils/connectedComponents.py new/morecvutils-1.1.0/morecvutils/connectedComponents.py --- old/morecvutils-1.0.2/morecvutils/connectedComponents.py 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/morecvutils/connectedComponents.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,50 +0,0 @@ -import cv2 -import numpy as np -from typing import Tuple - - -def doblob( - img: np.ndarray, blobdet, anno: bool = True -) -> Tuple[np.ndarray, np.ndarray]: - """ - img: can be RGB (MxNx3) or gray (MxN) - - http://docs.opencv.org/master/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html - http://docs.opencv.org/trunk/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html - """ - keypoints = blobdet.detect(img) - kpsize = np.asarray([k.size for k in keypoints]) - final = img.copy() # is the .copy necessary? - - final = cv2.drawKeypoints( - img, keypoints, outImage=final, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS - ) - # %% plot count of blobs - if anno: - cv2.putText( - final, - text=str(len(keypoints)), - org=(int(img.shape[1] * 0.9), 25), - fontFace=cv2.FONT_HERSHEY_PLAIN, - fontScale=2, - color=(0, 255, 0), - thickness=2, - ) - - return final, kpsize - - -def setupblob(minarea: int, maxarea: int, mindist: int): - - blobparam = cv2.SimpleBlobDetector_Params() - blobparam.filterByArea = True - blobparam.filterByColor = False - blobparam.filterByCircularity = False - blobparam.filterByInertia = False - blobparam.filterByConvexity = False - - blobparam.minDistBetweenBlobs = mindist - blobparam.minArea = minarea - blobparam.maxArea = maxarea - # blobparam.minThreshold = 40 #we have already made a binary image - return cv2.SimpleBlobDetector_create(blobparam) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/morecvutils/cv2draw.py new/morecvutils-1.1.0/morecvutils/cv2draw.py --- old/morecvutils-1.0.2/morecvutils/cv2draw.py 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/morecvutils/cv2draw.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,89 +0,0 @@ -from __future__ import division, absolute_import -import cv2 -from numpy import ( - dstack, - degrees, - pi, - array, - ones_like, - arctan2, - hypot, - mgrid, - vstack, - uint8, - int32, - iinfo, -) - - -def draw_flow(img, flow, step=16, dtype=uint8): - """ - draws flow vectors on image - this came from opencv/examples directory - another way: http://docs.opencv.org/trunk/doc/py_tutorials/py_gui/py_drawing_functions/py_drawing_functions.html - """ - maxval = iinfo(img.dtype).max - - # scaleFact = 1. #arbitary factor to make flow visible - canno = (0, maxval, 0) # green color - h, w = img.shape[:2] - y, x = mgrid[step // 2: h: step, step // 2: w: step].reshape(2, -1) - fx, fy = flow[y, x].T - # create line endpoints - lines = vstack([x, y, (x + fx), (y + fy)]).T.reshape(-1, 2, 2) - lines = int32(lines + 0.5) - # create image - if img.ndim == 2: # assume gray - vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) - else: # already RGB - vis = img - # draw line - cv2.polylines(vis, lines, isClosed=False, color=canno, thickness=1, lineType=8) - # draw filled green circles - for (x1, y1), (_x2, _y2) in lines: - cv2.circle(vis, center=(x1, y1), radius=1, color=canno, thickness=-1) - return vis - - -def draw_hsv(mag, ang, dtype=uint8, fn=None): - """ - mag must be uint8, uint16, uint32 and 2-D - ang is in radians (float) - """ - assert mag.shape == ang.shape - assert mag.ndim == 2 - maxval = iinfo(dtype).max - - hsv = dstack( - ( - (degrees(ang) / 2).astype(dtype), # /2 to keep less than 255 - ones_like(mag) * maxval, # maxval must be after in 1-D case - cv2.normalize(mag, alpha=0, beta=maxval, norm_type=cv2.NORM_MINMAX), - ) - ) - rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB) - - if fn is not None: - print('writing ' + fn) - cv2.imwrite(fn, rgb) - - return rgb # , hsv - - -def flow2magang(flow, dtype=uint8): - """ - flow dimensions y,x,2 3-D. flow[...,0] is magnitude, flow[...,1] is angle - """ - fx, fy = flow[..., 0], flow[..., 1] - return hypot(fx, fy).astype(dtype), arctan2(fy, fx) + pi - - -# %% selftest -if __name__ == '__main__': - flow = array([[[55, pi / 4], [128, 3 * pi / 2]], [[123, pi / 2], [48, pi]]]) - - mag, ang = flow2magang(flow, uint8) - - rgb = draw_hsv(mag, ang) - - assert rgb[1, 0, 2] == 239 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/morecvutils/getaviprop.py new/morecvutils-1.1.0/morecvutils/getaviprop.py --- old/morecvutils-1.0.2/morecvutils/getaviprop.py 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/morecvutils/getaviprop.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,60 +0,0 @@ -#!/usr/bin/env python -""" -gets basic info about AVI file using OpenCV - -input: filename or cv2.Capture -""" -from pathlib import Path -from struct import pack -from typing import Dict, Any -import cv2 - - -def getaviprop(fn: Path) -> Dict[str, Any]: - if isinstance(fn, (str, Path)): # assuming filename - fn = Path(fn).expanduser() - if not fn.is_file(): - raise FileNotFoundError(fn) - v = cv2.VideoCapture(str(fn)) - if v is None: - raise OSError(f'could not read {fn}') - else: # assuming cv2.VideoCapture object - v = fn - - if not v.isOpened(): - raise OSError(f'cannot read {fn} probable codec issue') - - vidparam = { - 'nframe': int(v.get(cv2.CAP_PROP_FRAME_COUNT)), - 'xy_pixel': ( - int(v.get(cv2.CAP_PROP_FRAME_WIDTH)), - int(v.get(cv2.CAP_PROP_FRAME_HEIGHT)), - ), - 'fps': v.get(cv2.CAP_PROP_FPS), - 'codec': fourccint2ascii(int(v.get(cv2.CAP_PROP_FOURCC))), - } - - if isinstance(fn, Path): - v.release() - - return vidparam - - -def fourccint2ascii(fourcc_int: int) -> str: - """ - convert fourcc 32-bit integer code to ASCII - """ - assert isinstance(fourcc_int, int) - - return pack('<I', fourcc_int).decode('ascii') - - -if __name__ == '__main__': - from argparse import ArgumentParser - - p = ArgumentParser(description='get parameters of AVI file') - p.add_argument('avifn', help='avi filename') - p = p.parse_args() - - vidparam = getaviprop(p.avifn) - print(vidparam) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/mypy.ini new/morecvutils-1.1.0/mypy.ini --- old/morecvutils-1.0.2/mypy.ini 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/mypy.ini 1970-01-01 01:00:00.000000000 +0100 @@ -1,4 +0,0 @@ -[mypy] -ignore_missing_imports = True -strict_optional = False -allow_redefinition = True \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/pyproject.toml new/morecvutils-1.1.0/pyproject.toml --- old/morecvutils-1.0.2/pyproject.toml 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/pyproject.toml 2026-03-11 23:03:53.000000000 +0100 @@ -1,2 +1,37 @@ [build-system] -requires = ["setuptools", "wheel"] \ No newline at end of file +requires = ["setuptools>=61.0.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "morecvutils" +description = "Computer Vision utilities, OpenCV plot helpers for Optical Flow and Blob Analysis, AVI codec helpers" +requires-python = ">=3.10" +keywords = ["computer vision", "opencv"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Intended Audience :: Science/Research", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Topic :: Scientific/Engineering :: Visualization" +] +dynamic = ["readme", "version"] +dependencies = [ + "numpy", + "imageio" +] + +[tool.setuptools.dynamic] +readme = {file = ["README.md"], content-type = "text/markdown"} +version = {attr = "morecvutils.__version__"} + +[project.optional-dependencies] +tests = ["pytest", "mypy"] +plot = ["matplotlib"] +opencv = ["opencv-python"] + +[tool.mypy] +files = ["."] +install_types = true +exclude = ["^build([/\\\\]|$)"] +ignore_missing_imports = true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/pytest.ini new/morecvutils-1.1.0/pytest.ini --- old/morecvutils-1.0.2/pytest.ini 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/pytest.ini 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -[pytest] -addopts = -ra -v diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/setup.cfg new/morecvutils-1.1.0/setup.cfg --- old/morecvutils-1.0.2/setup.cfg 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/setup.cfg 1970-01-01 01:00:00.000000000 +0100 @@ -1,49 +0,0 @@ -[metadata] -name = morecvutils -version = 1.0.2 -author = Michael Hirsch, Ph.D. -author_email = [email protected] -description = Computer Vision utilities, OpenCV plot helpers for Optical Flow and Blob Analysis, AVI codec helpers -url = https://github.com/scivision/morecvutils -keywords = - computer vision - opencv -classifiers = - Development Status :: 5 - Production/Stable - Environment :: Console - Intended Audience :: Science/Research - Operating System :: OS Independent - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Topic :: Scientific/Engineering :: Visualization -license_files = - LICENSE.txt -long_description = file: README.md -long_description_content_type = text/markdown - -[options] -python_requires = >= 3.6 -packages = find: -include_package_data = True -zip_safe = False -scripts = - DemoOptFlow.m - DemoConnectedComponentsBlob.py - DemoMedianFilter.py - OpticalFlow_Python_vs_Matlab.py -install_requires = - numpy - imageio - -[options.extras_require] -tests = - pytest -lint = - flake8 - mypy -plot = - matplotlib - seaborn -opencv = - opencv-python diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/setup.py new/morecvutils-1.1.0/setup.py --- old/morecvutils-1.0.2/setup.py 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/setup.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,4 +0,0 @@ -#!/usr/bin/env python -from setuptools import setup - -setup() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/src/morecvutils/__init__.py new/morecvutils-1.1.0/src/morecvutils/__init__.py --- old/morecvutils-1.0.2/src/morecvutils/__init__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/morecvutils-1.1.0/src/morecvutils/__init__.py 2026-03-11 23:03:53.000000000 +0100 @@ -0,0 +1 @@ +__version__ = "1.1.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/src/morecvutils/calcOptFlow.py new/morecvutils-1.1.0/src/morecvutils/calcOptFlow.py --- old/morecvutils-1.0.2/src/morecvutils/calcOptFlow.py 1970-01-01 01:00:00.000000000 +0100 +++ new/morecvutils-1.1.0/src/morecvutils/calcOptFlow.py 2026-03-11 23:03:53.000000000 +0100 @@ -0,0 +1,59 @@ +#!/usr/bin/env python +""" +Michael Hirsch +Example calculations of optical flow, starting with Horn Schunk Optical Flow using OpenCV +""" + +import numpy as np + +from pyoptflow import HornSchunck + + +def optflowHornSchunk(new, ref, uv, smoothing=0.01): + try: + import cv2 + + """ + http://docs.opencv.org/modules/legacy/doc/motion_analysis.html + Note that smoothness parameter for cv.CalcOpticalFlowHS needs to be SMALLER than matlab + to get similar result. Useless when smoothness was 1 in OpenCV, but it's 1 in Matlab! + """ + cvref = cv2.fromarray(ref) + cvnew = cv2.fromarray(new) + # result is placed in u,v + # matlab vision.OpticalFlow Horn-Shunck has default maxiter=10, terminate=eps, smoothness=1 + cv2.CalcOpticalFlowHS( + cvref, + cvnew, + False, + uv[0], + uv[1], + smoothing, + (cv2.CV_TERMCRIT_ITER | cv2.CV_TERMCRIT_EPS, 8, 0.1), + ) + + # reshape to numpy float32, xpix x ypix x 2 + flow = np.dstack((np.asarray(uv[0]), np.asarray(uv[1]))) + except ImportError: + u, v = HornSchunck(ref, new) + flow = np.dstack((u, v)) + + return flow + + +def setupuv(rc): + """ + Horn Schunck legacy OpenCV function requires we use these old-fashioned cv matrices, not numpy array + """ + if cv2 is not None: + (r, c) = rc + u = cv2.CreateMat(r, c, cv2.CV_32FC1) + v = cv2.CreateMat(r, c, cv2.CV_32FC1) + return (u, v) + else: + return [None] * 2 + + +def calcofhs(new, ref, smoothing): + uv = setupuv(new.shape) + return optflowHornSchunk(new, ref, uv, smoothing) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/src/morecvutils/connectedComponents.py new/morecvutils-1.1.0/src/morecvutils/connectedComponents.py --- old/morecvutils-1.0.2/src/morecvutils/connectedComponents.py 1970-01-01 01:00:00.000000000 +0100 +++ new/morecvutils-1.1.0/src/morecvutils/connectedComponents.py 2026-03-11 23:03:53.000000000 +0100 @@ -0,0 +1,47 @@ +import cv2 +import numpy as np + + +def doblob(img, blobdet, anno: bool = True) -> tuple: + """ + img: can be RGB (MxNx3) or gray (MxN) + + http://docs.opencv.org/master/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html + http://docs.opencv.org/trunk/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html + """ + keypoints = blobdet.detect(img) + kpsize = np.asarray([k.size for k in keypoints]) + final = img.copy() # is the .copy necessary? + + final = cv2.drawKeypoints( + img, keypoints, outImage=final, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS + ) + # %% plot count of blobs + if anno: + cv2.putText( + final, + text=str(len(keypoints)), + org=(int(img.shape[1] * 0.9), 25), + fontFace=cv2.FONT_HERSHEY_PLAIN, + fontScale=2, + color=(0, 255, 0), + thickness=2, + ) + + return final, kpsize + + +def setupblob(minarea: int, maxarea: int, mindist: int): + + blobparam = cv2.SimpleBlobDetector_Params() # type: ignore[attr-defined] + blobparam.filterByArea = True + blobparam.filterByColor = False + blobparam.filterByCircularity = False + blobparam.filterByInertia = False + blobparam.filterByConvexity = False + + blobparam.minDistBetweenBlobs = mindist + blobparam.minArea = minarea + blobparam.maxArea = maxarea + # blobparam.minThreshold = 40 #we have already made a binary image + return cv2.SimpleBlobDetector_create(blobparam) # type: ignore[attr-defined] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/src/morecvutils/cv2draw.py new/morecvutils-1.1.0/src/morecvutils/cv2draw.py --- old/morecvutils-1.0.2/src/morecvutils/cv2draw.py 1970-01-01 01:00:00.000000000 +0100 +++ new/morecvutils-1.1.0/src/morecvutils/cv2draw.py 2026-03-11 23:03:53.000000000 +0100 @@ -0,0 +1,78 @@ +import cv2 + +import numpy as np + + +def draw_flow(img, flow, step=16): + """ + draws flow vectors on image + this came from opencv/examples directory + another way: http://docs.opencv.org/trunk/doc/py_tutorials/py_gui/py_drawing_functions/py_drawing_functions.html + """ + maxval = np.iinfo(img.dtype).max + + # scaleFact = 1. #arbitary factor to make flow visible + canno = (0, maxval, 0) # green color + h, w = img.shape[:2] + y, x = np.mgrid[step // 2 : h : step, step // 2 : w : step].reshape(2, -1) + fx, fy = flow[y, x].T + # create line endpoints + lines = np.vstack([x, y, (x + fx), (y + fy)]).transpose.reshape(-1, 2, 2) + lines = np.int32(lines + 0.5) + # create image + if img.ndim == 2: # assume gray + vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) + else: # already RGB + vis = img + # draw line + cv2.polylines(vis, lines, isClosed=False, color=canno, thickness=1, lineType=8) + # draw filled green circles + for (x1, y1), (_x2, _y2) in lines: + cv2.circle(vis, center=(x1, y1), radius=1, color=canno, thickness=-1) + return vis + + +def draw_hsv(mag, ang, dtype=np.uint8, fn: str | None = None): + """ + mag must be uint8, uint16, uint32 and 2-D + ang is in radians (float) + """ + assert mag.shape == ang.shape + assert mag.ndim == 2 + maxval = np.iinfo(dtype).max + + hsv = np.dstack( + ( + (np.degrees(ang) / 2).astype(dtype), # /2 to keep less than 255 + np.ones_like(mag) * maxval, # maxval must be after in 1-D case + cv2.normalize(mag, alpha=0, beta=maxval, norm_type=cv2.NORM_MINMAX), # type: ignore[call-overload] + ) + ) + rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB) + + if fn is not None: + print("writing " + fn) + cv2.imwrite(fn, rgb) + + return rgb # , hsv + + +def flow2magang(flow, dtype=np.uint8): + """ + flow dimensions y,x,2 3-D. flow[...,0] is magnitude, flow[...,1] is angle + """ + fx, fy = flow[..., 0], flow[..., 1] + return np.hypot(fx, fy).astype(dtype), np.arctan2(fy, fx) + np.pi + + +# %% selftest +if __name__ == "__main__": + flow = np.array( + [[[55, np.pi / 4], [128, 3 * np.pi / 2]], [[123, np.pi / 2], [48, np.pi]]] + ) + + mag, ang = flow2magang(flow, np.uint8) + + rgb = draw_hsv(mag, ang) + + assert rgb[1, 0, 2] == 239 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/src/morecvutils/getaviprop.py new/morecvutils-1.1.0/src/morecvutils/getaviprop.py --- old/morecvutils-1.0.2/src/morecvutils/getaviprop.py 1970-01-01 01:00:00.000000000 +0100 +++ new/morecvutils-1.1.0/src/morecvutils/getaviprop.py 2026-03-11 23:03:53.000000000 +0100 @@ -0,0 +1,62 @@ +#!/usr/bin/env python +""" +gets basic info about AVI file using OpenCV + +input: filename or cv2.Capture +""" + +from pathlib import Path +from struct import pack +from typing import Any +import cv2 + + +def getaviprop(fn: str | Path) -> dict[str, Any]: + match fn: + case str() | Path(): # assuming filename + fn = Path(fn).expanduser() + if not fn.is_file(): + raise FileNotFoundError(fn) + v = cv2.VideoCapture(str(fn)) + if v is None: + raise OSError(f"could not read {fn}") + case _: # assuming cv2.VideoCapture object + v = fn + + if not v.isOpened(): + raise OSError(f"cannot read {fn} probable codec issue") + + vidparam = { + "nframe": int(v.get(cv2.CAP_PROP_FRAME_COUNT)), + "xy_pixel": ( + int(v.get(cv2.CAP_PROP_FRAME_WIDTH)), + int(v.get(cv2.CAP_PROP_FRAME_HEIGHT)), + ), + "fps": v.get(cv2.CAP_PROP_FPS), + "codec": fourccint2ascii(int(v.get(cv2.CAP_PROP_FOURCC))), + } + + if isinstance(fn, Path): + v.release() + + return vidparam + + +def fourccint2ascii(fourcc_int: int) -> str: + """ + convert fourcc 32-bit integer code to ASCII + """ + assert isinstance(fourcc_int, int) + + return pack("<I", fourcc_int).decode("ascii") + + +if __name__ == "__main__": + from argparse import ArgumentParser + + p = ArgumentParser(description="get parameters of AVI file") + p.add_argument("avifn", help="avi filename") + args = p.parse_args() + + vidparam = getaviprop(args.avifn) + print(vidparam) Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/bunny.avi and new/morecvutils-1.1.0/src/morecvutils/tests/data/bunny.avi differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_0.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_0.png differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_1.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_1.png differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_2.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_2.png differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_3.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_3.png differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_4.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_4.png differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_5.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_5.png differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_6.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_6.png differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_7.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_7.png differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_8.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_8.png differ Binary files old/morecvutils-1.0.2/src/morecvutils/tests/data/vertsine_horizslide_9.png and new/morecvutils-1.1.0/src/morecvutils/tests/data/vertsine_horizslide_9.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/src/morecvutils/tests/test_blob.py new/morecvutils-1.1.0/src/morecvutils/tests/test_blob.py --- old/morecvutils-1.0.2/src/morecvutils/tests/test_blob.py 1970-01-01 01:00:00.000000000 +0100 +++ new/morecvutils-1.1.0/src/morecvutils/tests/test_blob.py 2026-03-11 23:03:53.000000000 +0100 @@ -0,0 +1,37 @@ +#!/usr/bin/env python +import pytest +import numpy as np +from pytest import approx + +import importlib.resources as ir + + +def test_blob(): + mb = pytest.importorskip("morecvutils.connectedComponents") + im_good = np.zeros((32, 32), dtype=np.uint8) + im_good[10:20, 10:20] = 255 + + im_bad = np.zeros((32, 32), dtype=np.uint8) + im_bad[10:12, 10:12] = 255 + + blob = mb.setupblob(10, 200, 4) + + labeled_img, label_sizes = mb.doblob(im_good, blob) + + assert labeled_img.shape == (32, 32, 3) + assert len(label_sizes) == 1 + + labeled_img, label_sizes = mb.doblob(im_bad, blob) + + assert len(label_sizes) == 0 + + +def test_avi(): + getaviprop = pytest.importorskip("morecvutils.getaviprop") + + finf = getaviprop.getaviprop(ir.files("morecvutils.tests.data") / "bunny.avi") + + assert finf["fps"] == approx(24.0) + assert finf["xy_pixel"] == (426, 240) + assert finf["nframe"] == 168 + assert finf["codec"] == "h264" Binary files old/morecvutils-1.0.2/tests/data/bunny.avi and new/morecvutils-1.1.0/tests/data/bunny.avi differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_0.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_0.png differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_1.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_1.png differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_2.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_2.png differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_3.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_3.png differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_4.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_4.png differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_5.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_5.png differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_6.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_6.png differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_7.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_7.png differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_8.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_8.png differ Binary files old/morecvutils-1.0.2/tests/data/vertsine_horizslide_9.png and new/morecvutils-1.1.0/tests/data/vertsine_horizslide_9.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/morecvutils-1.0.2/tests/test_blob.py new/morecvutils-1.1.0/tests/test_blob.py --- old/morecvutils-1.0.2/tests/test_blob.py 2019-11-19 20:00:50.000000000 +0100 +++ new/morecvutils-1.1.0/tests/test_blob.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,42 +0,0 @@ -#!/usr/bin/env python -import pytest -import numpy as np -from pytest import approx -from pathlib import Path - -R = Path(__file__).parent - - -def test_blob(): - mb = pytest.importorskip('morecvutils.connectedComponents') - im_good = np.zeros((32, 32), dtype=np.uint8) - im_good[10:20, 10:20] = 255 - - im_bad = np.zeros((32, 32), dtype=np.uint8) - im_bad[10:12, 10:12] = 255 - - blob = mb.setupblob(10, 200, 4) - - labeled_img, label_sizes = mb.doblob(im_good, blob) - - assert labeled_img.shape == (32, 32, 3) - assert len(label_sizes) == 1 - - labeled_img, label_sizes = mb.doblob(im_bad, blob) - - assert len(label_sizes) == 0 - - -def test_avi(): - getaviprop = pytest.importorskip('morecvutils.getaviprop') - - finf = getaviprop.getaviprop(R / 'data/bunny.avi') - - assert finf['fps'] == approx(24.0) - assert finf['xy_pixel'] == (426, 240) - assert finf['nframe'] == 168 - assert finf['codec'] == 'H264' - - -if __name__ == '__main__': - pytest.main([__file__])
