Introdução: por que reconhecer uma lata de Coca-Cola é mais difícil do que parece
Imagine: você está programando um robô que deve classificar lixo automaticamente. Ou um sistema que conta a quantidade de produtos em uma prateleira. Uma das tarefas mais populares em entrevistas e projetos educacionais é o reconhecimento de uma lata de Coca-Cola. Parece simples, não? Um cilindro vermelho brilhante com uma inscrição branca. Mas na prática, tudo é diferente.
No Stack Overflow, a pergunta "Image Processing: Algorithm Improvement for 'Coca-Cola Can' Recognition" acumulou milhares de visualizações e dezenas de respostas. Programadores lutaram com o problema: como distinguir de forma confiável a lata de outros objetos vermelhos (extintor de incêndio, caneca vermelha, pedaço de plástico) em diferentes condições de iluminação?
Neste artigo, não vamos apenas fornecer um código pronto em C++ usando OpenCV. Vamos analisar passo a passo os algoritmos de processamento de imagens que transformam um fluxo de vídeo bruto em um reconhecimento confiável. Você aprenderá como melhorar a precisão da detecção, evitar falsos positivos e escrever um código que funcione em tempo real.
O problema: por que métodos simples não funcionam
O erro típico de um iniciante é tentar encontrar o objeto apenas pela cor. Por exemplo, destacar todos os pixels vermelhos e encontrar o maior contorno entre eles. Mas:
- A iluminação muda — a cor vermelha sob luz fluorescente e sob o sol parece diferente.
- Reflexos no metal — a lata reflete luz, e sua cor pode parecer branca ou laranja.
- O fundo causa ruído — camisetas vermelhas, cadeiras, outdoors publicitários confundem o detector.
- A forma é distorcida — a lata pode estar girada, parcialmente coberta ou deformada.
Portanto, a melhoria do algoritmo de reconhecimento não é apenas uma questão de ajustar limites, mas uma combinação de métodos: filtragem de cores, busca de contornos, análise de forma e texturas.
Arquitetura da solução: dos pixels à decisão
Vamos construir um pipeline de três etapas:
- Pré-processamento — desfoque, conversão para HSV, morfologia.
- Segmentação — destaque de candidatos por cor e contornos.
- Verificação — filtragem por proporção de aspecto, área, características de textura.
Essa abordagem é usada em visão computacional em C++ para tarefas industriais — desde a classificação de peças até o controle de qualidade.
Passo 1: Filtragem de cores em HSV
O primeiro e mais importante passo é converter a imagem de RGB para HSV (Matiz, Saturação, Valor). Por quê? Porque o HSV separa a cor (matiz) do brilho. Isso permite definir um intervalo para a cor vermelha que funcione sob diferentes iluminações.
#include <opencv2/opencv.hpp>using namespace cv;
Mat hsv, mask;cvtColor(src, hsv, COLOR_BGR2HSV);
// Intervalo para a cor vermelha (dois intervalos devido à ciclicidade do HSV)Scalar lower_red1 = Scalar(0, 70, 50);Scalar upper_red1 = Scalar(10, 255, 255);Scalar lower_red2 = Scalar(170, 70, 50);Scalar upper_red2 = Scalar(180, 255, 255);
Mat mask1, mask2;inRange(hsv, lower_red1, upper_red1, mask1);inRange(hsv, lower_red2, upper_red2, mask2);mask = mask1 | mask2;Observe: a cor vermelha está na borda do HSV (0 e 180 graus), portanto precisamos de dois intervalos. Os parâmetros de Saturação (70) e Valor (50) eliminam pixels muito pálidos ou muito escuros.
Passo 2: Morfologia e busca de contornos
Após a máscara, obtemos uma imagem binária, mas ela contém ruído. Aplicamos o fechamento morfológico (closing) para preencher buracos dentro da lata, e a abertura (opening) para remover pequenos pontos.
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));morphologyEx(mask, mask, MORPH_CLOSE, kernel);morphologyEx(mask, mask, MORPH_OPEN, kernel);