Segmentação de imagem

Uma etapa importante no processamento de imagens digitais para analisar o que está dentro dela é classificar seu conteúdo de pixeis em diferentes grupos. Esse processo é chamado de segmentação de imagem, cujo objetivo é transformar a representação de uma imagem em algo mais significativo e fácil de analisar. É muito comum o uso de algoritmos de agrupamento (“clusters”) para realizar esse procedimento. O post sobre Análise de clusters faz uma breve revisão dos métodos hierárquico e não-hierárquico de agrupamento, com aplicações em python.

Imagem all sky original e segmentada em 3 cores
Imagem all sky original e segmentada em 3 cores

O OpenCV (Open Source Computer Vision Library), originalmente desenvolvido e lançado pela Intel em 1999, é uma biblioteca livre e multiplataforma para o desenvolvimento de aplicativos na área de visão computacional. Desenvolvida em C/C++, pode ser usada no python instalando-se a biblioteca “opencv” (disponível no Conda). Possui módulos de processamento de imagens e centenas de algoritmos, como filtros de imagem, calibração de câmera, reconhecimento de objetos, análise estrutural e outros.

O OpenCV fornece a função cv2.kmeans(amostras, nclusters(K), critérios, numero_tentativas, sinalizadores) para agrupamento de cores. Os critérios são definidos como tipo, número máximo de iterações e epsilon (precisão). Os tipos podem ser cv.TERM_CRITERIA_EPS (interrompe a iteração do algoritmo se a precisão especificada, epsilon, for atingida), cv.TERM_CRITERIA_MAX_ITER (interrompe o algoritmo após o número especificado de iterações, max_iter) ou as duas juntas (interrompe a iteração quando alguma das condições for atendida). Os sinalizadores podem ser cv.KMEANS_PP_CENTERS ou cv.KMEANS_RANDOM_CENTERS.

Veja o exemplo a seguir:

#!/usr/bin/env python3.7.5
# -*- Coding: UTF-8 -*-

# Read allsky image file and do segmentation
import numpy as np
import matplotlib.pyplot as plt
import cv2

# Load image file and convert from color to RGB
original_image = cv2.imread('20181206132000_11.jpg')
img = cv2.cvtColor(original_image,cv2.COLOR_BGR2RGB, 0)
# converts the MxNx3 image into a Kx3 matrix where K=MxN
vectorized = img.reshape((-1,3))
# convert the unit8 values to float
vectorized = np.float32(vectorized)
# color clustering
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 3
attempts = 10
ret,label,center = cv2.kmeans(vectorized,K,None,criteria,attempts,cv2.KMEANS_PP_CENTERS)
# Regenerate image
center = np.uint8(center)
res = center[label.flatten()]
result_image = res.reshape((img.shape))

# Remove black (borders)
#lower = np.array([50,50,1])  #-- Lower range --
#upper = np.array([255,255,255])  #-- Upper range --
#mask = cv2.inRange(img, lower, upper)
#res = cv2.bitwise_and(img, img, mask= mask)  #-- Contains pixels having the gray color--
#result_image = res.reshape((img.shape))

# Plot images
figure_size = 15
plt.figure(figsize=(figure_size,figure_size))
plt.subplot(1,2,1),plt.imshow(img)
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(1,2,2),plt.imshow(result_image)
plt.title('Segmented Image when K = %i' % K), plt.xticks([]), plt.yticks([])
plt.show()

# Canny Edge detection
#edges = cv2.Canny(img,150,200)
#plt.figure(figsize=(figure_size,figure_size))
#plt.subplot(1,2,1),plt.imshow(img)
#plt.title('Original Image'), plt.xticks([]), plt.yticks([])
#plt.subplot(1,2,2),plt.imshow(edges,cmap = 'gray')
#plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
#plt.show()

Foi escolhido k = 3 para considerar os agrupamentos com as cores preta das bordas, azul do céu e branco/cinza das nuvens. Também foram incluídos blocos (comentados) para remover limiares de cores e para detecção de bordas. Fonte: KDnuggets – Introduction to Image Segmentation with K-Means clustering.

Existem outros algoritmos na separação entre céu e nuvem. Dentre os mais conhecidos, estão a definição de um limiar da imagem de acordo com a proporção de intensidades de vermelho e azul da imagem vermelho-verde-azul (thresholding RGB) ou de acordo com a componente de saturação da transformação matiz-saturação-intensidade (HSI) da imagem RGB original ou ainda um limiar de acordo com a escala de cinza.

A segmentação é a partição de uma imagem em várias partes “coerentes”, mas sem qualquer tentativa de compreender o que essas partes representam. Já a segmentação semântica tenta particionar a imagem em partes semanticamente significativas e classificar cada parte em uma das classes pré-determinadas.

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.