calango 2.2.8__tar.gz → 2.2.9__tar.gz
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.
- {calango-2.2.8 → calango-2.2.9}/PKG-INFO +13 -2
- {calango-2.2.8 → calango-2.2.9}/calango/__init__.py +3 -1
- {calango-2.2.8 → calango-2.2.9}/calango/media.py +115 -1
- {calango-2.2.8 → calango-2.2.9}/calango.egg-info/PKG-INFO +13 -2
- {calango-2.2.8 → calango-2.2.9}/calango.egg-info/requires.txt +1 -0
- {calango-2.2.8 → calango-2.2.9}/LICENSE +0 -0
- {calango-2.2.8 → calango-2.2.9}/README.md +0 -0
- {calango-2.2.8 → calango-2.2.9}/calango/devices.py +0 -0
- {calango-2.2.8 → calango-2.2.9}/calango/settings.py +0 -0
- {calango-2.2.8 → calango-2.2.9}/calango/utils.py +0 -0
- {calango-2.2.8 → calango-2.2.9}/calango.egg-info/SOURCES.txt +0 -0
- {calango-2.2.8 → calango-2.2.9}/calango.egg-info/dependency_links.txt +0 -0
- {calango-2.2.8 → calango-2.2.9}/calango.egg-info/top_level.txt +0 -0
- {calango-2.2.8 → calango-2.2.9}/setup.cfg +0 -0
- {calango-2.2.8 → calango-2.2.9}/setup.py +0 -0
- {calango-2.2.8 → calango-2.2.9}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: calango
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.9
|
|
4
4
|
Summary: It looks like calango
|
|
5
5
|
Home-page: https://github.com/cereja-project/calango
|
|
6
6
|
Author: Joab Leite
|
|
@@ -15,6 +15,17 @@ Requires-Dist: cereja
|
|
|
15
15
|
Requires-Dist: opencv-python
|
|
16
16
|
Requires-Dist: matplotlib
|
|
17
17
|
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: scikit-learn
|
|
19
|
+
Dynamic: author
|
|
20
|
+
Dynamic: author-email
|
|
21
|
+
Dynamic: classifier
|
|
22
|
+
Dynamic: description
|
|
23
|
+
Dynamic: description-content-type
|
|
24
|
+
Dynamic: home-page
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
Dynamic: requires-dist
|
|
27
|
+
Dynamic: requires-python
|
|
28
|
+
Dynamic: summary
|
|
18
29
|
|
|
19
30
|
# Calango Project
|
|
20
31
|
|
|
@@ -13,6 +13,7 @@ import cv2
|
|
|
13
13
|
import numpy as np
|
|
14
14
|
import logging
|
|
15
15
|
from matplotlib import pyplot as plt
|
|
16
|
+
from sklearn.cluster import KMeans
|
|
16
17
|
|
|
17
18
|
from .devices import Mouse
|
|
18
19
|
from .settings import ON_COLAB_JUPYTER
|
|
@@ -520,7 +521,43 @@ class Image(np.ndarray):
|
|
|
520
521
|
def save(self, p: str):
|
|
521
522
|
cv2.imwrite(p, self)
|
|
522
523
|
assert cj.Path(p).exists, f'Error saving image {p}'
|
|
524
|
+
def get_background_foreground_colors(self, k=2):
|
|
525
|
+
"""
|
|
526
|
+
Função para determinar as cores RGB do background e do foreground em uma imagem.
|
|
527
|
+
|
|
528
|
+
Parâmetros:
|
|
529
|
+
image (np.array): imagem em formato de array numpy.
|
|
530
|
+
k (int): número de clusters para segmentação de cores (2 significa fundo e primeiro plano).
|
|
531
|
+
|
|
532
|
+
Retorna:
|
|
533
|
+
dict: dicionário com as cores RGB do background e do foreground.
|
|
534
|
+
"""
|
|
535
|
+
|
|
536
|
+
# Redimensiona a imagem para acelerar o processamento
|
|
537
|
+
resize_dim = (300, 300)
|
|
538
|
+
image_resized = cv2.resize(self, resize_dim)
|
|
539
|
+
image_rgb = cv2.cvtColor(image_resized, cv2.COLOR_BGR2RGB)
|
|
540
|
+
|
|
541
|
+
# Converte a imagem para um array de pixels
|
|
542
|
+
pixels = image_rgb.reshape(-1, 3)
|
|
543
|
+
|
|
544
|
+
# Aplica KMeans para segmentar em duas cores (background e foreground)
|
|
545
|
+
kmeans = KMeans(n_clusters=k, random_state=0)
|
|
546
|
+
kmeans.fit(pixels)
|
|
547
|
+
|
|
548
|
+
# Obtém as cores dos clusters
|
|
549
|
+
cluster_colors = kmeans.cluster_centers_
|
|
550
|
+
cluster_labels, counts = np.unique(kmeans.labels_, return_counts=True)
|
|
523
551
|
|
|
552
|
+
# Identifica o background como a cor com mais pixels
|
|
553
|
+
background_idx = cluster_labels[np.argmax(counts)]
|
|
554
|
+
foreground_idx = cluster_labels[np.argmin(counts)]
|
|
555
|
+
|
|
556
|
+
# Converte as cores para inteiros RGB
|
|
557
|
+
background_rgb = tuple(map(int, cluster_colors[background_idx]))
|
|
558
|
+
foreground_rgb = tuple(map(int, cluster_colors[foreground_idx]))
|
|
559
|
+
|
|
560
|
+
return {"background_rgb": background_rgb, "foreground_rgb": foreground_rgb}
|
|
524
561
|
def plot_colors_histogram(self):
|
|
525
562
|
# tuple to select colors of each channel line
|
|
526
563
|
colors = ("red", "green", "blue") if self._color_mode == 'RGB' else ('blue', 'green', 'red')
|
|
@@ -647,6 +684,24 @@ class Image(np.ndarray):
|
|
|
647
684
|
dir_path = cj.Path(dir_path)
|
|
648
685
|
return [cls(im_p.path) for im_p in dir_path.list_files(ext=ext)]
|
|
649
686
|
|
|
687
|
+
@classmethod
|
|
688
|
+
def _get_image_from_window(cls):
|
|
689
|
+
with cj.TempDir() as tmp:
|
|
690
|
+
while True:
|
|
691
|
+
window = yield
|
|
692
|
+
p = tmp.path.join('frame.bmp')
|
|
693
|
+
window.capture_image_bmp(p.path)
|
|
694
|
+
yield Image(p.path)
|
|
695
|
+
|
|
696
|
+
@classmethod
|
|
697
|
+
def from_window(cls, window: cj.Window) -> 'Image':
|
|
698
|
+
"""
|
|
699
|
+
Get image from window
|
|
700
|
+
"""
|
|
701
|
+
gen = cls._get_image_from_window()
|
|
702
|
+
next(gen)
|
|
703
|
+
return gen.send(window)
|
|
704
|
+
|
|
650
705
|
|
|
651
706
|
class VideoWriter:
|
|
652
707
|
def __init__(self, p, fourcc=None, width=None, height=None, fps=30):
|
|
@@ -957,6 +1012,63 @@ class Screen(_IVideo):
|
|
|
957
1012
|
self._capture = False
|
|
958
1013
|
|
|
959
1014
|
|
|
1015
|
+
class WindowStream(_IVideo):
|
|
1016
|
+
|
|
1017
|
+
def __init__(self, window: cj.Window, *args, fps=None, **kwargs):
|
|
1018
|
+
self._window = window
|
|
1019
|
+
self._fps = fps or 30
|
|
1020
|
+
self._total_frames = -1
|
|
1021
|
+
self._capture = True
|
|
1022
|
+
self._frames = self.__get_frame()
|
|
1023
|
+
self._width, self._height = self._window.size
|
|
1024
|
+
|
|
1025
|
+
def set_fps(self, fps: Union[int, float]) -> None:
|
|
1026
|
+
assert isinstance(fps, (int, float)), ValueError(f'{fps} value for fps is not valid. Send int or float.')
|
|
1027
|
+
self._fps = fps
|
|
1028
|
+
|
|
1029
|
+
@property
|
|
1030
|
+
def next_frame(self) -> Tuple[bool, Union[np.ndarray, None]]:
|
|
1031
|
+
return True, next(self._frames)
|
|
1032
|
+
|
|
1033
|
+
def __get_frame(self):
|
|
1034
|
+
with cj.TempDir() as tmp:
|
|
1035
|
+
while self._capture:
|
|
1036
|
+
p = tmp.path.join('frame.bmp')
|
|
1037
|
+
self._window.capture_image_bmp(p.path)
|
|
1038
|
+
yield Image(p.path)
|
|
1039
|
+
|
|
1040
|
+
@property
|
|
1041
|
+
def width(self) -> int:
|
|
1042
|
+
return self._window.size[0]
|
|
1043
|
+
|
|
1044
|
+
@property
|
|
1045
|
+
def height(self) -> int:
|
|
1046
|
+
return self._window.size[1]
|
|
1047
|
+
|
|
1048
|
+
@property
|
|
1049
|
+
def total_frames(self) -> int:
|
|
1050
|
+
return self._total_frames
|
|
1051
|
+
|
|
1052
|
+
@property
|
|
1053
|
+
def fps(self) -> Union[int, float]:
|
|
1054
|
+
return self._fps
|
|
1055
|
+
|
|
1056
|
+
@property
|
|
1057
|
+
def is_webcam(self) -> bool:
|
|
1058
|
+
return True
|
|
1059
|
+
|
|
1060
|
+
@property
|
|
1061
|
+
def is_stream(self) -> bool:
|
|
1062
|
+
return False
|
|
1063
|
+
|
|
1064
|
+
@property
|
|
1065
|
+
def is_opened(self) -> bool:
|
|
1066
|
+
return self._capture
|
|
1067
|
+
|
|
1068
|
+
def stop(self):
|
|
1069
|
+
self._capture = False
|
|
1070
|
+
|
|
1071
|
+
|
|
960
1072
|
class Video:
|
|
961
1073
|
|
|
962
1074
|
def __init__(self, *args, fps=None, frame_preprocess=None, **kwargs):
|
|
@@ -976,7 +1088,9 @@ class Video:
|
|
|
976
1088
|
|
|
977
1089
|
def _build(self):
|
|
978
1090
|
if len(self._args):
|
|
979
|
-
if isinstance(self._args[0],
|
|
1091
|
+
if isinstance(self._args[0], cj.Window):
|
|
1092
|
+
self._cap = WindowStream(window=self._args[0], *self._args[1:], **self._kwargs)
|
|
1093
|
+
elif isinstance(self._args[0], str):
|
|
980
1094
|
if self._args[0] == 'monitor':
|
|
981
1095
|
self._cap = Screen()
|
|
982
1096
|
elif cj.request.is_url(self._args[0]):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: calango
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.9
|
|
4
4
|
Summary: It looks like calango
|
|
5
5
|
Home-page: https://github.com/cereja-project/calango
|
|
6
6
|
Author: Joab Leite
|
|
@@ -15,6 +15,17 @@ Requires-Dist: cereja
|
|
|
15
15
|
Requires-Dist: opencv-python
|
|
16
16
|
Requires-Dist: matplotlib
|
|
17
17
|
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: scikit-learn
|
|
19
|
+
Dynamic: author
|
|
20
|
+
Dynamic: author-email
|
|
21
|
+
Dynamic: classifier
|
|
22
|
+
Dynamic: description
|
|
23
|
+
Dynamic: description-content-type
|
|
24
|
+
Dynamic: home-page
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
Dynamic: requires-dist
|
|
27
|
+
Dynamic: requires-python
|
|
28
|
+
Dynamic: summary
|
|
18
29
|
|
|
19
30
|
# Calango Project
|
|
20
31
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|