Mosaico de imagens com OpenCV e Python
Tags: python, opencv, computervision
Published: 2021-07-16 18:17:06

Um **mosaico ou panorama de imagens** (em inglês, *image stitching*) consiste em uma composição a partir de algoritmos de alinhamento, os quais estão entre os mais antigos e usados na área de Visão Computacional. 

São muito úteis, por exemplo, na construção de mapas, fotos de satélite e na criação de panoramas de imagens nos smartphones.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttzoyixa7bkzwxhpk15q.png)
 
<figcaption>Fig. 1 - Exemplo de mosaico utilizando a função panorama de um celular</figcaption>

### <br> Passos para a criar um mosaico:

#### <br>Passo 1 - Encontrar pontos-chave em todas as fotos

Consiste na identificação de pontos semelhantes nas imagens, para que haja o alinhamento correto dos objetos.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6p0hd9dnxm8u3sjewed8.png)
 
<figcaption>Fig. 2 - Pontos-chave entre duas imagens</figcaption>

#### <br>Passo 2 - Encontrar correspondências paralelas (*pairwise correspondences*)

Para que haja a construção de um único objeto identificado, é necessário encontrar correspondências entre elas. 

Como diria Fábio Jr, encontrar as metades da laranja.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/10mnxbsdb56agauyhyvi.png)
<figcaption>Fig. 3 - Correspondências entre as imagens</figcaption>

#### <br>Passo 3 e 4 - Estimar homografias semelhantes e refiná-las (*pairwise homographies*)

O processo de homografia (em inglês, *homography*) corresponde ao mapeamento de duas projeções, onde há ângulos diferentes em planos 2D ou 3D. Ao refinar esse mapeamento, é possível encontrar pontos em comum e mapear suas posições combinadas em uma única perspectiva.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4jpud9l92k1zde5jgkto.png)

<figcaption>Fig. 4 - Exemplo de um processo de homografia </figcaption>

#### <br>Passo 5 - Junção das imagens

Por fim, para realizar o panorama é preciso juntá-las usando os conceitos anteriores. Abaixo há um exemplo de mosaico:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yrduxdgpnvdz9no6kfv.png)
 
<figcaption>Fig. 5 - Resultado da junção das imagens </figcaption>
 
------

#### A fim de reproduzir esse resultado, utilizaremos a biblioteca *open-source* OpenCV e a linguagem de programação Python para construir um mosaico de múltiplas fotos.

Para criar mosaicos de imagens usando OpenCV, é indispensável usar a classe **stitcher**.

#### <br>Passo 1 - Importação das bibliotecas

Usaremos as bibliotecas **cv2** (OpenCV), **glob** (para retornar todos os arquivos em um diretório), **matplotlib.pyplot** (uma coleção de funções que simulam o MATLAB) e **math** (funções matemáticas).

```python
import cv2
import glob
import matplotlib.pyplot as plt
import math
```

#### <br>Passo 2 - Leitura das imagens

Neste passo, **glob.glob** identificará todas as imagens do diretório informado : ("diretorio/*") e a realização da leitura será feita com o apoio da função **imread** do OpenCV.
As imagens são convertidas de BGR para RGB para facilitar a identificação dos pontos-chave das imagens.

```python
imagefiles = glob.glob("diretorio/*")
imagefiles.sort()

images = []
for filename in imagefiles:
  img = cv2.imread(filename)
  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  images.append(img)

num_images = len(images)
```

#### <br>Passo 3 - Exibição das imagens

Para que haja a exibição prévia das imagens a serem utilizadas, serão plotadas linhas e colunas de acordo com **num_images**.

```python
plt.figure(figsize=[30,10]) 
num_cols = 3
num_rows = math.ceil(num_images / num_cols)
for i in range(0, num_images):
  plt.subplot(num_rows, num_cols, i+1) 
  plt.axis('off')
  plt.imshow(images[i])
```
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a738pj6q5vud295vk4k7.png)

<figcaption>Fig. 6 - Exibição das imagens </figcaption>

#### <br>Passo 4 - Construção do mosaico e exibição do resultado

Por fim, usaremos a classe **stitcher** para realizar o panorama das imagens selecionadas:

```python
stitcher = cv2.Stitcher_create()
status, result = stitcher.stitch(images)
if status == 0:
  plt.figure(figsize=[30, 10])
  plt.imshow(result)
  plt.show()
```

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/or88nbl73ybs3g0k45cg.png)
<figcaption>Fig. 7 - Resultado do panorama de imagens </figcaption>

------

#### Código completo: [Link no Github](https://github.com/tassianeanzolin/computervision/tree/main/stitching)

```python
import cv2
import glob
import matplotlib.pyplot as plt
import math

# Read Images

imagefiles = glob.glob("diretorio/*")
imagefiles.sort()

images = []
for filename in imagefiles:
  img = cv2.imread(filename)
  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  images.append(img)

num_images = len(images)

# Display Images
plt.figure(figsize=[30, 10])
num_cols = 3
num_rows = math.ceil(num_images / num_cols)
for i in range(0, num_images):
  plt.subplot(num_rows, num_cols, i+1)
  plt.axis('off')
  plt.imshow(images[i])

# Stitch Images
stitcher = cv2.Stitcher_create()
status, result = stitcher.stitch(images)
if status == 0:
  plt.figure(figsize=[30, 10])
  plt.imshow(result)
  plt.show()
```

------
#### Referências

###### GARTIA, Anisha. Project 2: Local Feature Matching. Disponível em: https://www.cc.gatech.edu/classes/AY2016/cs4476_fall/results/proj2/html/agartia3/.

###### SZELISKI, Richard. Computer Vision: Algorithms and Applications. 2021. Disponível em: https://szeliski.org/Book/.

###### MILGRAM, D. L.. Computer Methods for Creating Photomosaics, in IEEE Transactions on Computers, vol. C-24, no. 11, pp. 1113-1119, Nov. 1975, doi: 10.1109/T-C.1975.224142.

###### OPENCV. Basic concepts of the homography explained with code. Disponível em: https://docs.opencv.org/3.4/d9/dab/tutorial_homography.html. 

###### OPENCV. OpenCV Python Course. Disponível em: https://opencv.org/opencv-python-free-course/.

###### PULLI, Kari. Stitching and Blending. Disponível em: https://web.stanford.edu/class/cs231m/lectures/lecture-5-stitching-blending.pdf. Acesso em: 14 jul. 2021.

###### TARALLO, André de Souza. Construção Automática De Mosaicos De Imagens Digitais Aéreas Agrícolas Utilizando Transformada SIFT E Processamento Paralelo. 2013.

###### Wu, Mengmeng & Wang, J.. (2018). Reassembling fractured sand particles using fracture-region matching algorithm. Powder Technology. 338. 10.1016/j.powtec.2018.06.045.