Mosaico de imagens com OpenCV e Python
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.
Passos para a criar um mosaico:
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.
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.
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.
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:
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.
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).
import cv2
import glob
import matplotlib.pyplot as plt
import math
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.
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)
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.
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])
Passo 4 - Construção do mosaico e exibição do resultado
Por fim, usaremos a classe stitcher para realizar o panorama das imagens selecionadas:
stitcher = cv2.Stitcher_create()
status, result = stitcher.stitch(images)
if status == 0:
plt.figure(figsize=[30, 10])
plt.imshow(result)
plt.show()
Código completo: Link no Github
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()