Skip to content

Instantly share code, notes, and snippets.

@johnnyferreiradev
Created April 30, 2019 20:27
Show Gist options
  • Save johnnyferreiradev/b3391cc8db4dd324fa8c23834bd51669 to your computer and use it in GitHub Desktop.
Save johnnyferreiradev/b3391cc8db4dd324fa8c23834bd51669 to your computer and use it in GitHub Desktop.
Filtro Gaussiano com Convolução Genérica + exemplo de utilização
#include <QCoreApplication>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat convoluirGenerica(Mat& img, float **masc, int M, int N){
// output é a variavel responsavel por realizar o somatorio da convolução
float output=0;
Mat resp = img.clone();
int m=(M-1)/2; // Esse ajuste faz com que a matriz não ultrapasse o seu limite maximo.
int n=(N-1)/2;
// inicializando todos os valores da imagem resultante para zero
for (int x=0; x<img.rows;x++){
for (int y=0; y<img.cols; y++){
resp.at<uchar>(x,y) = 0;
}
}
int i=0,j=0;
// Os dois for mais externos são responsáveis por percorrer toda a imagem
for (int x=m; x<img.rows-m;x++){
for (int y=n; y<img.cols-n; y++) {
output=0; // Cada vez que a mascara se movimentar dentro da imagem, um novo somatorio deve ser obtido
// Os dois for() mais internos são responsáveis por movimentar a mascara
for (int ml=-m; ml<=m; ml++){ // Realiza-se o somatorio de -m (linhas) ate m.
for (int mc=-n; mc<=n; mc++) { // Realiza-se o somatorio de -m (linhas) ate m.
// Cada pixel de uma determinada vizinhança é multiplicado por um valor da mascara
// Essa multiplicação é feita de forma que um pixel é sempre multiplicado pelo valor
// correspondementente inverso na mascara
// Apos a multiplicação os valores são acrescidos a output
output += img.at<uchar>(x-mc,y-ml) * masc[mc+ m][ml+n];
// Truncamento responsável por evitar o overflow e underflow
if(output>255)
output=255;
if(output<0)
output=0;
}
}
// O pixel central da imagem recebe o resultado da convolução
resp.at<uchar>(x,y) = (int)output;
}
}
return (resp);
}
void criarGaussiano(float **mascara, int largura, int altura){
// adotando desvio padrão = 1,0
float sigma = 1.0;
float r, s = 2.0 * sigma * sigma;
// variável para somatório
float soma = 0.0;
// delimitadores para máscara simétrica com média em (0,0)
int m = (largura-1)/2;
int n = (altura-1)/2;
// geração dos valores da máscara
for (int x = -m; x <= m; x++) {
for (int y = -n; y <= n; y++) {
r = sqrt(x * x + y * y);
mascara[x + m][y + n] = (exp(-(r * r) / s)) / (M_PI * s);
soma += mascara[x + m][y + n];
}
}
// normalizando a máscara
for (int i = 0; i < largura; ++i)
for (int j = 0; j < altura; ++j)
mascara[i][j] /= soma;
}
Mat filtroGauss(Mat img, int x, int y){
Mat processada = img.clone();
// Cria dinamicamente uma matriz com as dimenções passadas por parametro
float **Kernel;
Kernel = (float**) malloc (x * sizeof(float*) );
for (int i=0; i<x; i++){
Kernel[i] = (float*) malloc (y * sizeof(float) );
}
criarGaussiano(Kernel, x, y); // Atribuição de valores a mascara
processada = convoluirGenerica(img, Kernel, x, y); // Processamento da imagem
return processada;
}
int main(){
Mat img = imread("/home/johnny/Documentos/Sistemas de Informacao/S4/PDI/Imagens/lenna.jpeg", 0);
Mat filtrada = img.clone();
filtrada = filtroGauss(img, 9, 9);
imshow("screen1", img); imshow("screen2",filtrada);
waitKey(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment