homa 0.22__py3-none-any.whl → 0.23__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of homa might be problematic. Click here for more details.

homa/__init__.py CHANGED
@@ -2,3 +2,8 @@ from .main import *
2
2
  from .filters import *
3
3
  from .camera import *
4
4
  from .orientation import *
5
+ from .spaces import *
6
+ from .events import *
7
+ from .shapes import *
8
+
9
+ from .helpers import *
homa/camera.py CHANGED
@@ -1,21 +1,19 @@
1
1
  import cv2
2
2
  from .classes.Repository import Repository
3
+ from typing import Iterator
3
4
 
4
5
 
5
- def camera(delay=10):
6
- capture = cv2.VideoCapture(0)
7
-
6
+ def camera(delay: int = 10, exit_on: str = "q") -> Iterator[int]:
8
7
  pressed_key = None
9
-
8
+ capture = cv2.VideoCapture(0)
10
9
  frame_number = 0
11
-
12
- while pressed_key != ord("q"):
13
- frame_number += 1
10
+ while pressed_key != ord(exit_on):
14
11
  _, frame = capture.read()
15
-
16
12
  Repository.images["camera"] = frame
17
13
 
14
+ frame_number += 1
18
15
  yield frame_number
16
+
19
17
  pressed_key = cv2.waitKey(delay)
20
18
 
21
19
  capture.release()
@@ -1,4 +1,4 @@
1
- from ..helpers import is_colab
1
+ from ..helpers.environment import is_colab
2
2
 
3
3
 
4
4
  class RepositoryWrapper:
@@ -8,8 +8,7 @@ class RepositoryWrapper:
8
8
 
9
9
  self.directory = "./"
10
10
  self.images = {}
11
- self.cameras = {}
12
- self.window_counter = 0
11
+ self.windows = {}
13
12
 
14
13
  if is_colab():
15
14
  from google.colab.patches import cv2_imshow as imshow
@@ -24,9 +23,5 @@ class RepositoryWrapper:
24
23
 
25
24
  self.imshow = final_imshow
26
25
 
27
- def get_counter(self):
28
- self.window_counter += 1
29
- return self.window_counter
30
-
31
26
 
32
27
  Repository = RepositoryWrapper()
homa/events.py ADDED
@@ -0,0 +1,70 @@
1
+ # enum MouseEventTypes
2
+ # {
3
+ # EVENT_MOUSEMOVE = 0,
4
+ # EVENT_LBUTTONDOWN = 1,
5
+ # EVENT_RBUTTONDOWN = 2,
6
+ # EVENT_MBUTTONDOWN = 3,
7
+ # EVENT_LBUTTONUP = 4,
8
+ # EVENT_RBUTTONUP = 5,
9
+ # EVENT_MBUTTONUP = 6,
10
+ # EVENT_LBUTTONDBLCLK = 7,
11
+ # EVENT_RBUTTONDBLCLK = 8,
12
+ # EVENT_MBUTTONDBLCLK = 9,
13
+ # EVENT_MOUSEWHEEL = 10,
14
+ # EVENT_MOUSEHWHEEL = 11,
15
+ # };
16
+ import cv2
17
+ from .main import win
18
+ from inspect import signature
19
+
20
+ event_map = {
21
+ "click": cv2.EVENT_LBUTTONDOWN,
22
+ "rclick": cv2.EVENT_RBUTTONDOWN,
23
+ "mclick": cv2.EVENT_MBUTTONDOWN,
24
+ "mouseup": cv2.EVENT_LBUTTONUP,
25
+ "rmouseup": cv2.EVENT_RBUTTONUP,
26
+ "dblclick": cv2.EVENT_LBUTTONDBLCLK,
27
+ "rdblclick": cv2.EVENT_RBUTTONDBLCLK,
28
+ "move": cv2.EVENT_MOUSEMOVE
29
+ }
30
+
31
+
32
+ def create_wrapper_function(event_name: str, handler: callable):
33
+ def wrapper_function(event, x, y, flags, param):
34
+ if event != event_map[event_name]:
35
+ return
36
+
37
+ argument_count = len(signature(handler).parameters)
38
+ if argument_count == 2:
39
+ handler(x, y)
40
+ elif argument_count == 3:
41
+ handler(x, y, flags)
42
+ elif argument_count == 4:
43
+ handler(x, y, flags, param)
44
+
45
+ return wrapper_function
46
+
47
+
48
+ def onClick(key: str, handler: callable):
49
+ win(key)
50
+ cv2.setMouseCallback(key, create_wrapper_function("click", handler))
51
+
52
+
53
+ def onRightClick(key: str, handler: callable):
54
+ win(key)
55
+ cv2.setMouseCallback(key, create_wrapper_function("rclick", handler))
56
+
57
+
58
+ def onMouseUp(key: str, handler: callable):
59
+ win(key)
60
+ cv2.setMouseCallback(key, create_wrapper_function("mouseup", handler))
61
+
62
+
63
+ def onMove(key: str, handler: callable):
64
+ win(key)
65
+ cv2.setMouseCallback(key, create_wrapper_function("mousemove", handler))
66
+
67
+
68
+ def onDoubleClick(key: str, handler: callable):
69
+ win(key)
70
+ cv2.setMouseCallback(key, create_wrapper_function("dblclick", handler))
homa/filters.py CHANGED
@@ -1,10 +1,10 @@
1
1
  from typing import List
2
2
  from .classes.Repository import Repository
3
- from .helpers import create_kernel
3
+ from .helpers.kernel import create_kernel
4
4
  import cv2
5
5
 
6
6
 
7
- def blur(key: str, kernel: int | List[int] = (7, 7), new_key: str | None = None):
7
+ def blur(key: str, kernel: int | List[int] = (7, 7), new_key: str | None = None) -> None:
8
8
  if new_key is None:
9
9
  new_key = key
10
10
 
@@ -14,21 +14,28 @@ def blur(key: str, kernel: int | List[int] = (7, 7), new_key: str | None = None)
14
14
  )
15
15
 
16
16
 
17
- def sigma(x: float = 0, y: float = 0):
17
+ def median(key: str, kernel: int | List[int] = (7, 7), new_key: str | None = None) -> None:
18
+ if new_key is None:
19
+ new_key = key
20
+
21
+ Repository.images[new_key] = cv2.medianBlur(
22
+ Repository.images[key],
23
+ create_kernel(kernel)
24
+ )
25
+
26
+
27
+ def sigma(x: float = 0, y: float = 0) -> None:
18
28
  Repository.sigmaX = x
19
29
  Repository.sigmaY = y
20
30
 
21
31
 
22
- def gaussian(key: str, kernel: None | List[int] = None, new_key: str | None = None):
32
+ def gaussian(key: str, kernel: None | List[int] = None, new_key: str | None = None) -> None:
23
33
  if new_key is None:
24
34
  new_key = key
25
35
 
26
- if isinstance(kernel, int):
27
- kernel = (kernel, kernel)
28
-
29
36
  Repository.images[new_key] = cv2.GaussianBlur(
30
37
  Repository.images[key],
31
- kernel,
38
+ create_kernel(kernel),
32
39
  sigmaX=Repository.sigmaX,
33
40
  sigmaY=Repository.sigmaY
34
41
  )
File without changes
homa/helpers/alias.py ADDED
@@ -0,0 +1,14 @@
1
+ from ..classes.Repository import Repository
2
+ from ..classes import Collection
3
+ from typing import List
4
+
5
+
6
+ def repo(key: str|None = None):
7
+ if key is None:
8
+ return Repository.images
9
+
10
+ return Repository.images[key]
11
+
12
+
13
+ def collection(items: List[any]):
14
+ return Collection(items)
@@ -0,0 +1,5 @@
1
+ import sys
2
+
3
+
4
+ def is_colab() -> bool:
5
+ return 'google.colab' in sys.modules
homa/helpers/kernel.py ADDED
@@ -0,0 +1,15 @@
1
+ from typing import Tuple
2
+
3
+
4
+ def create_kernel(value: int | Tuple[int, int]) -> Tuple[int, int]:
5
+ if isinstance(value, tuple):
6
+ x, y = value
7
+
8
+ x = x - 1 if x % 2 == 0 else x
9
+ y = y - 1 if y % 2 == 0 else y
10
+
11
+ return (x, y)
12
+
13
+ value = value - 1 if value % 2 == 0 else value
14
+
15
+ return (value, value)
homa/helpers.py CHANGED
@@ -1,30 +0,0 @@
1
- import sys
2
- from typing import List
3
- from .classes.Collection import Collection
4
- from .classes.Logger import Logger
5
-
6
-
7
- def is_colab() -> bool:
8
- return 'google.colab' in sys.modules
9
-
10
-
11
- def collection(items: List[any]):
12
- return Collection(items)
13
-
14
-
15
- def danger(message: str) -> None:
16
- Logger.danger(message)
17
-
18
-
19
- def create_kernel(value: int | tuple) -> tuple:
20
- if isinstance(value, tuple):
21
- x, y = value
22
-
23
- x = x - 1 if x % 2 == 0 else x
24
- y = y - 1 if y % 2 == 0 else y
25
-
26
- return (x, y)
27
-
28
- value = value - 1 if value % 2 == 0 else value
29
-
30
- return (value, value)
homa/main.py CHANGED
@@ -1,8 +1,20 @@
1
1
  import cv2
2
- from .helpers import danger
2
+ from .classes.Logger import Logger
3
3
  from .classes.Repository import Repository
4
4
 
5
5
 
6
+ def destroy(key: str | None = None) -> None:
7
+ if key is not None:
8
+ cv2.destroyWindow(key)
9
+ return
10
+
11
+ cv2.destroyAllWindows()
12
+
13
+
14
+ def win(key: str):
15
+ cv2.namedWindow(key)
16
+
17
+
6
18
  def path(directory: str) -> None:
7
19
  Repository.directory = directory
8
20
 
@@ -41,16 +53,23 @@ def show(key: any = None, wait: bool = False, window: str = "Homa Window") -> No
41
53
 
42
54
  if key is not None and not isinstance(key, str):
43
55
  Repository.imshow(window, key)
56
+ Repository.windows[key] = window
44
57
 
45
58
  elif key is None:
46
59
  for key, image in Repository.images.items():
47
60
  Repository.imshow(key, image)
61
+ Repository.windows[key] = key
48
62
 
49
63
  elif key is not None:
50
64
  if key in Repository.images:
51
65
  Repository.imshow(key, Repository.images[key])
66
+ Repository.windows[key] = key
52
67
  else:
53
- danger(f"No image found with key {key}")
68
+ Logger.danger(f"No image found with key {key}")
54
69
 
55
70
  if wait:
56
71
  cv2.waitKey(0)
72
+
73
+
74
+ def refresh(key: str) -> None:
75
+ cv2.imshow(Repository.windows[key], Repository.images[key])
homa/orientation.py CHANGED
@@ -1,6 +1,5 @@
1
- from typing import List
2
1
  from .classes.Repository import Repository
3
- from .helpers import collection
2
+ from .helpers.alias import collection
4
3
  import numpy
5
4
 
6
5
 
@@ -15,8 +14,11 @@ def stack(*keys, **settings):
15
14
  **settings
16
15
  }
17
16
 
17
+ if all(isinstance(item, str) for item in keys):
18
+ keys = collection(keys).map(lambda key: Repository.images[key])
19
+
18
20
  stacked_image = numpy.concatenate(
19
- collection(keys).map(lambda key: Repository.images[key]),
21
+ keys,
20
22
  axis=settings["axis"]
21
23
  )
22
24
 
homa/shapes.py ADDED
@@ -0,0 +1,9 @@
1
+ import cv2
2
+ from .main import refresh
3
+ from .helpers.alias import repo
4
+ from .classes.Repository import Repository
5
+
6
+
7
+ def circle(key: str, x: int = 0, y: int = 0, r: int = 1, color=(0, 0, 255), thickness: int = 1):
8
+ cv2.circle(repo(key), (x, y), r, color, thickness)
9
+ refresh(key)
homa/spaces.py ADDED
@@ -0,0 +1,20 @@
1
+ from typing import Tuple
2
+ from .helpers.alias import repo
3
+
4
+
5
+ def rgb(key: str) -> Tuple[int, int, int]:
6
+ image = repo(key)
7
+
8
+ if image.shape[2] == 3:
9
+ # found three channels in stored image
10
+ # meaning that it has been loaded as a color image
11
+
12
+ b = image[:, :, 0]
13
+ g = image[:, :, 0]
14
+ r = image[:, :, 0]
15
+
16
+ return (r, g, b)
17
+
18
+ if image.shape[2] == 1:
19
+ gray = image[:, :, 0]
20
+ return (gray, gray, gray)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: homa
3
- Version: 0.22
3
+ Version: 0.23
4
4
  Maintainer: Taha Shieenavaz
5
5
  Maintainer-email: tahashieenavaz@gmail.com
6
6
  Description-Content-Type: text/markdown
@@ -49,7 +49,8 @@ image("horse.jpg")
49
49
  blur("horse", 7) # rewrites "horse" key
50
50
  blur("horse", (7, 19)) # rewrites "horse" key
51
51
  blur("horse", 9, "blurred horse") # as a new key in the repository
52
- show("blurred horse")
52
+
53
+ showWait("blurred horse")
53
54
  ```
54
55
 
55
56
  ### Gaussian Blur
@@ -62,7 +63,8 @@ image("horse.jpg")
62
63
  gaussian("horse", 7) # rewrites "horse" key
63
64
  gaussian("horse", (7, 19)) # rewrites "horse" key
64
65
  gaussian("horse", 9, "gaussian blurred horse") # as a new key in the repository
65
- show("gaussian blurred horse")
66
+
67
+ showWait("gaussian blurred horse")
66
68
  ```
67
69
 
68
70
  ## Stacking
@@ -0,0 +1,25 @@
1
+ homa/__init__.py,sha256=fImpDDouSHoDdq-q-O0p8RirzGTgXXRI4Ol_LU4f9sI,182
2
+ homa/camera.py,sha256=PHZb3sX0EFdwLDixYindluVDftg6JZlG_Ssbd3hgiNE,464
3
+ homa/constants.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ homa/events.py,sha256=Q077YcaM8-VjfKYhPQCQ7dasdu-mACKMf5cupiLNDoY,1946
5
+ homa/filters.py,sha256=lEwUZtCUSH59D4J9lWQ-d0ObSk_ikZBGRnNAZWMnpPo,1058
6
+ homa/helpers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ homa/main.py,sha256=1bRjOrU-Frdlj5a1cLvM2pUVLpk3K9EK6J0bFBC5hQU,1774
8
+ homa/orientation.py,sha256=kR7mEmbjCdyxNeQ7UuGpwTFD6EaNbXmErzaln3gpzfk,804
9
+ homa/shapes.py,sha256=MVZWkOtqkby8KiL04mK4nrirDGeQM3k8dDEZIpDt8AU,283
10
+ homa/spaces.py,sha256=yEIXofkM0ebvRBbRp-e7epETHW_xmwSrCoTyYUYV-uA,460
11
+ homa/classes/Collection.py,sha256=7hskbC8wxTAC3hHmFYXtzR5W05lsA4GaYTzjiez_6Zg,222
12
+ homa/classes/Logger.py,sha256=2VjXJzBLMW5joArFpu2wGrbWUw7S-77z7LNhKUG1Iow,93
13
+ homa/classes/Repository.py,sha256=w7hlbj6QIWNV2lWNs5-j6OXacSm6UGQ9DtX1zxaUA7c,589
14
+ homa/classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ homa/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ homa/helpers/alias.py,sha256=a-wq7UUnT_nYIh5nP-bc_EZb-0zF5VfnKwVhSuLSjw8,288
17
+ homa/helpers/environment.py,sha256=I7rD9B5zv3W8lkspntcshm5PZZRRSW81OqIjKOdZW6U,78
18
+ homa/helpers/kernel.py,sha256=sAdIW92coy0BoAPlk5Ez4sE5iFU207TU7OfjP7sPSkM,330
19
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ tests/test_images.py,sha256=4k5tDcMc2YZOKAq3wNQnbJ_cO1Y_DQ-YUn82yzy__ww,772
21
+ homa-0.23.dist-info/LICENSE,sha256=js3WDbJn9k5EN6sy1uuP2QBXxyPgS5DjO4Bf5yE35hQ,1072
22
+ homa-0.23.dist-info/METADATA,sha256=rBFjHYZz3mSqydiHvPLzLoTGAbMtkJF18zVnqPZvcUk,2071
23
+ homa-0.23.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
24
+ homa-0.23.dist-info/top_level.txt,sha256=i1-Cx_lkcOD5QJEK9JYp1uDEBhtshAN7No-99mhpOZ0,11
25
+ homa-0.23.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ homa
2
+ tests
tests/__init__.py ADDED
File without changes
tests/test_images.py ADDED
@@ -0,0 +1,27 @@
1
+ from homa import *
2
+
3
+ import unittest
4
+
5
+
6
+ class LoadingImagesTest(unittest.TestCase):
7
+ def setUp(self):
8
+ pass
9
+
10
+ def test_can_load_images_into_repository(self):
11
+ image("italy.jpg", "italy")
12
+ self.assertIn("italy", repo())
13
+
14
+ def test_it_does_not_load_extra_images(self):
15
+ image("italy.jpg", "italy")
16
+ self.assertEqual(len(repo()), 1)
17
+
18
+ image("italy.jpg", "italy again")
19
+ self.assertEqual(len(repo()), 2)
20
+
21
+ def test_it_can_load_images_as_black_and_white(self):
22
+ image("italy.jpg", "italy", color=False)
23
+ self.assertEqual(len(repo("italy").shape), 2)
24
+
25
+ def test_it_can_load_images_as_colorful(self):
26
+ image("italy.jpg", "italy", color=True)
27
+ self.assertEqual(len(repo("italy").shape), 3)
@@ -1,16 +0,0 @@
1
- homa/__init__.py,sha256=BKmHKbWAjj61ESPbgQTmsQ7GH_NjRBowkD15QOIZBf0,92
2
- homa/camera.py,sha256=KZf1r7olUkMRmX5c2qcDskMAq19cKWN5gTwj24pOM9o,391
3
- homa/constants.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- homa/filters.py,sha256=oIo6dsB8OnCAkSDlYUzOySxEhlUI4D6ZHkKvO2GvuP4,821
5
- homa/helpers.py,sha256=iS-MzPtcfwJYxmhM9NtWfWmWuLUwnAKaN3ZxxVA4SHw,593
6
- homa/main.py,sha256=g0Uk271_qE8xq6Gs2hVMGNI73Sp7zjPbP-jiaaFndfo,1346
7
- homa/orientation.py,sha256=0BdvozqBuuscMjG9zSl6YFt__MS4zM52Ja04SjbxIpk,749
8
- homa/classes/Collection.py,sha256=7hskbC8wxTAC3hHmFYXtzR5W05lsA4GaYTzjiez_6Zg,222
9
- homa/classes/Logger.py,sha256=2VjXJzBLMW5joArFpu2wGrbWUw7S-77z7LNhKUG1Iow,93
10
- homa/classes/Repository.py,sha256=c0F_okpC6d8ppsOQ5X6eUD2dfHmIiVInNrGNe6b-3ss,705
11
- homa/classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- homa-0.22.dist-info/LICENSE,sha256=js3WDbJn9k5EN6sy1uuP2QBXxyPgS5DjO4Bf5yE35hQ,1072
13
- homa-0.22.dist-info/METADATA,sha256=VpZ5AVoNJwnwHp0o8mSryTdO9oghE1u8Ha5zJfnoi4Y,2061
14
- homa-0.22.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
15
- homa-0.22.dist-info/top_level.txt,sha256=tmOfy2tuaAwc3W5-i6j61_vYJsXgR4ivBWkhJ3ZtJDc,5
16
- homa-0.22.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- homa
File without changes
File without changes