mpvc 0.0.1__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.
mpvc-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: mpvc
3
+ Version: 0.0.1
4
+ Summary: Módulo para detecção de mão, rosto e malha facial usando MediaPipe e OpenCV
5
+ Author-email: Mundo Python <mundopython98@gmail.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: <=3.12,>=3.9
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: opencv-python
12
+ Requires-Dist: mediapipe==0.10.21
mpvc-0.0.1/README.md ADDED
File without changes
@@ -0,0 +1,17 @@
1
+ """
2
+ MPVC - MediaPipe & OpenCV Detectors
3
+ Módulo profissional para detecção simplificada de mãos, rostos e malha facial.
4
+ """
5
+
6
+ from .detector_maos import DetectorMaos
7
+ from.detector_rosto import DetectorRosto
8
+ from .malha_rosto import DetectorMalhaRosto
9
+
10
+ __all__ = [
11
+ 'DetectorMaos',
12
+ 'DetectorRosto',
13
+ 'DetectorMalhaRosto'
14
+ ]
15
+
16
+ __version__ = '0.0.1'
17
+ __author__ = 'Mundo Python'
@@ -0,0 +1,244 @@
1
+ # --- Importar as bibliotecas --- #
2
+ import cv2
3
+ import math
4
+ import numpy as np
5
+ import mediapipe as mp
6
+ from typing import Any, List, Tuple
7
+
8
+
9
+ class DetectorMaos:
10
+ """Classe responsável pela detecção de mãos."""
11
+ def __init__(
12
+ self,
13
+ modo: bool = False,
14
+ max_maos: int = 2,
15
+ deteccao_confianca: float = 0.5,
16
+ rastreio_confianca: float = 0.5,
17
+ cor_pontos: Tuple[int, int, int] = (0, 0, 255),
18
+ cor_conexoes: Tuple[int, int, int] = (255, 255, 255),
19
+ ):
20
+ """
21
+ Função responsável por inicializar a classe.
22
+
23
+ :param modo: Modo de captura da imagem. Se True, a detecção e rastreio serão feitos a todo momento;
24
+ fica muito travado. Se False, não são feitas a detecção e rastreio a todo momento; pode perder por
25
+ alguns instantes as marcações, porém não trava.
26
+
27
+ :param max_maos: Quantidade máxima de mãos para serem detectadas.
28
+
29
+ :param deteccao_confianca: Percentual da taxa de detecção da mão. Se for menor do que este limite,
30
+ a deteção não ocorre.
31
+
32
+ :param rastreio_confianca: Percentual da taxa de detecção da mão. Se for menor do que este limite,
33
+ a detecção não ocorre.
34
+
35
+ :param cor_pontos: Cor dos pontos.
36
+
37
+ :param cor_conexoes: Cor das conexões.
38
+ """
39
+ # --- Inicializar os módulos de detecção das mãos --- #
40
+ self.maos_mp = mp.solutions.hands
41
+ self.maos = self.maos_mp.Hands(
42
+ modo,
43
+ max_maos,
44
+ 1,
45
+ deteccao_confianca,
46
+ rastreio_confianca
47
+ )
48
+
49
+ # --- Função para desenhar os pontos nas mãos --- #
50
+ self.desenho = mp.solutions.drawing_utils
51
+
52
+ # --- Confifuração do desenho dos pontos --- #
53
+ self.desenho_pontos = self.desenho.DrawingSpec(color=cor_pontos)
54
+
55
+ # --- Configuração do desenho das conexões --- #
56
+ self.desenho_conexoes = self.desenho.DrawingSpec(color=cor_conexoes)
57
+
58
+ def encontrar_maos(self, imagem: np.ndarray, desenho: bool = True) -> np.ndarray:
59
+ """
60
+ Função responsável por detectar a(s) mão(s).
61
+ :param imagem: Imagem capturada.
62
+ :param desenho: Desenhar os pontos e as conexões na(s) mão(s).
63
+ :return: Retorna a imagem com a detecção.
64
+ """
65
+ # --- Converter a imagem de BGR para RGB --- #
66
+ imagem_rgb = cv2.cvtColor(imagem, cv2.COLOR_BGR2RGB)
67
+
68
+ # --- Passar a imagem convertida para o detector --- #
69
+ self.resultado = self.maos.process(imagem_rgb)
70
+
71
+ # --- Verificar se alguma mão foi detectada --- #
72
+ if self.resultado.multi_hand_landmarks:
73
+ for pontos in self.resultado.multi_hand_landmarks:
74
+ if desenho:
75
+ # --- Desenhar os pontos nas mãos detectadas --- #
76
+ self.desenho.draw_landmarks(
77
+ imagem,
78
+ pontos,
79
+ self.maos_mp.HAND_CONNECTIONS,
80
+ self.desenho_pontos,
81
+ self.desenho_conexoes
82
+ )
83
+
84
+ return imagem
85
+
86
+ def encontrar_pontos(
87
+ self,
88
+ imagem: np.ndarray,
89
+ mao_num: int = 0,
90
+ desenho: bool = True,
91
+ cor: Tuple[int, int, int] = (255, 0, 255),
92
+ raio: int = 7,
93
+ ponto_detectado: Any = 0
94
+ ) -> List:
95
+ """
96
+ Função responsável por encontrar a posição dps pontos da(s) mão(s).
97
+ :param imagem: Imagem capturada.
98
+ :param mao_num: Número da mão detectada.
99
+ :param desenho: Desenhar o ponto encontrado.
100
+ :param cor: Tupla com a cor do ponto (RGB).
101
+ :param raio: Raio do círculo do ponto.
102
+ :param ponto_detectado: Ponto a ser detectado.
103
+ :return: Lista com os pontos detectados.
104
+ """
105
+ # --- Lista com os pontos detectados --- #
106
+ lista_pontos = []
107
+
108
+ # --- Garantir que o ponto_detectado seja uma lista --- #
109
+ if isinstance(ponto_detectado, int):
110
+ pontos_alvo = [ponto_detectado]
111
+ else:
112
+ pontos_alvo = ponto_detectado
113
+
114
+ # --- Obter as dimensões da imagem capturada --- #
115
+ altura, largura, _ = imagem.shape
116
+
117
+ # --- Verificar se alguma mão foi detectada --- #
118
+ if self.resultado.multi_hand_landmarks:
119
+ for num_mao, landmark_mao in enumerate(self.resultado.multi_hand_landmarks):
120
+ # --- Lista com os pontos da mão detectada --- #
121
+ lista_pontos_mao = []
122
+ # --- Obter as informações dos pontos --- #
123
+ for id_, ponto in enumerate(landmark_mao.landmark):
124
+ if id_ in pontos_alvo:
125
+ # --- Transformar a posição do ponto de proporção para pixel --- #
126
+ centro_x, centro_y = int(ponto.x * largura), int(ponto.y * altura)
127
+
128
+ # --- Adicionar os pontos da mão detectda na lista --- #
129
+ lista_pontos_mao.append([id_, centro_x, centro_y])
130
+
131
+ # --- Colocar um círculo em um ponto --- #
132
+ if desenho:
133
+ cv2.circle(
134
+ imagem,
135
+ (centro_x, centro_y),
136
+ raio,
137
+ cor,
138
+ cv2.FILLED
139
+ )
140
+ lista_pontos.append(lista_pontos_mao)
141
+
142
+ return lista_pontos
143
+
144
+ def encontrar_distancia(
145
+ self,
146
+ ponto_1: int,
147
+ ponto_2: int,
148
+ imagem: np.ndarray,
149
+ mao_num: int = 0,
150
+ desenho_linha: bool = True,
151
+ desenho_ponto: bool = True,
152
+ cor_linha: Tuple[int, int, int] = (255, 0, 255),
153
+ cor_ponto: Tuple[int, int, int] = (0, 255, 0),
154
+ espessura: int = 2,
155
+ raio: int = 7
156
+ ) -> Tuple[float, np.ndarray, List[int]]:
157
+ """
158
+ Função responsável por calcular a distância entre dois pontos da mão.
159
+ :param ponto_1: ID do primeiro ponto.
160
+ :param ponto_2: ID do segundo ponto.
161
+ :param imagem: Imagem capturada.
162
+ :param mao_num: Índice da mão detectada.
163
+ :param desenho_linha: Se True, desenha uma linha entre os pontos e o centro.
164
+ :param desenho_ponto: Se True, desenha o ponto médio entre os pontos selecionados.
165
+ :param cor_linha: Cor da linha.
166
+ :param cor_ponto: Cor do ponto médio.
167
+ :param espessura: Espessura da linha que conecta os pontos.
168
+ :param raio: Raio do ponto central da linha.
169
+ :return: Uma tupla contendo a distância calculada, a imagem e uma lista com as coordenadas.
170
+ """
171
+ distancia = 0
172
+ info_pontos = []
173
+
174
+ # --- Verificar se alguma mão foi detectada e se o índice da mão existe --- #
175
+ if self.resultado.multi_hand_landmarks and len(self.resultado.multi_hand_landmarks) > mao_num:
176
+ mao_alvo = self.resultado.multi_hand_landmarks[mao_num]
177
+ altura, largura, _ = imagem.shape
178
+
179
+ # --- Extrair as coordenadas em pixels dos dois pontos --- #
180
+ x_1 = int(mao_alvo.landmark[ponto_1].x * largura)
181
+ y_1 = int(mao_alvo.landmark[ponto_1].y * altura)
182
+
183
+ x_2 = int(mao_alvo.landmark[ponto_2].x * largura)
184
+ y_2 = int(mao_alvo.landmark[ponto_2].y * altura)
185
+
186
+ # --- Encontrar o ponto central entre os pontos --- #
187
+ centro_x, centro_y = (x_1 + x_2) // 2, (y_1 + y_2) // 2
188
+ info_pontos = [x_1, y_1, x_1, y_2, centro_x, centro_y]
189
+
190
+ # --- Calcular a distância euclidiana --- #
191
+ distancia = math.hypot(x_2 - x_1, y_2 - y_1)
192
+
193
+ # --- Desenhar a linha e o ponto central --- #
194
+ if desenho_linha:
195
+ cv2.line(imagem, (x_1, y_1), (x_2, y_2), cor_linha, espessura)
196
+ if desenho_ponto:
197
+ cv2.circle(imagem, (centro_x, centro_y), raio, cor_ponto, cv2.FILLED)
198
+
199
+ return distancia, imagem, info_pontos
200
+
201
+
202
+ def main():
203
+ # --- Capturar o vídeo pela webcam --- #
204
+ cap = cv2.VideoCapture(0)
205
+
206
+ # --- Instanciar a classe do detector --- #
207
+ detector = DetectorMaos()
208
+
209
+ # --- Realizar a captura --- #
210
+ while True:
211
+ # --- Obter a imagem --- #
212
+ _, imagem = cap.read()
213
+
214
+ # --- Inverter a imagem --- #
215
+ imagem = cv2.flip(imagem, 1)
216
+
217
+ # --- Realizar a detecção das mãos --- #
218
+ imagem = detector.encontrar_maos(imagem)
219
+
220
+ # --- Lista com os pontos --- #
221
+ lista_pontos = detector.encontrar_pontos(imagem)
222
+
223
+ # --- Distância entre os pontos --- #
224
+ if len(lista_pontos) != 0 and len(lista_pontos[0]) > 0:
225
+ distancia, imagem, info = detector.encontrar_distancia(4, 8, imagem, desenho_ponto=False)
226
+ cv2.putText(
227
+ imagem,
228
+ f'Dist: {int(distancia)}',
229
+ (10, 50),
230
+ cv2.FONT_HERSHEY_SIMPLEX,
231
+ 1,
232
+ (255, 255, 0),
233
+ 2
234
+ )
235
+
236
+ # --- Mostrar a imagem de captura --- #
237
+ cv2.imshow('Captura', imagem)
238
+
239
+ # --- Tempo de atualização da captura --- #
240
+ cv2.waitKey(1)
241
+
242
+
243
+ if __name__ == '__main__':
244
+ main()
@@ -0,0 +1,232 @@
1
+ # --- Importar as bibliotecas --- #
2
+ import cv2
3
+ import numpy as np
4
+ import mediapipe as mp
5
+ from typing import List, Tuple
6
+
7
+ class DetectorRosto:
8
+ """Classe responsável por detectar rostos."""
9
+ def __init__(self, deteccao_confianca: float = 0.5):
10
+ """
11
+ Função responsável por iniciar a classe.
12
+ :param deteccao_confianca: Percentual da taxa de detecção do rosto. Se for menor que este limite,
13
+ a detecção não ocorre.
14
+ """
15
+ # --- Inicializar a função de detecção do rosto --- #
16
+ self.rosto_mp = mp.solutions.face_detection
17
+ self.rosto = self.rosto_mp.FaceDetection(deteccao_confianca)
18
+
19
+ def encontrar_rosto(
20
+ self,
21
+ imagem: np.ndarray,
22
+ desenho: bool = True,
23
+ cor_caixa: Tuple[int, int, int] = (255, 0, 255),
24
+ cor_moldura: Tuple[int, int, int] = (255, 0, 255),
25
+ comprimento: int = 30,
26
+ espessura_moldura: int = 5,
27
+ espessura_retangulo: int = 1,
28
+ desenho_caixa: bool = True,
29
+ desenho_moldura: bool = True,
30
+ texto: bool = True
31
+ ) -> Tuple[np.ndarray, List]:
32
+ """
33
+ Função responsável por detectar o(s) rosto(s).
34
+ :param imagem: Imagem capturada.
35
+ :param desenho: Desenhar a(s) caixa(s) de detecção do(s) rosto(s).
36
+ :param cor_caixa: Cor da caixa.
37
+ :param cor_moldura: Cor da moldura.
38
+ :param comprimento: Comprimento da linha da moldura.
39
+ :param espessura_moldura: Espessura da linha da moldura.
40
+ :param espessura_retangulo: Espessura do retângulo da(s) caixa(s).
41
+ :param desenho_caixa: Desenhar a caixa de detecção.
42
+ :param desenho_moldura: Desenhar a moldura na caixa de detecção.
43
+ :param texto: Escrever o texto da porcentagem de detecção.
44
+ :return: Retorna a imagem com a detecção e a lista com a(s) caixa(s) de detecção.
45
+ """
46
+ # --- Converter a imagem de BGR para RGB --- #
47
+ imagem_rgb = cv2.cvtColor(imagem, cv2.COLOR_BGR2RGB)
48
+
49
+ # --- Passar a imagem convertida para o detector --- #
50
+ resultado = self.rosto.process(imagem_rgb)
51
+
52
+ # --- Dimensões da imagem de captura --- #
53
+ altura, largura, _ = imagem.shape
54
+
55
+ # --- Lista com as caixa de detecção do rosto --- #
56
+ caixas = []
57
+
58
+ # --- Verificar se ocorreu a detecção do rosto --- #
59
+ if resultado.detections:
60
+ # --- Obter o ID da detecção, bem como a detecção --- #
61
+ for id_, deteccao in enumerate(resultado.detections):
62
+ # --- Informações da caixa de reconhecimento --- #
63
+ info_caixa = deteccao.location_data.relative_bounding_box
64
+
65
+ # --- Caixa de detecção --- #
66
+ caixa = (int(info_caixa.xmin * largura), int(info_caixa.ymin * altura),
67
+ int(info_caixa.width * largura), int(info_caixa.height * altura))
68
+
69
+ # --- Adicionar a caixa à lista de caixas --- #
70
+ caixas.append([id_, caixa, deteccao.score])
71
+
72
+ # --- Desenhar a caixa em volta do rosto detectado --- #
73
+ if desenho:
74
+ imagem = self.desenho_moldura(
75
+ imagem,
76
+ caixa,
77
+ cor_caixa,
78
+ cor_moldura,
79
+ comprimento,
80
+ espessura_moldura,
81
+ espessura_retangulo,
82
+ desenho_caixa,
83
+ desenho_moldura
84
+ )
85
+
86
+ if texto:
87
+ # --- Colocar na caixa de detecção a porcentagem de certeza da detecção --- #
88
+ cv2.putText(
89
+ imagem,
90
+ f'{int(deteccao.score[0] * 100)}%',
91
+ (caixa[0], caixa[1] - 20),
92
+ cv2.FONT_HERSHEY_PLAIN,
93
+ 2,
94
+ cor_caixa,
95
+ 2
96
+ )
97
+
98
+ return imagem, caixas
99
+
100
+ def desenho_moldura(
101
+ self,
102
+ imagem: np.ndarray,
103
+ caixa: List,
104
+ cor_caixa: Tuple,
105
+ cor_moldura: Tuple,
106
+ comprimento: int,
107
+ espessura_moldura: int,
108
+ espessura_retangulo: int,
109
+ desenho_caixa: bool,
110
+ desenho_moldura: bool
111
+ )-> np.ndarray:
112
+ """
113
+ Função responsável por criar a moldura da caixa de detecção do(s) rosto(s).
114
+ :param imagem: Imagem capturada.
115
+ :param caixa: Caixa de detecção.
116
+ :param cor_caixa: Cor da caixa.
117
+ :param cor_moldura: Cor da moldura.
118
+ :param comprimento: Comprimento da linha da moldura.
119
+ :param espessura_moldura: Espessura da linha da moldura.
120
+ :param espessura_retangulo: Espessura do retângulo da(s) caixa(s).
121
+ :param desenho_caixa: Desenhar a caixa de detecção.
122
+ :param desenho_moldura: DEsenhar a moldura na caixa de detecção.
123
+ :return: Retorna a imagem com a caixa de detecção desenhada.
124
+ """
125
+ # --- Dimensões da caixa --- #
126
+ x, y, largura, altura = caixa
127
+
128
+ # --- Pontos iniciais da moldura --- #
129
+ x_1, y_1 = x + largura, y + largura
130
+
131
+ if desenho_caixa:
132
+ # --- Desenhar a caixa em volta do rosto detectado --- #
133
+ cv2.rectangle(
134
+ imagem,
135
+ caixa,
136
+ cor_caixa,
137
+ espessura_retangulo
138
+ )
139
+
140
+ if desenho_moldura:
141
+ # --- Canto superior esquerdo --- #
142
+ cv2.line(
143
+ imagem,
144
+ (x, y),
145
+ (x + comprimento, y),
146
+ cor_moldura,
147
+ espessura_moldura
148
+ )
149
+ cv2.line(
150
+ imagem,
151
+ (x, y),
152
+ (x, y + comprimento),
153
+ cor_moldura,
154
+ espessura_moldura
155
+ )
156
+
157
+ # --- Canto superior direito --- #
158
+ cv2.line(
159
+ imagem,
160
+ (x_1, y),
161
+ (x_1 - comprimento, y),
162
+ cor_moldura,
163
+ espessura_moldura
164
+ )
165
+ cv2.line(
166
+ imagem,
167
+ (x_1, y),
168
+ (x_1, y + comprimento),
169
+ cor_moldura,
170
+ espessura_moldura
171
+ )
172
+
173
+ # --- Canto inferior esquerdo --- #
174
+ cv2.line(
175
+ imagem,
176
+ (x, y_1),
177
+ (x + comprimento, y_1),
178
+ cor_moldura,
179
+ espessura_moldura
180
+ )
181
+ cv2.line(
182
+ imagem,
183
+ (x, y_1),
184
+ (x, y_1 - comprimento),
185
+ cor_moldura,
186
+ espessura_moldura
187
+ )
188
+
189
+ # --- Canto inferior direito --- #
190
+ cv2.line(
191
+ imagem,
192
+ (x_1, y_1),
193
+ (x_1 - comprimento, y_1),
194
+ cor_moldura,
195
+ espessura_moldura
196
+ )
197
+ cv2.line(
198
+ imagem,
199
+ (x_1, y_1),
200
+ (x_1, y_1 - comprimento),
201
+ cor_moldura,
202
+ espessura_moldura
203
+ )
204
+
205
+ return imagem
206
+
207
+
208
+ def main():
209
+ # --- Captura da webcam --- #
210
+ cap = cv2.VideoCapture(0)
211
+
212
+ # --- Instanciar o detector de rosto --- #
213
+ detector = DetectorRosto()
214
+
215
+ # --- Loop de captura --- #
216
+ while True:
217
+ # --- Obter a imagem --- #
218
+ _, imagem = cap.read()
219
+
220
+ # --- Inverter a imagem --- #
221
+ imagem = cv2.flip(imagem, 1)
222
+
223
+ imagem, caixas = detector.encontrar_rosto(imagem)
224
+
225
+ # --- Mostrar a captura --- #
226
+ cv2.imshow('Captura', imagem)
227
+
228
+ # --- Tempo de atualização da captura --- #
229
+ cv2.waitKey(1)
230
+
231
+ if __name__ == '__main__':
232
+ main()
@@ -0,0 +1,160 @@
1
+ # --- Importar as bibliotecas --- #
2
+ import cv2
3
+ import numpy as np
4
+ import mediapipe as mp
5
+ from typing import List, Tuple
6
+
7
+ class DetectorMalhaRosto:
8
+ def __init__(
9
+ self,
10
+ modo: bool = False,
11
+ max_rosto: int = 2,
12
+ refinar_pontos: bool = False,
13
+ deteccao_confianca: float = 0.5,
14
+ rastreio_confianca: float = 0.5,
15
+ cor_pontos: Tuple = (255, 255, 255),
16
+ cor_conexoes: Tuple = (0, 255, 0)
17
+ ):
18
+ """
19
+ Função responsável por inicializar a classe.
20
+
21
+ :param modo: Modo de captura da imagem. Se True, a detecção e o rastrio serão feitos a todo momento;
22
+ deixa muito travado. Se False, não são feitas a detecção e rastrio a todo momento; pode perder
23
+ pos alguns instântes as marcações, porém não trava.
24
+
25
+ :param max_rostos: Quantidade máxima de rostos para serem detectados.
26
+
27
+ :param refinar_pontos: Refinar as coordenadas dos pontos da boca e dos olhos.
28
+
29
+ :param deteccao_confianca: Percentual da taxa de detecção do rosto. Se for menor do que este limite,
30
+ a detecção não ocorre.
31
+
32
+ :param rastreio_confianca: Percentual da taxa do rastreio do rosto. Se for menor do que este limite,
33
+ o rastreio não ocorre.
34
+
35
+ :param cor_pontos: Cor dos pontos.
36
+
37
+ :param cor_conexoes: Cor das conexões.
38
+ """
39
+
40
+ # --- Inicializar a função de detecção da malha do rosto --- #
41
+ self.malha_rosto_mp = mp.solutions.face_mesh
42
+ self.malha_rosto = self.malha_rosto_mp.FaceMesh(
43
+ modo,
44
+ max_rosto,
45
+ refinar_pontos,
46
+ deteccao_confianca,
47
+ rastreio_confianca
48
+ )
49
+ self.malha_rosto_conexoes = mp.solutions.face_mesh_connections
50
+
51
+ # --- Função para desenhar a malha no rosto --- #
52
+ self.desenho = mp.solutions.drawing_utils
53
+
54
+ # --- Configuração do desenho dos pontos --- #
55
+ self.desenho_pontos = self.desenho.DrawingSpec(
56
+ color=cor_pontos,
57
+ thickness=1,
58
+ circle_radius=1
59
+ )
60
+
61
+ # --- Configuração do desenho das conexões --- #
62
+ self.desenho_conexoes = self.desenho.DrawingSpec(
63
+ color=cor_conexoes,
64
+ thickness=1
65
+ )
66
+
67
+ def encontrar_malha_rosto(
68
+ self,
69
+ imagem: np.ndarray,
70
+ desenho: bool = True
71
+ )-> np.ndarray:
72
+ """
73
+ Função responsável por detectar o(s) rosto(s) e aplicar a malha.
74
+ :param imagem: Imagem capturada.
75
+ :param desenho: Desenhar a(s) malha(s) no(s) rosto(s).
76
+ :return: Retorna a imagem com a malha facial.
77
+ """
78
+ # --- Converter a imagem de BGR para RGB --- #
79
+ imagem_rgb = cv2.cvtColor(imagem, cv2.COLOR_BGR2RGB)
80
+
81
+ # --- Passar a imagem convertida para o detector --- #
82
+ self.resultado = self.malha_rosto.process(imagem_rgb)
83
+
84
+ # --- Verificar se ocorreu detecção do rosto --- #
85
+ if self.resultado.multi_face_landmarks:
86
+ # --- Obter os pontos da malha facial --- #
87
+ for ponto in self.resultado.multi_face_landmarks:
88
+ if desenho:
89
+ # --- Desenhar os pontos da malha --- #
90
+ self.desenho.draw_landmarks(
91
+ imagem,
92
+ ponto,
93
+ self.malha_rosto_conexoes.FACEMESH_CONTOURS,
94
+ self.desenho_pontos,
95
+ self.desenho_conexoes
96
+ )
97
+
98
+ return imagem
99
+
100
+ def encontrar_pontos(self, imagem: np.ndarray) -> List:
101
+ """
102
+ Função responsável por informar os pontos da malha facial.
103
+ :param imagem: Imagem capturada.
104
+ :return: Retorna a lista com os pontos da(s) malha(s) do(s) rosto(s) detectado(s).
105
+ """
106
+ # --- Lista com os pontos do rosto --- #
107
+ rostos = []
108
+
109
+ # --- Obter as dimensões da imagem --- #
110
+ altura, largura, _ = imagem.shape
111
+
112
+ # --- Verificar se ocorreu a detecção do rosto --- #
113
+ if self.resultado.multi_face_landmarks:
114
+ # --- Obter os pontos da malha facial --- #
115
+ for pontos in self.resultado.multi_face_landmarks:
116
+ # --- Lista com a malha do rosto detectado --- #
117
+ rosto = []
118
+
119
+ # --- Obter a informação de cada ponto da malha --- #
120
+ for id_, ponto in enumerate(pontos.landmark):
121
+ # --- Converter os valores de proporção para pixels --- #
122
+ x, y = int(ponto.x * largura), int(ponto.y * altura)
123
+
124
+ # --- Adicionar à lista de rosto o ponto do rosto --- #
125
+ rosto.append([id_, x, y])
126
+
127
+ # --- Adicionar a lista com os pontos do rosto à lista de rostos detectados --- #
128
+ rostos.append(rosto)
129
+
130
+ return rostos
131
+
132
+
133
+ def main():
134
+ # --- Captura da webcam --- #
135
+ cap = cv2.VideoCapture(0)
136
+
137
+ # --- Instanciar o detector da malha facial --- #
138
+ detector = DetectorMalhaRosto()
139
+
140
+ # --- Loop de captura --- #
141
+ while True:
142
+ # --- Captura da imagem --- #
143
+ _, imagem = cap.read()
144
+
145
+ # --- Inverter a imagem --- #
146
+ imagem = cv2.flip(imagem, 1)
147
+
148
+ # --- Detectar a malha do rosto --- #
149
+ imagem = detector.encontrar_malha_rosto(imagem)
150
+ rostos = detector.encontrar_pontos(imagem)
151
+
152
+ # --- Mostrar a imagem --- #
153
+ cv2.imshow('Captura', imagem)
154
+
155
+ # --- Tempo de atualização --- #
156
+ cv2.waitKey(1)
157
+
158
+
159
+ if __name__ == '__main__':
160
+ main()
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: mpvc
3
+ Version: 0.0.1
4
+ Summary: Módulo para detecção de mão, rosto e malha facial usando MediaPipe e OpenCV
5
+ Author-email: Mundo Python <mundopython98@gmail.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: <=3.12,>=3.9
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: opencv-python
12
+ Requires-Dist: mediapipe==0.10.21
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ mpvc/__init__.py
4
+ mpvc/detector_maos.py
5
+ mpvc/detector_rosto.py
6
+ mpvc/malha_rosto.py
7
+ mpvc.egg-info/PKG-INFO
8
+ mpvc.egg-info/SOURCES.txt
9
+ mpvc.egg-info/dependency_links.txt
10
+ mpvc.egg-info/requires.txt
11
+ mpvc.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ opencv-python
2
+ mediapipe==0.10.21
@@ -0,0 +1 @@
1
+ mpvc
@@ -0,0 +1,26 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "mpvc"
7
+ version = "0.0.1"
8
+ authors = [
9
+ { name="Mundo Python", email="mundopython98@gmail.com" },
10
+ ]
11
+ description = "Módulo para detecção de mão, rosto e malha facial usando MediaPipe e OpenCV"
12
+ readme = "README.md"
13
+ requires-python = ">=3.9, <=3.12"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = [
20
+ "opencv-python",
21
+ "mediapipe==0.10.21",
22
+ ]
23
+
24
+ [tool.setuptools.packages.find]
25
+ where = ["."]
26
+ include = ["mpvc*"]
mpvc-0.0.1/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+