Relatório 02 - Filtragem

Introdução

A filtragem de imagens é uma técnica essencial no processamento digital de imagens, usada para suavizar, reduzir ruído e destacar detalhes importantes. Este relatório explora as principais técnicas de filtragem, como a média, o filtro Gaussiano, a mediana e o filtro bilateral, todas disponíveis na biblioteca OpenCV. O uso de diferentes tamanhos de kernel e a aplicação de ruído tipo sal-e-pimenta permitem uma análise comparativa dos resultados. O objetivo é entender o impacto dessas técnicas no aprimoramento da qualidade visual e utilidade prática das imagens.

Explicando os filtros

Filtro de Média (blur):Suaviza a imagem ao calcular a média dos pixels vizinhos dentro de um kernel, suavizando detalhes e reduzindo variações bruscas de intensidade.

Filtro Gaussiano (GaussianBlur):Aplica uma função Gaussiana para suavizar a imagem, dando maior peso aos pixels centrais no kernel, preservando detalhes melhor do que a média simples.

Filtro Mediana (medianBlur):Substitui cada pixel pela mediana de seus vizinhos, eficiente para remover ruídos como sal-e-pimenta.

Filtro Bilateral (bilateralFilter):Suaviza a imagem enquanto preserva as bordas, ao levar em conta a diferença de intensidade entre os pixels vizinhos, sendo ideal para reduzir ruído sem perder nitidez nas bordas.

O que é o Kernel?

O kernel é uma pequena matriz de números (geralmente quadrada) usada em operações de filtragem de imagens. Ele percorre a imagem pixel por pixel, aplicando uma transformação com base nos valores da matriz e dos pixels correspondentes na imagem original. O objetivo do kernel é suavizar, detectar bordas ou aplicar outros efeitos de processamento. O tamanho do kernel (como 3x3, 5x5, etc.) influencia o grau de suavização ou detalhamento, com kernels maiores tendendo a produzir maior suavização, mas com potencial perda de detalhes finos.

O ruído sal e pimenta

O ruído sal e pimenta é um tipo de distorção em imagens digitais, onde pixels aleatórios são alterados para valores extremos: “sal” (branco, valor máximo) e “pimenta” (preto, valor mínimo). Isso resulta em pontos brancos e pretos dispersos na imagem. Esse tipo de ruído geralmente surge devido a falhas no sensor, transmissões defeituosas ou erros no armazenamento de imagens. Para remover esse ruído, o filtro mediana é comumente utilizado, pois substitui os pixels ruidosos pelo valor mediano de seus vizinhos, preservando as bordas da imagem.

Imagens Obtidas

Modificamos o código disponível no seguinte tutorial para que ele pudesse processar a foto dos três membros do grupo. O programa foi ajustado para ler essa imagen e, em seguida, aplicar quatro diferentes filtros: média, Gaussiano, mediana e bilateral, utilizando inicialmente um kernel 3x3, depois 5x5, 7x7 e então 11x11. Como resultado, foram geradas quatro imagens filtradas, permitindo a comparação visual dos efeitos de cada técnica de filtragem.

Filtros com kernel 3X3

3x3

3X3 Bilateral

3x3

3X3 Gaussiana

3x3

3X3 Media

3x3

3X3 Mediana

Filtros 5X5

5x5

5X5 Bilateral

5x5

5X5 Gaussiana

5x5

5X5 Media

5x5

5X5 Mediana

Filtros 7X7

7x7

7X7 Bilateral

7x7

7X7 Gaussiana

7x7

7X7 Media

7x7

7X7 Mediana

Filtros 11X11

11x11

11X11 Bilateral

11x11

11X11 Gaussiana

11x11

11X11 Media

11x11

11X11 Mediana

Análise

Na análise das imagens filtradas, observamos que, conforme o tamanho do kernel aumentou (de 3x3 a 11x11), o grau de suavização das imagens também se intensificou. No kernel 3x3 a suavização é baixa em ambos os filtros que é quase imperceptivel a diferença entre as imagens obtidas. No filtro de média, houve uma crescente perda de detalhes, principalmente nas bordas. O filtro Gaussiano apresentou suavização progressiva, mas manteve melhor definição nas bordas. No filtro mediana, observamos uma suavização dos detalhes em kernels maiores. Já o filtro bilateral preservou bem as bordas, mesmo com kernels grandes, ao suavizar regiões internas.

Ruído Sal e Pimenta

A foto do grupo recebeu o tratamento do ruído sal e pimenta conforme a imagem abaixo:

Sal e Pimenta

Filtro Sal e Pimenta

Filtros com kernel 3X3

3x3

3X3 Bilateral

3x3

3X3 Gaussiana

3x3

3X3 Media

3x3

3X3 Mediana

Filtros 5X5

5x5

5X5 Bilateral

5x5

5X5 Gaussiana

5x5

5X5 Media

5x5

5X5 Mediana

Filtros 7X7

7x7

7X7 Bilateral

7x7

7X7 Gaussiana

7x7

7X7 Media

7x7

7X7 Mediana

Filtros 11X11

11x11

11X11 Bilateral

11x11

11X11 Gaussiana

11x11

11X11 Media

11x11

11X11 Mediana

Análise

Podemos destacar a diferença entre as imagens com ruído sal e pimenta e as tratadas com filtros de suavização. O filtro de mediana se mostrou o mais eficaz, removendo o ruído enquanto preserva os contornos da imagem de forma eficiente até o kernel 7x7, perdendo detalhes no kernel 11x11. Já o filtro gaussiano, embora suavize a imagem, não foi tão eficiente na eliminação específica do ruído sal e pimenta, resultando em maior perda de detalhes. O filtro bilateral foi o que se mostrou mais ineficiente em remover o ruído sal e pimenta.

Webcam com filtro

O código foi alterado para que o filtro Gaussiano fosse aplicado na webcam e que ao clicar na tecla [S] salvasse uma foto.

Arquivo: webcam.cpp


#include 
#include 

using namespace std;
using namespace cv;

int main() {
    	// Inicializa a captura da webcam
    	VideoCapture cap(0); // 0 é o ID da webcam padrão
	if (!cap.isOpened()) {
        	cerr << "Erro ao abrir a webcam!" << endl;
        	return -1;
    	}

    	Mat frame, filtered_frame;
    	char key;

    	while (true) {
        	// Captura um novo quadro da webcam
        	cap >> frame;

        	// Verifica se o quadro foi capturado
        	if (frame.empty()) {
            		cerr << "Erro ao capturar imagem da webcam!" << endl;
            		break;
        	}

        	// Aplica o filtro gaussiano
        	GaussianBlur(frame, filtered_frame, Size(11, 11), 0);

        	// Exibe a imagem filtrada
        	imshow("Filtro Gaussiano - Webcam", filtered_frame);

        	// Espera pela tecla 's' para salvar a imagem ou 'q' para sair
        	key = waitKey(30);
        	if (key == 's') {
            		imwrite("imagem_filtrada.jpg", filtered_frame);
            		cout << "Imagem salva como 'imagem_filtrada.jpg'" << endl;
        	}
        	if (key == 'q') {
            		break; // Sai do loop se a tecla 'q' for pressionada
        	}
    	}

    	// Libera a captura e fecha as janelas
    	cap.release();
    	destroyAllWindows();

    	return 0;
}
        		

Webcam filtro

Imagem da Webcam com filtro

Programa de Filtragem

Para facilitar a captura das imagens, fizemos uma alteração no código abaixo para que o usuário escolha o filtro através das teclas [a], [g], [m], e [b] do teclado, para os filtros de média, gaussiano, mediana, e bilateral, respectivamente. E escolher o kernel através das teclas [3], [5], [7], [9], [B] do teclado, para os kernel (3x3), (5x5), (7x7), (9x9), e (11x11) respectivamente. Por fim salvar a imagem ao clicar a tecla [s].


#include 
#include 

using namespace std;
using namespace cv;

int main() {
	// Inicializa a captura da webcam
    	VideoCapture cap(0);
    	if (!cap.isOpened()) {
        	cerr << "Erro ao abrir a webcam!" << endl;
        	return -1;
    	}

    	Mat frame, filtered_frame;
    	char key;
    	int kernelSize = 3; // Tamanho do kernel padrão
    	int filterType = 0; // 0: Média, 1: Gaussiano, 2: Mediana, 3: Bilateral

    	while (true) {
        	// Captura um novo quadro da webcam
        	cap >> frame;
        	if (frame.empty()) {
            		cerr << "Erro ao capturar imagem da webcam!" << endl;
            		break;
        	}

        	// Aplica o filtro selecionado
        	switch (filterType) {
            		case 0: // Filtro de média
                		blur(frame, filtered_frame, Size(kernelSize, kernelSize));
                		break;
            		case 1: // Filtro gaussiano
                		GaussianBlur(frame, filtered_frame, Size(kernelSize, kernelSize), 0);
                		break;
            		case 2: // Filtro mediano
                		medianBlur(frame, filtered_frame, kernelSize);
                		break;
            		case 3: // Filtro bilateral
                		bilateralFilter(frame, filtered_frame, kernelSize, kernelSize * 2, kernelSize / 2);
                		break;
            		default:
                		filtered_frame = frame; // Sem filtro
                		break;
        	}

        	// Exibe a imagem filtrada
        	imshow("Filtragem da Webcam", filtered_frame);

        	// Espera pela tecla do usuário
        	key = waitKey(30);
        	if (key == 'a') {
            		filterType = 0; // Média
        	} else if (key == 'g') {
            		filterType = 1; // Gaussiano
        	} else if (key == 'm') {
            		filterType = 2; // Mediana
        	} else if (key == 'b') {
            		filterType = 3; // Bilateral
        	} else if (key == '3') {
            		kernelSize = 3;
        	} else if (key == '5') {
            		kernelSize = 5;
        	} else if (key == '7') {
            		kernelSize = 7;
        	} else if (key == '9') {
            		kernelSize = 9;
        	} else if (key == 'B') {
            		kernelSize = 11;
        	} else if (key == 'q') {
            		break; // Sai do loop se a tecla 'q' for pressionada
        	}
    	}

    	// Libera a captura e fecha as janelas
    	cap.release();
    	destroyAllWindows();

    	return 0;
}