Script para abrir webcam com Python utilizando OpenCV
Tags: ptbr, opencv, python, visaocomputacional
Published: 2021-07-19 17:07:49

Já pensou em desenvolver algum projetinho que precisa de uma captura de imagem em tempo real, mas não sabe por onde começar? Nesse post vamos trazer uma solução simples de como fazer um script utilizando **Python3** e **OpenCV** para abrir a sua webcam!

<p>
<img src="https://media1.tenor.com/images/5ee541edd1960466e4f30bd90a3d0590/tenor.gif?itemid=3780800"/>
</p>

## Um pouco sobre a biblioteca OpenCV
A [**OpenCV**](https://opencv.org/) é uma biblioteca de código aberto desenvolvida pela Intel nos anos 2000, inicialmente nas linguagens C e C++, com o objetivo de melhorar o aparato disponível para o desenvolvimento de aplicações, assim como nos estudos e pesquisas na área de [**Visão Computacional**](https://pt.wikipedia.org/wiki/Vis%C3%A3o_computacional). Hoje em dia ela ainda é referência e se tornou multiplataforma e multilinguagem, isto é, podemos utilizá-la em aplicações nos mais diversos sistemas operacionais e linguagens de programação.

## OpenCV + Python == "PERFEIÇÃO"
O OpenCV não foi apenas desenvolvido para melhorar a experiência em questão de otimização das técnicas e dos algoritmos de processamento de imagem, mas também para fácil utilização da biblioteca pelos interessados. 
Quando unimos isso ao Python temos um ambiente perfeito para explorar a criatividade utilizando imagens: biblioteca simples e linguagem de sintaxe simples!
Quer provas? Continua lendo este post!

## Instalando o OpenCV na sua máquina
Para iniciar, precisaremos instalar o OpenCV na nossa máquina. Para isso, você pode instalar o pacote via pip com o comando abaixo:

```
pip install opencv-python
```
ou
```
pip3 install opencv-python
```
> Lembrando que é sempre bom considerar a criação de um **ambiente virtual** para seus projetos! Assim, caso você queira compartilhar e receber contribuições, irá ajudar bastante na configuração local do projeto na máquina do contribuidor, além de evitar que alguns erros se tornem incapazes de serem resolvidos. Caso não saiba como fazê-lo, consulte este [link](https://docs.python.org/pt-br/3/library/venv.html) da documentação do Python para saber mais. 

## Mão na massa!
Com o OpenCV instalado na máquina podemos partir para o código! Crie um arquivo .py, abra o editor de sua preferência e vamos começar!

<p>
<img src="https://media1.tenor.com/images/3ccc0e15cbf9bee22c30701649065643/tenor.gif?itemid=3393582"/>
</p>

Antes de tudo, vamos importar a nossa biblioteca:
```python
import cv2 as cv
```

Com o pacote devidamente importado, poderemos partir para a captura da imagem pela webcam do seu computador!

### Abrindo a webcam com código!
Abrir a webcam com um script Python é mais fácil do que você imagina! Vamos utilizar OpenCV para capturar imagens em tempo real.

#### Passo 1:
O primeiro passo é instanciar um objeto [**VideoCapture**](https://docs.opencv.org/master/dd/d43/tutorial_py_video_display.html). Essa classe do OpenCV é responsável por realizar a captura de frames em um vídeo, o qual passamos o caminho como parâmetro na criação do objeto. No caso da leitura da webcam, precisamos passar o seu ID de referência (se você usa um laptop, o ID da sua câmera primária é 0):
```python
camera = cv.VideoCapture(0)
```
#### Passo 2:
Para iniciar o segundo passo, é importante que você entenda **o que é um vídeo**. De uma forma bem genérica, **um vídeo é uma sucessão de imagens que imprimem uma sensação de movimento**. A cada uma dessas imagens damos o nome de **quadros (ou frames)**.

Fazendo o paralelo disso com lógica de programação, **qual a estrututa que utilizamos para fazer uma repetição sucessiva de alguma coisa?**
<p>
<img src="https://media1.tenor.com/images/7ffd2774603c1aac0d09704ec29d1255/tenor.gif?itemid=11731609"/>
</p>
Se você respondeu **laço**, está mais que correto! Mas, qual laço escolher, **for** ou **while**?

<p>
<img src="https://media1.tenor.com/images/d727553135e15b67eaee12ad00b4e213/tenor.gif?itemid=7528656"/>
</p>

Vamos pensar: estamos fazendo uma captura de vídeo em **tempo real** com a nossa webcam, então **não sabemos quando a captura irá parar**, desse modo **enquanto estiver rodando nosso script eu capturo um frame novo**. Matamos a charada e vamos de **loop while**!

Passando essa ideia para Python, temos algo do tipo:
```python
rodando = True

while rodando:
    # Captura um frame
    pass
```
#### Passo 3:
Agora podemos partir para todo o código dentro do loop!

Para fazer a captura do frame da vez, usaremos o método **read()** no nosso objeto **VideoCapture**. Esse método retorna uma tupla com dois valores: um booleano referente ao **status de captura** e o próprio **frame no formato de um array NumPy**.

O valor do **status** é muito útil para quando estamos **lendo um vídeo passado por um caminho**, visto que, quando chegamos no último frame do mesmo, o próximo não poderá ser capturado, o retorno desse valor será False e poderemos parar a execução do loop sem o lançamento de uma exceção. Além disso, pode haver algum problema na captura da webcam e isso ser indicado por esse retorno, por isso, vamos utilizá-lo. 

Já o **frame** é essencial, já que é o que mais nos interessa! A **imagem retornada** será o alvo dos **processamentos** feitos durante a iteração do loop e também será jogada na saída.

Faremos isso da seguinte forma, dissociando os valores retornados em duas variáveis:
```python
#...
while rodando:
    status, frame = camera.read()
```

#### Passo 4:
Chegou o momento de falarmos das **condições de parada**.
<p>
<img src="https://media1.tenor.com/images/4e765a33c88071c8c321f3ce5e12ff8d/tenor.gif?itemid=14191522"/>
</p>

Queremos parar a captura em **dois casos**:
1. Em casos de erro 
2. Caso eu apenas queira parar de executar o script

Vamos unir essas duas condições de parada em apenas uma condição:
```python
#...
    if not status or cv.waitKey(1) & 0xff == ord('q'):
        rodando = False
```
<p>
<img src="https://media1.tenor.com/images/86f3b65249fbaca12e142281558c06ac/tenor.gif?itemid=4486363"/>
</p>

Parece estranho, mas não é difícil de entender. O que estamos querendo dizer é basicamente "**se deu algo errado na captura da imagem ou o usuário apertou a tecla 'q', então pare o script!**".

A função [**cv.waitKey(1)**](https://docs.opencv.org/master/d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7) espera que um evento de tecla acionada aconteça e, caso ocorra, ela retorna o valor da tecla pressionada segundo o padrão UTF-8. Para comparar se a tecla pressionada foi a 'q', combinamos o retorno dessa função com a constante hexadecimal **0xff** e utilizamos a função padrão de python **ord('q')**, que retorna o valor de uma string passada como parâmetro em UTF-8.

Caso **ao menos uma dessas condições seja satisfeita**, a nossa variável **rodando** passa a receber **False** e na próxima iteração há a **parada do loop**. 

#### Passo 5:
Nesse estágio já temos o objeto que captura nossa imagem da webcam, a imagem capturada devidamente lida e também uma condição de parada do nosso loop. Só nos resta uma coisa: **jogar essa imagem na saída**!

<p>
<img src="https://media.tenor.com/images/55bf09e811c9fb48f27afcdb5dfe295b/tenor.gif"/>
</p>

Para isso utilizaremos a função **cv.imshow()** do OpenCV. Essa função cria recebe dois parâmetros: uma string referente ao **nome da janela** e o array que se refere a **imagem** que queremos mostrar. Temos tudo que precisamos!

Para finalmente enxergarmos a captura em tempo real, escrevemos a seguinte linha dentro do loop:
```python
#...
    cv.imshow("Camera", frame)
```

## Finalmente, o script!
Tudo isso resulta em um script de **apenas 8 linhas**!

<p>
<img src="https://media.tenor.com/images/774f034a3348256ebc3032b8c166d15f/tenor.gif"/>
</p>

```python
import cv2 as cv 

camera = cv.VideoCapture(0)
rodando = True

while rodando:

    status, frame = camera.read()

    if not status or cv.waitKey(1) & 0xff == ord('q'):
        rodando = False
    
    cv.imshow("Camera", frame)
```

Com isso temos tudo que você precisa para capturar imagens em tempo real utilizando um **script simples em Python junto com OpenCV**!

E o que fazer com esse script?

<p>
<img src="https://media1.tenor.com/images/b200fc13a785faf7d8589748b1794b27/tenor.gif?itemid=13895777"/>
</p>

Existem várias possibilidades de aproveitar essa base, que vão desde **detectores** até registros de imagens para alguma **aplicação ou sistema feito em Python**.

Muito obrigada por ter lido até o fim! Se esse post te inspirou a criar alguma coisa, não se esquece de postar nas tuas redes e me marcar, que eu quero ver ~e quem sabe eu volte aqui com mais coisas legais para fazer com OpenCV~!

Minhas redes:
[LinkedIn: Maria Eduarda de Azevedo Silva](https://www.linkedin.com/in/MariaEduardaDeAzevedo/)
[Twitter: @ddt_azevedo](https://twitter.com/ddt_azevedo)
[GitHub: MariaEduardaDeAzevedo](https://github.com/MariaEduardaDeAzevedo)