diff --git a/projetos/projeto_01/README.md b/projetos/projeto_01/README.md new file mode 100644 index 0000000..5dea8e4 --- /dev/null +++ b/projetos/projeto_01/README.md @@ -0,0 +1,30 @@ +# Projeto 01 - Substituição de Fundo Verde em Vídeos (Chroma Key) + +Este script substitui o fundo verde em um vídeo (chroma key) por um vídeo ou imagem de fundo selecionada. + +## Instalação + +```bash +git clone https://github.com/carlosfab/visao-computacional.git +cd visao-computacional/projetos/projeto_01/ +pip install -r requirements.txt +``` + +## Como Usar + +Para usar o script, execute o seguinte comando no terminal, substituindo `` pelo caminho do vídeo com o fundo verde e `` pelo caminho do vídeo ou imagem que será usado como novo fundo. + +```bash +python projeto_01.py -i -b +``` + +### Argumentos + +* `-i`, `--input`: Caminho para o vídeo de entrada com fundo verde. +* `-b`, `--background`: Caminho para o vídeo ou imagem de fundo que substituirá o fundo verde. + +## Contato + +Este repositório faz parte do programa de [Especialização em Visão Computacional](https://escola.sigmoidal.ai/especializacao-em-visao-computacional). Para dúvidas, sugestões ou feedbacks: + +> **Carlos Melo** - [Contato](https://sigmoidal.ai/contato/) diff --git a/projetos/projeto_01/data/praia.jpg b/projetos/projeto_01/data/praia.jpg new file mode 100644 index 0000000..530d931 Binary files /dev/null and b/projetos/projeto_01/data/praia.jpg differ diff --git a/projetos/projeto_01/data/praia.mp4 b/projetos/projeto_01/data/praia.mp4 new file mode 100755 index 0000000..75752a7 Binary files /dev/null and b/projetos/projeto_01/data/praia.mp4 differ diff --git a/projetos/projeto_01/data/webcam.mp4 b/projetos/projeto_01/data/webcam.mp4 new file mode 100755 index 0000000..007a269 Binary files /dev/null and b/projetos/projeto_01/data/webcam.mp4 differ diff --git a/projetos/projeto_01/identificar_cor.py b/projetos/projeto_01/identificar_cor.py new file mode 100644 index 0000000..83bb202 --- /dev/null +++ b/projetos/projeto_01/identificar_cor.py @@ -0,0 +1,95 @@ +""" +Este módulo contém um script para extrair cores RGB de um vídeo usando o OpenCV. + +O script abre um arquivo de vídeo e exibe seus quadros. Quando o usuário clica em um pixel no quadro, o script +extrai a cor RGB daquele pixel e adiciona-a a uma lista de amostras de cores. Em seguida, o script calcula os limites +inferior e superior da faixa de cor com base nas amostras e exibe as informações de cor no quadro. + +Uso: + python identificar_cor.py -i + +Argumentos: + -i (--image): Caminho para o arquivo de vídeo. + +Exemplo: + python identificar_cor.py -i video.mp4 +""" +import argparse + +import cv2 +import numpy as np + +# Inicializa a lista de amostras +samples = [] + + +# Função callback para o evento do mouse +def callback(event: int, x: int, y: int) -> None: + """ + Função de callback a ser chamada quando um evento do mouse ocorre na janela da imagem. + + Esta função recupera a cor na localização do clique, adiciona-a a uma lista de amostras, + calcula os limites inferior e superior da faixa de cor, e exibe as informações de cor na janela da imagem. + + Args: + event (int): O tipo de evento do mouse que ocorreu. + x (int): A coordenada x do evento do mouse. + y (int): A coordenada y do evento do mouse. + + Returns: + None + """ + if event == cv2.EVENT_LBUTTONDOWN: + # Recupera as cores na localização do clique + blue = frame[y, x, 0] + green = frame[y, x, 1] + red = frame[y, x, 2] + # Adiciona a cor à lista de amostras + samples.append([blue, green, red]) + # Calcula os limites inferior e superior + lower_bound = np.amin(samples, axis=0) + upper_bound = np.amax(samples, axis=0) + print(f'Lower bound: {lower_bound}') + print(f'Upper bound: {upper_bound}') + # Desenha as informações na tela + text = f'B: {blue}, G: {green}, R: {red}' + cv2.putText( + frame, + text, + (x, y), + cv2.FONT_HERSHEY_SIMPLEX, + 0.5, + (255, 255, 255), + 1, + ) + cv2.imshow('image', frame) + + +# Configura o argparse +parser = argparse.ArgumentParser( + description='Script para extrair cores RGB de um video.' +) +parser.add_argument( + '-i', '--image', help='Caminho para o video.', required=True +) +args = parser.parse_args() + +# Carrega o primeiro frame do video +cap = cv2.VideoCapture(args.image) +ret, frame = cap.read() +if not ret: + print(f'Não foi possível abrir o video: {args.image}') + exit(1) + +cv2.namedWindow('image') +cv2.setMouseCallback('image', callback) + +# Exibe a imagem até que o usuário pressione 'q' ou 'esc' +while True: + cv2.imshow('image', frame) + key = cv2.waitKey(1) & 0xFF + if key == ord('q') or key == 27: + break + +cap.release() +cv2.destroyAllWindows() diff --git a/projetos/projeto_01/projeto_01.py b/projetos/projeto_01/projeto_01.py new file mode 100644 index 0000000..a5778d3 --- /dev/null +++ b/projetos/projeto_01/projeto_01.py @@ -0,0 +1,88 @@ +""" +Este script substitui o fundo verde em um vídeo (chroma key) por um vídeo ou imagem de fundo selecionada. + +Uso: + python projeto_01.py -i -b + +Argumentos: + -i, --input Caminho para o vídeo de entrada com fundo verde. + -b, --background Caminho para o vídeo ou imagem de fundo que substituirá o fundo verde. + +O script processa o vídeo de entrada quadro a quadro, identificando os pixels verdes usando uma faixa de cor especificada. +Em seguida, sobreponha essas áreas com os pixels correspondentes do vídeo ou imagem de fundo. O resultado é um novo +fluxo de vídeo exibido em tempo real onde o fundo verde original é substituído de forma contínua. + +Pressione 'q' enquanto a janela de saída está em foco para encerrar o programa. + +Exemplo: + python projeto_01.py -i video_entrada.mp4 -b video_fundo.mp4 +""" + +import argparse + +import cv2 +import numpy as np + +# Configura o argparse +parser = argparse.ArgumentParser( + description='Script para substituição de fundo verde por uma imagem escolhida.' +) +parser.add_argument( + '-i', + '--input', + help='Caminho para o vídeo com fundo verde.', + required=True, +) +parser.add_argument( + '-b', '--background', help='Caminho para o vídeo de fundo.', required=True +) +args = parser.parse_args() + +# Carrega os dois vídeos +cap_webcam = cv2.VideoCapture(args.input) +cap_praia = cv2.VideoCapture(args.background) + +# Loop principal +while True: + # Lê um quadro de cada vídeo + ret_webcam, frame_webcam = cap_webcam.read() + ret_praia, frame_praia = cap_praia.read() + + # Verifica se os vídeos terminaram + if not ret_webcam or not ret_praia: + break + + # Define os limites da cor verde em RGB + lower_green = np.array([0, 100, 0], dtype=np.uint8) + upper_green = np.array([100, 255, 100], dtype=np.uint8) + + # Cria uma máscara com os pixels que estão dentro da faixa de cor verde + mask = cv2.inRange(frame_webcam, lower_green, upper_green) + + # Usa a máscara para extrair os pixels da praia que correspondem ao fundo verde da webcam + praia_background = cv2.bitwise_and(frame_praia, frame_praia, mask=mask) + + # Inverte a máscara para obter os pixels que não estão na faixa de cor verde + mask_inv = np.invert(mask) + + # Usa a máscara invertida para extrair os pixels da webcam que não são verdes + webcam_foreground = cv2.bitwise_and( + frame_webcam, frame_webcam, mask=mask_inv + ) + + # Combina o primeiro plano da webcam e o fundo da praia + result = cv2.addWeighted(praia_background, 1, webcam_foreground, 1, 0) + + # Exibe o resultado + cv2.imshow('Result', result) + + # Verifica se a tecla 'q' foi pressionada + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# Quando tudo estiver pronto, libera a captura e fecha todas as janelas +cap_webcam.release() +cap_praia.release() +cv2.destroyAllWindows() + + diff --git a/projetos/projeto_01/requirements.txt b/projetos/projeto_01/requirements.txt new file mode 100644 index 0000000..ab4b974 --- /dev/null +++ b/projetos/projeto_01/requirements.txt @@ -0,0 +1,2 @@ +numpy>=1.26.1,<2.0.0 +opencv-python>=4.8