Capítulo 1: Introdução à Visão Computacional#

cover

🟡⚫ Google Colab, Linux e Bibliotecas#

O Google Colab (Colaboratory) é uma ferramenta poderosa e acessível para tarefas de visão computacional. Neste material, exploraremos como essa plataforma pode facilitar o desenvolvimento de projetos nessa área, desde a configuração inicial até o uso de recursos avançados. Além disso, veremos por que o Google Colab se tornou essencial para pesquisadores, estudantes e entusiastas da visão computacional.

Por que usar o Google Colab?#

O Google Colab é uma ferramenta gratuita fornecida pelo Google que permite a execução de código Python diretamente no navegador. Baseado no Jupyter Notebook, ele é especialmente útil para tarefas que demandam alto poder computacional, como aprendizado de máquina e visão computacional. Seu ambiente integrado elimina a necessidade de configurações locais complexas, tornando-se uma opção prática e acessível para estudantes, pesquisadores e desenvolvedores.

Principais Vantagens para Visão Computacional

Gratuito e acessível – Qualquer usuário com uma conta Google pode utilizá-lo, sem necessidade de infraestrutura própria.
Acesso a hardware avançado – Uso gratuito de GPUs e TPUs, essenciais para o treinamento e inferência de modelos complexos.
Integração com o Google Drive – Facilita o armazenamento e o acesso a grandes conjuntos de dados.
Colaboração em tempo real – Permite que vários usuários editem simultaneamente o mesmo notebook, ideal para projetos em equipe.
Ambiente interativo – Suporte a células de código e texto, proporcionando uma experiência eficiente para desenvolvimento, documentação e visualização de resultados.

Configurando um Notebook no Google Colab

  • Acessando o Colab

  • Criando um novo notebook

    • Vá até “Arquivo” > “Novo Notebook”.

    • Comece a escrever e executar código Python imediatamente.

  • Configurando o hardware

    • Para utilizar GPUs ou TPUs, acesse “Ambiente de execução” > “Alterar tipo de ambiente de execução”.

    • Em “Acelerador de hardware”, selecione “GPU” ou “TPU”, conforme necessário.

  • Salvando seu trabalho

    • O notebook é salvo automaticamente no seu Google Drive.

    • Para salvar manualmente ou criar uma cópia, vá em “Arquivo” e selecione a opção desejada.

Gerenciando Bibliotecas com pip#

O pip (Python Package Installer) é o gerenciador de pacotes padrão do Python. Ele permite instalar, atualizar, remover e gerenciar versões de bibliotecas, facilitando o controle de dependências nos projetos.

No Google Colab, todos os comandos do pip podem ser executados diretamente no ambiente usando !pip no início.

Instalando Bibliotecas

Para projetos de Visão Computacional, algumas das bibliotecas mais utilizadas incluem:

# Instalação de bibliotecas essenciais
!pip install numpy opencv-python matplotlib scikit-image pillow

Se precisar instalar múltiplos pacotes ao mesmo tempo, basta separá-los por espaço.

Listando Pacotes Instalados

Para verificar quais bibliotecas estão instaladas no ambiente e suas respectivas versões:

# Listar todos os pacotes instalados
!pip list

# Mostrar informações detalhadas sobre um pacote específico (exemplo: OpenCV)
!pip show opencv-python

Gerando e Utilizando um Arquivo de Requisitos

O comando pip freeze lista todos os pacotes instalados no formato nome==versão, útil para replicar ambientes.

# Gerar um arquivo requirements.txt com todas as dependências do ambiente
!pip freeze > requirements.txt

# Instalar dependências a partir de um arquivo requirements.txt
!pip install -r requirements.txt

Isso permite compartilhar o ambiente com outros desenvolvedores ou restaurá-lo posteriormente.

Verificando e Especificando Versões de Pacotes

Para garantir compatibilidade, você pode instalar versões específicas:

# Instalar uma versão exata (exemplo: numpy 1.21.0)
!pip install numpy==1.21.0

Caso queira listar as versões disponíveis de um pacote, utilize:

# Listar versões disponíveis de um pacote usando PyPI
!pip index versions numpy

Caso o comando acima não funcione no seu ambiente, outra alternativa é verificar diretamente no PyPI.

Atualizando Pacotes

Para manter suas bibliotecas sempre atualizadas:

# Atualizar um pacote específico
!pip install --upgrade numpy

**Caso queira verificar quais pacotes estão desatualizados e atualizá-los: **

# Listar pacotes desatualizados
!pip list --outdated

# Atualizar todos os pacotes (use com cautela)
!pip list --outdated | cut -d ' ' -f 1 | xargs -n1 pip install -U

Desinstalando Pacotes

Se precisar remover um pacote do ambiente, use:

# Remover um pacote (exemplo: numpy)
!pip uninstall numpy -y

O argumento -y confirma a remoção automaticamente.

O que cada biblioteca faz?#

  • NumPy – Manipulação eficiente de arrays e matrizes, essencial para processamento numérico e imagens.

  • OpenCV – Biblioteca poderosa para processamento de imagens e vídeos, incluindo filtros, transformações e detecção de objetos.

  • Matplotlib – Ferramenta para visualização de gráficos e exibição de imagens processadas.

  • Scikit-Image – Conjunto avançado de algoritmos para análise e manipulação de imagens.

  • Pillow – Manipulação e conversão de imagens em diversos formatos.

💡 Dica: No Google Colab, muitas dessas bibliotecas já vêm pré-instaladas. Porém, rodar o comando acima garante que você tenha a versão mais atualizada para o seu projeto.

Aqui está uma versão aprimorada da tabela, incluindo melhorias na formatação, novas explicações e o uso do nohup para executar comandos em segundo plano:

Comandos e Terminal Linux#

Como estamos trabalhando em uma máquina virtual Linux no Google Colab, podemos utilizar comandos do terminal para gerenciar arquivos, configurar o ambiente e realizar diversas tarefas administrativas. Isto também é útil para computadores rodando SO Linux.

📌 No Google Colab, os comandos do terminal devem ser precedidos por !.

Exemplos de Comandos Úteis

Comando

Descrição

Exemplo de Uso

Listar arquivos e diretórios

Exibe arquivos e pastas no diretório atual

ls

Listar arquivos com detalhes

Mostra permissões, tamanho e data de modificação

ls -l

Exibir estrutura de diretórios

Mostra a árvore de diretórios e arquivos

tree

Mudar de diretório

Acessa um diretório específico

cd /content/meu_diretorio

Criar um novo diretório

Cria uma pasta

mkdir novo_diretorio

Mover ou renomear

Move ou renomeia um arquivo ou diretório

mv arquivo.txt novo_diretorio/

Copiar um arquivo ou diretório

Copia um arquivo ou pasta

cp arquivo.txt copia_arquivo.txt

Remover um arquivo

Deleta um arquivo específico

rm arquivo.txt

Remover um diretório

Exclui uma pasta e seu conteúdo

rm -r pasta_a_remover

Verificar o caminho atual

Exibe o caminho do diretório onde você está

pwd

Verificar espaço em disco

Mostra o uso do disco

df -h

Verificar memória disponível

Exibe o uso da RAM

free -h

Exibir uso da CPU em tempo real

Mostra os processos ativos e consumo de CPU

top

Exibir processos em execução

Lista processos rodando no sistema

ps aux

Rodar um processo em segundo plano

Executa um comando sem interrupção, mesmo após fechar o Colab

nohup python meu_script.py &

Ver conteúdo de um arquivo

Exibe o conteúdo de um arquivo de texto

cat arquivo.txt

Buscar texto dentro de arquivos

Procura por palavras ou padrões dentro de arquivos

grep "erro" log.txt

Alterar permissões de um arquivo

Modifica permissões de leitura, escrita e execução

chmod +x script.sh (torna executável)

Caso precise de mais comandos ou explicações, é só avisar! 🚀

Executando Comandos em Segundo Plano com nohup

Se você deseja rodar um script que pode demorar (como o treinamento de um modelo de Visão Computacional) sem que ele seja interrompido ao fechar a aba do Colab, use nohup:

!nohup python meu_script.py > saida.log 2>&1 &

🔹 Explicação:

  • nohup impede que o processo seja encerrado ao fechar o terminal.

  • > saida.log salva a saída do programa no arquivo saida.log.

  • 2>&1 redireciona mensagens de erro para o mesmo arquivo de saída.

  • & executa o processo em segundo plano.

💡 Para acompanhar a execução, visualize a saída do log com:

!tail -f saida.log

Ambientes Virtuais em Python#

Para que servem?
✔ Isolam dependências por projeto
✔ Evitam conflitos de versões
✔ Mantêm o Python global limpo

🐍 Principais Gerenciadores

python -m venv env      # Cria
source env/bin/activate # Ativa (Linux/Mac)  |  env\Scripts\activate (Win)
deactivate              # Desativa
  • conda (Anaconda/Miniconda) Projeto

conda create -n env python=3.9  # Cria
conda activate env              # Ativa
conda deactivate                # Desativa
pip install virtualenv        # Instala
virtualenv env                # Cria
source env/bin/activate       # Ativa (Linux/Mac)  |  env\Scripts\activate (Win)
deactivate                    # Desativa
  • pipenv (Pip + Virtualenv) Projeto

pip install pipenv           # Instala
pipenv install               # Cria e instala pacotes
pipenv shell                 # Ativa
exit                         # Desativa
pip install poetry           # Instala
poetry new projeto           # Cria projeto
poetry shell                 # Ativa
exit                         # Desativa

Exemplo de Fluxo de Trabalho Típico com o Conda

# Criar ambiente com Python 3.10 e pacotes básicos
conda create -n meu_projeto python=3.10 numpy pandas -y

# Ativar o ambiente
conda activate meu_projeto

# Instalar pacotes adicionais (usando conda ou pip)
conda install matplotlib scikit-learn  # via conda
pip install opencv-python              # via pip se não disponível no conda

# Listar pacotes instalados
conda list

# Exportar configuração do ambiente
conda env export > environment.yml

# Desativar o ambiente
conda deactivate

# --- Para recriar o ambiente em outra máquina ---
conda env create -f environment.yml
conda activate meu_projeto

📂 EXERCÍCIO: Manipulação de Arquivos no Terminal Linux (Google Colab)#

INSTRUÇÕES:

  • Execute cada comando na ordem apresentada.

  • Complete os trechos indicados com “???”, inserindo os comandos corretos.

Sobre a Exclamação (!) no Google Colab:

No Google Colab, comandos de terminal Linux podem ser executados diretamente nas células do notebook usando “!” (exclamação) antes do comando. Isso permite rodar comandos como ls, mkdir, mv e muitos outros, como se estivéssemos em um terminal Linux comum.

# Baixando uma imagem da internet com o comando wget
!wget -O minha_imagem.jpg https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/800px-Cat03.jpg

# Desafio: Liste os arquivos no diretório atual para garantir que a imagem foi baixada
!???
# Exibir o caminho do diretório atual
!pwd  

# Listar os arquivos e diretórios presentes no ambiente de trabalho
!ls -lh
# Criar um diretório chamado "imagens"
!mkdir imagens

# Desafio: Mover a imagem baixada para dentro do diretório recém-criado
!mv ??? imagens/

# Verificar os arquivos dentro da pasta "imagens" para garantir que a imagem foi movida
!ls -lh imagens/
# Criar uma cópia da imagem dentro do mesmo diretório
!cp imagens/minha_imagem.jpg imagens/minha_imagem_backup.jpg

# Desafio: Renomear a cópia da imagem para "foto_gato.jpg"
!mv ??? imagens/foto_gato.jpg

# Verificar os arquivos na pasta para confirmar as mudanças
!ls -lh imagens/
# Desafio: Remover a imagem "foto_gato.jpg" da pasta "imagens"
!rm ???

# Excluir a pasta inteira e seu conteúdo (CUIDADO!)
!rm -r imagens

# Desafio: Listar novamente os arquivos no diretório atual para garantir que a pasta foi removida
!???
# Conectar o Colab ao Google Drive (Execute apenas uma vez)
from google.colab import drive
drive.mount('/content/drive')
# Criar um diretório no Google Drive
!mkdir /content/drive/MyDrive/meus_arquivos_colab

# Desafio: Mover um arquivo para o Google Drive
!mv ??? /content/drive/MyDrive/meus_arquivos_colab/

# Verificar se o arquivo foi salvo corretamente
!ls -lh /content/drive/MyDrive/meus_arquivos_colab/
# Criar um script de teste que roda infinitamente
!echo "while true; do echo 'Rodando...'; sleep 5; done" > processo.sh

# Executar o script em segundo plano com 'nohup'
!nohup bash processo.sh > saida.log 2>&1 &

# Desafio: Visualizar o log gerado em tempo real
!tail -f ???

# Desafio final: Encontrar o PID do processo e finalizá-lo
!ps aux | grep ???
!kill -9 ???

🧐 Reflexão Final

Agora que você completou o exercício, pare e reflita sobre cada comando executado.

  • Você conseguiu compreender o que cada um deles faz?

  • Foi capaz de resolver os desafios sem olhar diretamente a resposta?

  • Caso tenha encontrado dificuldades, onde exatamente ocorreu a dúvida?

Tente explicar detalhadamente cada comando e processo para um colega ou para você mesmo. Se puder ensinar alguém, significa que realmente compreendeu.

Por fim, esteja preparado para apresentar e justificar suas respostas ao professor. Se houver algo que não entendeu, volte, revise e tente mais uma vez!

👁️ Conceitos de Visão Computacional#

A Visão Computacional é um ramo da Ciência da Computação que permite que máquinas processem e interpretem imagens e vídeos, replicando a percepção visual humana. Através de algoritmos avançados, os computadores analisam padrões visuais e extraem informações úteis para diversas aplicações.

Uma das áreas mais conhecidas é o reconhecimento facial, que identifica indivíduos com base em características únicas do rosto. Essa tecnologia está presente em sistemas de segurança, redes sociais e autenticação biométrica. Outra aplicação essencial é a detecção de objetos, utilizada em veículos autônomos e sistemas de vigilância para identificar pedestres, placas e obstáculos em tempo real.

Na área da saúde, a Visão Computacional auxilia na análise de imagens médicas, tornando exames como radiografias e tomografias mais precisos na detecção de doenças. Em segurança, sistemas inteligentes são capazes de monitorar ambientes, reconhecendo atividades suspeitas e alertando operadores sobre possíveis ameaças. Já na realidade aumentada (AR), a tecnologia permite sobrepor elementos virtuais ao mundo real, criando experiências imersivas para jogos, treinamentos e comércio.

Imagem Digital: Pixels, Resolução e Canais de Cor#

Toda imagem digital é composta por pixels, que são as menores unidades visuais. A quantidade total de pixels determina a resolução, expressa como largura × altura (exemplo: 1920×1080), influenciando diretamente a qualidade da imagem.

As cores são representadas por diferentes canais. No modelo RGB (Red, Green, Blue), cada pixel combina três intensidades de cor para formar uma ampla variedade de tons. Essa estrutura permite que computadores processem imagens de forma eficiente e reproduzam cores com fidelidade.

Tipos de Imagens#

As imagens digitais podem ter diferentes representações, dependendo da aplicação. No modelo RGB, cada pixel possui três valores (vermelho, verde e azul), sendo o formato mais comum para fotografias e vídeos. Já as imagens em escala de cinza utilizam apenas tons de preto ao branco, sendo amplamente empregadas em exames médicos e reconhecimento de padrões. Por fim, as imagens binárias contêm apenas dois valores (preto e branco) e são usadas em segmentação de objetos e reconhecimento óptico de caracteres (OCR).

Veja a Ilustração a seguir sobre uma imagem digital.

setup

A seguir, nosso primeiro exemplo prático sobre representação de imagens em diferentes formatos.
Geraremos uma imagem RGB com gradientes de cor, convertê-la-emos para tons de cinza usando o canal verde e, por fim, aplicaremos um limiar para criar uma imagem binária.

O código abaixo demonstra esse processo visualmente.

import numpy as np
import matplotlib.pyplot as plt
import warnings

# Ignorar avisos do Matplotlib para evitar mensagens desnecessárias
warnings.filterwarnings("ignore", category=UserWarning, module="matplotlib")

# Criar uma imagem RGB com gradientes suaves
img_rgb = np.zeros((256, 256, 3), dtype=np.uint8)  # Inicializa uma matriz de zeros (imagem preta) com 3 canais de cor (RGB)

# Preenchendo os canais de cor com gradientes:
img_rgb[:, :, 0] = np.linspace(0, 255, 256, dtype=np.uint8).reshape((256, 1))  # Canal Vermelho (R): varia verticalmente
img_rgb[:, :, 1] = np.linspace(0, 255, 256, dtype=np.uint8).reshape((1, 256))  # Canal Verde (G): varia horizontalmente
img_rgb[:, :, 2] = np.flip(img_rgb[:, :, 1], axis=1)  # Canal Azul (B): inverso do verde, criando um gradiente oposto

# Converter a imagem para tons de cinza usando apenas o canal verde
img_grayscale = img_rgb[:, :, 1]  # Mantemos apenas os valores do canal verde

# Criar uma imagem binária (thresholding) com limiar de 127
img_binary = (img_grayscale > 127).astype(np.uint8) * 255  # Pixels acima do limiar tornam-se brancos (255), os demais pretos (0)

# Criar a figura com 3 subplots para exibir as diferentes representações da imagem
fig, axes = plt.subplots(1, 3, figsize=(12, 4))  # Cria um layout de 1 linha e 3 colunas

# Definição dos títulos e das imagens a serem exibidas
titles = ["RGB", "Grayscale (Canal Verde)", "Binária"]
images = [img_rgb, img_grayscale, img_binary]
cmaps = [None, "gray", "gray"]  # Definição do colormap para cada imagem (apenas grayscale e binária precisam de escala cinza)

# Loop para exibir as imagens nos subplots
for ax, img, title, cmap in zip(axes, images, titles, cmaps):
    ax.imshow(img, cmap=cmap)  # Mostra a imagem
    ax.set_title(title)  # Define o título da imagem
    ax.axis("off")  # Remove os eixos para melhor visualização

# Ajusta o espaçamento entre os gráficos para melhor exibição
plt.tight_layout()
plt.show()  # Exibe as imagens
../../_images/1bd8ad508390b30eaeda5165b4aa931fb5d3cd1f6f9106cfac9255799f68cfa9.png

Processamento Digital de Imagens#

O que é Processamento Digital de Imagens?#

O processamento digital de imagens envolve a aplicação de algoritmos computacionais para modificar, aprimorar ou extrair informações de imagens digitais. Essa área tem um papel fundamental em diversas aplicações, como medicina, segurança, automação e inteligência artificial. As imagens processadas podem ser adquiridas por câmeras digitais, scanners ou sensores especializados, como aqueles usados em exames médicos e sistemas de vigilância.

Principais Etapas do Processamento de Imagens#

O processamento de imagens envolve diversas etapas essenciais, cada uma com objetivos específicos para a manipulação e extração de informação visual.

Aquisição da Imagem#

A etapa inicial consiste na captura da imagem por meio de dispositivos como câmeras digitais, sensores embarcados ou scanners. O resultado é uma imagem digital que servirá como base para as próximas fases do processamento.

Exemplo: Captura de imagens médicas, como tomografias, para análise computacional.

setup

Pré-processamento#

Antes da análise propriamente dita, a imagem precisa ser ajustada para melhorar sua qualidade e reduzir interferências. Essa etapa pode incluir:

  • Remoção de ruído: Uso de filtros espaciais, como o Gaussiano, para eliminar interferências indesejadas.

  • Ajuste de contraste: Realce de detalhes por meio da manipulação da intensidade dos pixels.

  • Equalização de histograma: Redistribui os níveis de cinza para melhorar a visibilidade de padrões.

  • Suavização: Redução de variações abruptas na imagem para minimizar artefatos indesejados.

Exemplo: Aplicação de um filtro Gaussiano para reduzir ruído em imagens biométricas.

setup

Segmentação#

A segmentação divide a imagem em regiões de interesse, isolando objetos do fundo. As principais técnicas incluem:

  • Limiarização (thresholding): Separar pixels com base em um valor de intensidade, gerando uma imagem binária.

  • Segmentação baseada em regiões: Agrupar pixels semelhantes para definir objetos distintos.

  • Detecção de bordas: Identificar contornos de objetos por meio de mudanças abruptas de intensidade.

Exemplo: Uso de limiarização para separar objetos em imagens de exames laboratoriais.

setup

Reconhecimento de Objetos#

Nesta etapa, os objetos previamente segmentados são analisados e classificados. As abordagens mais comuns incluem:

  • Técnicas de aprendizado de máquina: Algoritmos treinados para identificar padrões em imagens.

  • Redes neurais convolucionais (CNNs): Modelos avançados capazes de reconhecer categorias complexas de objetos.

  • Métodos baseados em características: Análise de formas, texturas e padrões presentes na imagem.

Exemplo: Identificação automática de camundongos em experimentos de neurociência.

setup

🔗 Referência: Detecção de camundongos em experimentos

Abrindo uma Imagem com OpenCV#

Antes de realizarmos operações aritméticas com imagens, precisamos aprender a carregar uma imagem utilizando a biblioteca OpenCV. O OpenCV é uma das bibliotecas mais populares para processamento de imagens e visão computacional.

Para abrir uma imagem, utilizamos a função cv2.imread(), que lê o arquivo e o armazena como um array NumPy.

Lembre-se de que o OpenCV carrega imagens no formato BGR (Blue, Green, Red), enquanto outras bibliotecas, como o Matplotlib, utilizam o padrão RGB (Red, Green, Blue). Isso pode causar diferenças na exibição da imagem.

import cv2
import matplotlib.pyplot as plt

# Carregar a imagem
imagem = cv2.imread('imagem_exemplo.png')

# Converter de BGR para RGB (padrão do OpenCV é BGR, mas o Matplotlib usa RGB)
imagem_rgb = cv2.cvtColor(imagem, cv2.COLOR_BGR2RGB)

# Exibir a imagem
plt.imshow(imagem_rgb)
plt.title('Imagem Carregada')
plt.axis('off')
plt.show()

Explicação do código:
🔹 cv2.imread('imagem_exemplo.png') – Carrega a imagem do arquivo.
🔹 cv2.cvtColor(imagem, cv2.COLOR_BGR2RGB) – Converte a imagem de BGR para RGB para exibição correta no Matplotlib.
🔹 plt.imshow(imagem_rgb) – Exibe a imagem com as cores corretas.

Após carregar a imagem, podemos manipulá-la e aplicar diversas transformações!

📝 Exercício: Baixar, Converter e Adicionar Texto com OpenCV#

Objetivo:
Você deverá baixar uma imagem da internet, convertê-la para escala de cinza, adicionar um texto personalizado e salvar o resultado no Google Drive.

Instruções

  • Baixe uma imagem da web

    • Use requests para baixar uma imagem de uma URL (exemplo: "https://heltonmaia.com/computervision/_images/cover.jpeg").

  • Converta para escala de cinza

    • Aplique cv2.COLOR_BGR2GRAY para transformar a imagem em preto e branco.

  • Adicione um texto à imagem

    • Use cv2.putText() para inserir um texto (ex: "OpenCV Challenge").

    • Defina:

      • Posição ((x, y)).

      • Fonte (cv2.FONT_HERSHEY_SIMPLEX).

      • Escala (1.0).

      • Cor (255 para branco em imagens em cinza).

      • Espessura (2).

  • Exiba a imagem processada

    • Mostre o resultado com cv2.imshow() (ou cv2_imshow no Google Colab).

  • Salve no Google Drive

    • Monte o Drive (drive.mount('/content/drive')).

    • Salve a imagem processada em uma pasta específica.


💡 Dicas Úteis

Posicionamento do texto:

  • Use (50, 50) para colocar o texto no canto superior esquerdo.

Se estiver no Google Colab:

  • Substitua cv2.imshow() por:

from google.colab.patches import cv2_imshow
cv2_imshow(imagem_processada)   

Operações Aritméticas com Imagens#

As operações aritméticas com imagens permitem manipular seus valores de pixel de maneira precisa, abrindo um leque de possibilidades para processamento e edição. As operações mais comuns incluem:

Adição: A adição de imagens combina duas imagens somando os valores dos pixels correspondentes. A operação pode ser descrita matematicamente como:

\(I_{\text{resultante}}(x, y) = I_1(x, y) + I_2(x, y)\)

onde \( I_{\text{resultante}}(x, y) \) é o valor do pixel na posição \((x, y)\) da imagem resultante, \( I_1(x, y) \) é o valor do pixel na posição \((x, y)\) da primeira imagem, e \( I_2(x, y) \) é o valor do pixel na posição \((x, y)\) da segunda imagem.

Essa operação é útil para:

  • Combinar informações: Ao adicionar imagens de diferentes fontes, podemos integrar informações e criar uma visão mais completa.

  • Ajustar o brilho: Adicionar um valor constante a todos os pixels aumenta o brilho da imagem.

Exemplo: Adicionar duas imagens e realizar uma combinação de informações.

import numpy as np
import matplotlib.pyplot as plt

# Carregar as imagens
img1 = plt.imread('tropical1.png')
img2 = plt.imread('tropical2.png')

# Verificar se as imagens têm o mesmo tamanho
if img1.shape != img2.shape:
    raise ValueError("As imagens devem ter o mesmo tamanho para adição.")

# Adicionar as imagens
added_img = img1 + img2

# Exibir as imagens lado a lado
fig, axs = plt.subplots(1, 3, figsize=(10, 5))

# Exibir a primeira imagem
axs[0].imshow(img1)
axs[0].set_title('Imagem 1')
axs[0].axis('off')

# Exibir a segunda imagem
axs[1].imshow(img2)
axs[1].set_title('Imagem 2')
axs[1].axis('off')

# Exibir a imagem resultante da adição
axs[2].imshow(added_img)
axs[2].set_title('Imagem Resultante')
axs[2].axis('off')
plt.show()

Baixar tropical1 tropical2

Para evitar a saturação, como poderíamos melhorar o código para obter a imagem abaixo?

Imagem resultante da adição

Subtração: A subtração de imagens calcula a diferença entre os valores dos pixels correspondentes de duas imagens. A operação pode ser descrita matematicamente como:

\( I_{\text{resultante}}(x, y) = I_1(x, y) - I_2(x, y) \)

onde \( I_{\text{resultante}}(x, y) \) é o valor do pixel na posição \((x, y)\) da imagem resultante, \( I_1(x, y) \) é o valor do pixel na posição \((x, y)\) da primeira imagem, e \( I_2(x, y)\) é o valor do pixel na posição \((x, y)\) da segunda imagem.

Essa operação é útil para:

  • Detectar diferenças: A subtração pode destacar as diferenças entre duas imagens, como mudanças ao longo do tempo ou objetos movidos.

  • Isolar elementos: Ao subtrair uma imagem de fundo de uma imagem com um objeto em primeiro plano, podemos isolar o objeto.

Exemplo: Subtrair uma imagem de referência de outra para destacar as alterações ou isolar um objeto. Veja o exemplo a seguir, onde em um cenário sem muitos objetos, existe um sútil movimento de uma mulher caminhando.

import numpy as np
import matplotlib.pyplot as plt

# Carregar as imagens
img1 = plt.imread('w1.png')
img2 = plt.imread('w2.png')

# Subtrair as imagens
subtracted_img = img1 - img2

# Exibir a imagem resultante da subtração
fig, axs = plt.subplots(1, 3, figsize=(10, 5))

# Exibir a primeira imagem
axs[0].imshow(img1)
axs[0].set_title('Imagem 1')
axs[0].axis('off')

# Exibir a segunda imagem
axs[1].imshow(img2)
axs[1].set_title('Imagem 2')
axs[1].axis('off')

# Exibir a imagem resultante da subtração
axs[2].imshow(subtracted_img)
axs[2].set_title('Imagem Resultante')
axs[2].axis('off')
plt.show()

Baixar walking1 walking2

Multiplicação: A multiplicação de imagens pode ser realizada de duas maneiras:

  • Multiplicação por uma constante: Multiplicar uma imagem por uma constante altera o contraste da imagem. Um valor maior aumenta o contraste, enquanto um valor menor o reduz. A operação pode ser descrita matematicamente como:

\( I_{\text{resultante}}(x, y) = c \cdot I(x, y) \)

onde \( I_{\text{resultante}}(x, y) \) é o valor do pixel na posição \((x, y)\) da imagem resultante, \( c \) é a constante multiplicativa, e \( I(x, y) \) é o valor do pixel na posição \((x, y)\) da imagem original.

  • Multiplicação por outra imagem: Multiplicar duas imagens elemento a elemento pode ser usado para aplicar máscaras, onde uma imagem define áreas específicas para serem modificadas na outra imagem. A operação pode ser descrita matematicamente como:

\( I_{\text{resultante}}(x, y) = I_1(x, y) \cdot I_2(x, y) \)

onde \( I_{\text{resultante}}(x, y) \) é o valor do pixel na posição \((x, y)\) da imagem resultante, \( I_1(x, y) \) é o valor do pixel na posição \((x, y)\) da primeira imagem, e \( I_2(x, y) \) é o valor do pixel na posição \((x, y)\) da segunda imagem.

Exemplo: Multiplicar uma imagem por uma constante para aumentar o contraste ou aplicar uma máscara para editar partes específicas da imagem. Utilize uma imagem de sua preferência.

# Multiplicação por uma constante
constant = 1.5
multiplied_img = img1 * constant

# Exibir a imagem resultante da multiplicação por uma constante
fig, axs = plt.subplots(1, 2, figsize=(10, 5))

# Exibir a imagem original
axs[0].imshow(img1)
axs[0].set_title('Imagem Original')
axs[0].axis('off')

# Exibir a imagem resultante da multiplicação
axs[1].imshow(multiplied_img)
axs[1].set_title('Imagem com Contraste Aumentado')
axs[1].axis('off')
plt.show()

Baixar walking1

Manipulação de pixels

# Cortar uma região da imagem
corte = img1[200:, 450:900] # observe a indexação linha x coluna
corte[10:20,100:300] = [0,1,0] # Acessando uma região de pixels e definindo para verde

plt.imshow(corte)

Essas operações básicas são fundamentais para manipulação e análise de imagens, permitindo ajustes precisos e modificações específicas que são essenciais em várias aplicações de Visão Computacional.

🎨 Conversão entre Espaços de Cor#

A conversão entre espaços de cor é essencial em processamento de imagens. O OpenCV (cv2.cvtColor) permite transformar imagens entre diferentes formatos (BGR, Grayscale, HSV, RGB, LAB). Abaixo, exemplos de conversão com visualização lado a lado usando plt.imshow:

Baixar walking3

- Carregar Imagem Original (BGR)

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('w3.png')  # OpenCV carrega em BGR
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # Converter para RGB (Matplotlib)
plt.imshow(img_rgb)
plt.title('Original (RGB)')

- Conversões para Outros Espaços de Cor BGR → Grayscale (Escala de Cinza)

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1), plt.imshow(img_rgb), plt.title('Original (RGB)'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(img_gray, cmap='gray'), plt.title('Grayscale'), plt.axis('off')
plt.tight_layout(), plt.show()

BGR → HSV (Matiz, Saturação, Valor)

img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1), plt.imshow(img_rgb), plt.title('Original (RGB)'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(img_hsv), plt.title('HSV'), plt.axis('off')
plt.tight_layout(), plt.show()

BGR → LAB (Luminância, Canais A/B)

img_lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1), plt.imshow(img_rgb), plt.title('Original (RGB)'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(img_lab), plt.title('LAB'), plt.axis('off')
plt.tight_layout(), plt.show()

Visualização de Todos os Espaços de Cores

plt.figure(figsize=(16, 4))
plt.subplot(1, 4, 1), plt.imshow(img_rgb), plt.title('RGB'), plt.axis('off')
plt.subplot(1, 4, 2), plt.imshow(img_gray, cmap='gray'), plt.title('Grayscale'), plt.axis('off')
plt.subplot(1, 4, 3), plt.imshow(img_hsv), plt.title('HSV'), plt.axis('off')
plt.subplot(1, 4, 4), plt.imshow(img_lab), plt.title('LAB'), plt.axis('off')
plt.tight_layout(), plt.show()

Dicas Importantes:

- OpenCV vs Matplotlib:

  • OpenCV usa BGR por padrão; Matplotlib usa RGB. Sempre converta com cv2.COLOR_BGR2RGB antes de exibir no plt.imshow.

- Canais Individuais (HSV/LAB):
Para visualizar canais separados (ex: H, S, V):

h, s, v = cv2.split(img_hsv)
plt.imshow(h, cmap='gray'), plt.title('Canal H (Matiz)'), plt.axis('off'), plt.show()

- Transições Suaves (Vídeo):
Para criar um vídeo de transição entre espaços de cor (como no exemplo do link), use cv2.VideoWriter interpolando os valores de conversão quadro a quadro.

Aproveite que estudou sobre como transitar em diferente canais de cor e tente fazer um vídeo como este do link.

Transformações Geométricas#

As transformações geométricas permitem modificar a posição, orientação e escala de uma imagem. Abaixo, exemplos de translação, rotação, escala, perspectiva e operações aritméticas, seguindo o mesmo padrão de formatação e exibição usado no exemplo de rotação.

- Translação (Deslocamento)
Desloca a imagem nos eixos x e y usando uma matriz de transformação afim:

matriz_translacao = np.float32([[1, 0, deslocamento_x],  # [a, b, tx] → controla eixo X  
                               [0, 1, deslocamento_y]]) # [c, d, ty] → controla eixo Y  

Onde:

  • 1 e 0 mantêm a escala original (sem distorção)

  • deslocamento_x e deslocamento_y definem o movimento em pixels

  • Valores positivos: direita/baixo | Valores negativos: esquerda/cima

Exemplo:

import cv2  
import numpy as np  
import matplotlib.pyplot as plt  

img = cv2.imread('w3.png')  
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  

# Aplica translação  
deslocamento_x, deslocamento_y = 50, 100  
img_transladada = cv2.warpAffine(img, matriz_translacao, (img.shape[1], img.shape[0]))  

# Exibe resultados  
plt.figure(figsize=(12, 6))  
plt.subplot(1, 2, 1), plt.imshow(img), plt.title('Original'), plt.axis('off')  
plt.subplot(1, 2, 2), plt.imshow(img_transladada), plt.title(f'Transladada ({deslocamento_x}, {deslocamento_y})'), plt.axis('off')  
plt.show()  

Saída:

  • Imagem original (esquerda) e transladada (direita)

  • Áreas deslocadas além dos limites ficam pretas.

- Rotação
Gira a imagem em torno de um ponto central (cv2.getRotationMatrix2D).

(h, w) = img.shape[:2]
centro = (w // 2, h // 2)
angulo = 45  # Graus
escala = 1.0
matriz_rotacao = cv2.getRotationMatrix2D(centro, angulo, escala)
img_rotacionada = cv2.warpAffine(img, matriz_rotacao, (w, h))

plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1), plt.imshow(img), plt.title('Original'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(img_rotacionada), plt.title(f'Rotacionada ({angulo}°)'), plt.axis('off')
plt.tight_layout()
plt.show()

- Escala (Redimensionamento)
Altera as dimensões da imagem (cv2.resize).

nova_largura, nova_altura = 300, 200  # Novas dimensões (largura, altura)
img_redimensionada = cv2.resize(img, (nova_largura, nova_altura))

plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1), plt.imshow(img), plt.title(f'Original ({w}x{h})'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(img_redimensionada), plt.title(f'Redimensionada ({nova_largura}x{nova_altura})'), plt.axis('off')
plt.tight_layout()
plt.show()

- Transformação de Perspectiva
Muda o ponto de vista da imagem (cv2.getPerspectiveTransform + cv2.warpPerspective).

pontos_originais = np.float32([[50, 50], [200, 50], [50, 200], [200, 200]])
pontos_destino = np.float32([[10, 100], [200, 50], [100, 250], [250, 200]])
matriz_perspectiva = cv2.getPerspectiveTransform(pontos_originais, pontos_destino)
img_perspectiva = cv2.warpPerspective(img, matriz_perspectiva, (w, h))

plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1), plt.imshow(img), plt.title('Original'), plt.axis('off')
plt.subplot(1, 2, 2), plt.imshow(img_perspectiva), plt.title('Transformação de Perspectiva'), plt.axis('off')
plt.tight_layout()
plt.show()

Ajuste de Gamma para Clareamento de Imagens com OpenCV e Matplotlib#

O ajuste de gamma é uma técnica fundamental em processamento de imagens para modificar o brilho e contraste de forma não-linear. Esta abordagem é particularmente útil para realçar detalhes em regiões escuras sem afetar excessivamente as áreas claras.

Fundamentos Matemáticos A transformação de gamma segue a equação:

\[ I_{\text{out}} = 255 \times \left(\frac{I_{\text{in}}}{255}\right)^\gamma \]

Onde:

  • \(I_{\text{in}}\): Valor do pixel de entrada (0 a 255)

  • \(\gamma\): Parâmetro de correção

  • \(I_{\text{out}}\): Valor do pixel processado

Efeitos do Parâmetro Gamma

Valor de γ

Efeito na Imagem

Aplicação Típica

γ < 1

Clareamento

Melhorar sombras

γ = 1

Nenhuma alteração

-

γ > 1

Escurecimento

Reduzir áreas superexpostas

Implementação Prática

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Carregar imagem (OpenCV lê em BGR)
img = cv2.imread('w3.png')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # Conversão para RGB

# Parâmetros de gamma
gamma_values = [0.4, 1.0, 2.2]  # Exemplos para clarear, original e escurecer

# Configurar plot
plt.figure(figsize=(18, 6))

for i, gamma in enumerate(gamma_values, 1):
    # Aplicar correção de gamma
    corrected = np.power(img_rgb/255., gamma)
    corrected = (corrected * 255).astype(np.uint8)
    
    # Plotar resultados
    plt.subplot(1, 3, i)
    plt.imshow(corrected)
    plt.title(f'γ = {gamma}')
    plt.axis('off')

plt.tight_layout()
plt.show()

Esta abordagem proporciona um controle preciso sobre o realce de imagens, sendo essencial em aplicações como visão computacional, fotografia médica e processamento de vídeo.

📝 Exercício - Processamento de Imagens com Gradio#

Objetivo: Implementar um aplicativo interativo que permita realizar diversas operações de processamento de imagens, incluindo transformações geométricas, manipulação de cores e ajustes de iluminação. O aplicativo deve ser desenvolvido usando uma das bibliotecas indicadas para criar uma interface amigável.

Tarefas a serem implementadas:

  1. Transformações Geométricas

    • Translação: Permitir ao usuário especificar os valores de deslocamento horizontal e vertical.

    • Rotação: Oferecer um controle deslizante para selecionar o ângulo de rotação (0° a 360°).

    • Escala: Incluir opções para ampliar/reduzir a imagem com fatores configuráveis.

  2. Operações de Cores

    • Conversão de espaços de cor: Converter de RGB para Grayscale, HSV e outros.

    • Ajuste de contraste: Multiplicação por constante com controle deslizante para ajuste.

  3. Correção Gamma e Clareamento

    • Controle de gamma: Implementar um controle deslizante para ajustar o valor gamma (0.1 a 3.0).

Lembre-se de permitir que as imagens modificadas possam ser salvas.

Bibliotecas:

🔗 Consulte a documentação do Gradio para implementação: https://gradio.app/docs/

🔗 Consulte a documentação do Streamlit para implementação: https://docs.streamlit.io/

🔗 Consulte a documentação do NiceGUI para implementação: https://nicegui.io/documentation

🧠 Exercícios Conceituais#

1. Explorando a Visão Computacional

Descreva com suas próprias palavras o que é visão computacional.

  • Quais são seus principais objetivos?

  • Por que essa área é considerada estratégica dentro da inteligência artificial?

  • Como ela tem sido aplicada em diferentes áreas do conhecimento e da indústria?

2. Fundamentos da Imagem Digital

O capítulo apresenta os conceitos de pixels, resolução e canais de cor (RGB, escala de cinza, binário).

  • Como a resolução influencia a quantidade de detalhes contidos em uma imagem?

  • De que forma essa característica impacta o desempenho de algoritmos de análise visual?

  • Em que contextos pode ser mais vantajoso utilizar imagens em RGB, tons de cinza ou binárias? Argumente com base em objetivos diferentes de análise.

3. Etapas do Processamento de Imagens

O fluxo do processamento digital de imagens inclui as etapas de aquisição, pré-processamento, segmentação e reconhecimento.

  • Escolha um cenário que envolva análise de imagens (como monitoramento ambiental, inspeção visual, mobilidade urbana etc.).

  • Descreva como essas etapas podem ser aplicadas nesse contexto, destacando o papel de cada uma para alcançar um resultado útil.

4. Bibliotecas Python Essenciais

As bibliotecas NumPy, OpenCV, Matplotlib, Scikit-Image e Pillow são frequentemente utilizadas em projetos de visão computacional.

  • Qual é a principal finalidade de cada uma dessas ferramentas?

  • Aponte situações específicas em que cada biblioteca pode oferecer recursos decisivos para o desenvolvimento de soluções com imagens.

5. Gerenciamento de Dependências com pip

O uso do pip e de arquivos requirements.txt é essencial para organizar ambientes de desenvolvimento.

  • Por que é importante manter um controle claro sobre as bibliotecas e versões utilizadas em um projeto?

  • Que tipos de dificuldades podem surgir quando diferentes membros da equipe ou sistemas operacionais tentam reproduzir um código sem dependências bem definidas?

6. Utilizando Comandos Linux

Imagine que você precisa organizar e preparar um conjunto de imagens no Google Colab usando comandos de terminal.

  • Descrevendo uma sequência de comandos Linux que inclua:

    • Criar uma pasta para armazenar imagens

    • Listar arquivos

    • Mover imagens para essa nova pasta

    • Copiar um conjunto de arquivos para backup

  • Ao final, responda:

    • Como o conhecimento da estrutura de diretórios e do sistema de arquivos do Linux pode ajudar nesse processo?

    • O que são permissões de arquivos no Linux e como elas podem impactar o acesso e manipulação de imagens?

7. Operações Aritméticas com Imagens

Somar ou subtrair imagens pode revelar diferentes tipos de informação.

  • Quando a adição de imagens pode ser vantajosa em análise visual?

  • E a subtração, como pode destacar mudanças ou padrões?

  • Proponha situações em que essas operações seriam especialmente reveladoras.

8. Conversão entre Espaços de Cor

A conversão entre espaços como RGB, Grayscale, HSV e LAB é recorrente em tarefas visuais.

  • Por que diferentes espaços de cor são usados dependendo do problema a ser resolvido?

  • Em que tipo de tarefa a conversão para HSV ou LAB pode facilitar o processamento ou melhorar os resultados?

9. Transformações Geométricas em Imagens

As transformações de imagem — como translação, rotação e escala — são fundamentais para adaptar a imagem ao contexto da análise.

  • Escolha uma situação que envolva múltiplos ângulos, posições ou tamanhos de objetos em uma imagem.

  • Explique como essas transformações ajudam a tornar o sistema mais robusto ou sensível a variações.

10. Ajuste de Gamma em Imagens

O ajuste de gamma modifica a relação entre brilho e contraste na imagem.

  • O que acontece com uma imagem quando usamos um valor de gamma menor que 1? Em que circunstâncias isso é benéfico?

  • E se o valor for maior que 1? Em que situações isso pode melhorar a visualização ou a extração de informações?

Referências e Conteúdo Extra#