Aprendizagem OpenCV: manipulação de imagem básica (5): Suavizar e desfocar

Filtros comuns

Filtragem média

A filtragem de média também é chamada de filtragem linear e seu método principal é a média de vizinhança. O princípio básico da filtragem linear é substituir cada valor de pixel na imagem original pelo valor médio, ou seja, o pixel atual (x, y) a ser processado, selecionar um modelo, que é composto de vários pixels vizinhos, e encontrar o valor de todos os pixels do modelo O valor médio e, em seguida, atribua o valor médio ao pixel atual (x, y), que pode ser expresso pela seguinte fórmula:

f (x, y) = \ frac {1} {m \ vezes n} \ sum_ {i \ in [-n, n]} \ sum_ {j \ in [-m, m]} f (i, j)

Características: O filtro de média em si tem defeitos inerentes, ou seja, não consegue proteger bem os detalhes da imagem, mas também destrói os detalhes da imagem ao mesmo tempo em que a elimina , de modo que a imagem fica borrada e o ruído não pode ser bem removido.

Filtro mediano

A filtragem de mediana é uma tecnologia de processamento de sinal não linear que pode suprimir efetivamente o ruído com base na teoria estatística de classificação. O princípio básico da filtragem de mediana é usar o valor de um ponto em uma imagem digital ou sequência digital com o valor de cada ponto em uma vizinhança desse ponto. Em vez do valor mediano, os valores dos pixels circundantes estão próximos do valor real, eliminando assim os pontos de ruído isolados.

f (x, y) = med (f (xm, yn), ..., f (x, y), ..., f (x + m, y + n))

Características: A filtragem de mediana tem um bom efeito de filtragem no ruído de impulso, especialmente ao filtrar o ruído, ela pode proteger a borda do sinal e evitar que seja borrado. Essas características excelentes não estão disponíveis em métodos de filtragem linear.

Filtragem gaussiana

Distribuição gaussiana bidimensional

A filtragem gaussiana é um filtro de suavização linear, adequado para eliminar o ruído gaussiano e amplamente utilizado no processo de redução de ruído no processamento de imagens. Em termos leigos, a filtragem gaussiana é o processo de média ponderada de toda a imagem.O valor de cada pixel é obtido pela média ponderada dele mesmo e de outros valores de pixel na vizinhança. O peso ponderado vem da distribuição gaussiana bidimensional gerada de acordo com os parâmetros de entrada.

Características: A maior parte do ruído da imagem é ruído gaussiano, portanto, os filtros gaussianos também são amplamente usados. A filtragem gaussiana é um filtro de suavização linear, adequado para eliminar o ruído gaussiano e amplamente utilizado na redução de ruído de imagens.

Filtragem bilateral

O filtro bilateral é um método de filtragem não linear, que combina a proximidade espacial da imagem e a similaridade do valor do pixel, além de considerar a informação espacial e a similaridade da escala de cinza para conseguir a preservação e eliminação de ruído. objetivo.

Domínio espacial S

Domínio de alcance de pixels (domínio de alcance R)

Em geral, quando a diferença de pixels é maior que o limite (ou seja, há uma borda), a filtragem é dividida em duas partes, sem afetar a borda para realizar a filtragem gaussiana. Estruturado conforme a seguinte fórmula:

Características: O filtro bilateral, como o próprio nome indica, tem uma variância gaussiana a mais do que o filtro gaussiano \ delta_d. É uma função de filtro gaussiana baseada na distribuição espacial. Assim, perto da borda, os pixels mais distantes não afetarão muito o valor do pixel na borda. Garanta a preservação dos valores dos pixels próximos à borda. No entanto, como muitas informações de alta frequência são armazenadas, o filtro bilateral não pode filtrar claramente o ruído de alta frequência na imagem colorida e pode apenas filtrar bem as informações de baixa frequência. A filtragem bilateral é freqüentemente usada em aplicações como a bela dermoabrasão.

Introdução API

  • Filtragem média
  • blur(src, dst, Size(5, 5));
    //源图片,生成图片,卷积核大小
    //卷积核大小长选用正方形的奇数边长,也可选用奇数长和宽的矩形,但不常用可根据实际情况选定
  • Filtro mediano
  • medianBlur(src, dst, ksize / 2 * 2 + 1);
    //源图片,生成图片,卷积核大小(默认为方形)
  • Filtragem gaussiana
  • GaussianBlur(src, dst, Size(wkernelSize / 2 * 2 + 1, hkernelSize / 2 * 2 + 1), wsigma, hsigma);
    //源图片,生成图片,核大小(长、宽),长上分布的标准差,宽上分布的标准差
    //同样可以根据需要改变卷积核的长宽,及对应维度上的分布
    
  • Filtragem bilateral
  • bilateralFilter(src, dst, kernelSize / 2 * 2 + 1, sigmaColor, sigmaSpace);
    //源图片,生成图片,卷积核大小,高斯分布标准差,保护边缘阈值

    Quanto mais baixo for definido o limite da borda de proteção, mais detalhes serão retidos e, quanto maior for a configuração, maior será o grau de desfoque.

Prática de código

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

typedef struct _imgPair {
	Mat* src;
	Mat* dst;
	void* Param;
	string winName;
}ImgPair;

typedef struct _gaussianParam {
	int kernelSize;
	int sigma;
}GaussianParam;

typedef struct _bilateralParam {
	int kernelSize;
	int sigmaColor;
	int sigmaSpace;
}BilateralParam;

void on_gaussiankernelBar(int ksize, void* userdata)
{
	ImgPair* pImgPair = (ImgPair*)userdata;
	GaussianParam* gPair = (GaussianParam*)(pImgPair->Param);
	gPair->kernelSize = ksize;

	GaussianBlur(*(pImgPair->src), *(pImgPair->dst), Size(gPair->kernelSize / 2 * 2 + 1, gPair->kernelSize / 2 * 2 + 1), gPair->sigma, gPair->sigma);
	imshow(pImgPair->winName, *(pImgPair->dst));
}


void on_gaussianSigmaBar(int sigma, void* userdata)
{
	ImgPair* pImgPair = (ImgPair*)userdata;
	GaussianParam* gPair = (GaussianParam*)(pImgPair->Param);
	gPair->sigma = double(sigma);

	GaussianBlur(*(pImgPair->src), *(pImgPair->dst), Size(gPair->kernelSize / 2 * 2 + 1, gPair->kernelSize / 2 * 2 + 1), gPair->sigma, gPair->sigma);
	imshow(pImgPair->winName, *(pImgPair->dst));
}




void on_medianSigmaBar(int ksize, void* userdata)
{
	ImgPair* pImgPair = (ImgPair*)userdata;

	medianBlur(*(pImgPair->src), *(pImgPair->dst), ksize / 2 * 2 + 1);
	imshow(pImgPair->winName, *(pImgPair->dst));

}


void on_bilateralDBar(int ksize, void* userdata)
{
	ImgPair* pImgPair = (ImgPair*)userdata;
	BilateralParam* param = (BilateralParam*)(pImgPair->Param);
	bilateralFilter(*(pImgPair->src), *(pImgPair->dst), ksize / 2 * 2 + 1, param->sigmaColor, param->sigmaSpace);
	param->kernelSize = ksize;
	imshow(pImgPair->winName, *(pImgPair->dst));

}



void on_bilateralSigmaSpaceBar(int sigmaSpace, void* userdata)
{
	ImgPair* pImgPair = (ImgPair*)userdata;
	BilateralParam* param = (BilateralParam*)(pImgPair->Param);
	bilateralFilter(*(pImgPair->src), *(pImgPair->dst), param->kernelSize / 2 * 2 + 1, param->sigmaColor, sigmaSpace);
	param->sigmaSpace = sigmaSpace;
	imshow(pImgPair->winName, *(pImgPair->dst));
}

void on_bilateralSigmaColorBar(int sigmaColor, void* userdata)
{
	ImgPair* pImgPair = (ImgPair*)userdata;
	BilateralParam* param = (BilateralParam*)(pImgPair->Param);
	bilateralFilter(*(pImgPair->src), *(pImgPair->dst), param->kernelSize / 2 * 2 + 1, sigmaColor, param->sigmaSpace);
	param->sigmaColor = sigmaColor;
	imshow(pImgPair->winName, *(pImgPair->dst));
}


int main()
{
	Mat src = imread("4.jpg");

	namedWindow("src");
	imshow("src", src);


	/*-------GaussianBlur-----------*/
	Mat GaussianBlurImg;
	namedWindow("GaussianBlurImg");
	GaussianParam gaussianParam = { 5, 1.0 };
	GaussianBlur(src, GaussianBlurImg, Size(5, 5), 1, 1);
	GaussianParam gparam = { 5, 1.0 };
	ImgPair  gaussianPair = { &src, &GaussianBlurImg, &gparam,  "GaussianBlurImg" };

	imshow("GaussianBlurImg", GaussianBlurImg);
	createTrackbar("kernelsize", "GaussianBlurImg", &(gparam.kernelSize), 30, on_gaussiankernelBar, &gaussianPair);
	createTrackbar("sigma", "GaussianBlurImg", &(gparam.kernelSize), 10, on_gaussianSigmaBar, &gaussianPair);

	/*-------medianBlur-----------*/
	Mat MedianBlurImg;
	int kernelSize = 5;
	ImgPair  medianPair = { &src, &MedianBlurImg, nullptr,  "MedianBlurImg" };
	medianBlur(src, MedianBlurImg, 5);
	imshow("MedianBlurImg", MedianBlurImg);
	createTrackbar("kernelsize", "MedianBlurImg", &(kernelSize), 30, on_medianSigmaBar, &medianPair);


	/*---Bilateral-----------------*/
	Mat BilateralFilterImg;
	bilateralFilter(src, BilateralFilterImg, 5, 2, 2);
	BilateralParam bparam = { 5,1,1 };
	ImgPair  bilateralPair = { &src, &BilateralFilterImg, &bparam,  "BilateralFilterImg" };
	imshow("BilateralFilterImg", BilateralFilterImg);
	createTrackbar("kernelsize", "BilateralFilterImg", &(bparam.kernelSize), 30, on_bilateralDBar, &bilateralPair);
	createTrackbar("sigmaspace", "BilateralFilterImg", &(bparam.sigmaSpace), 30, on_bilateralSigmaSpaceBar, &bilateralPair);
	createTrackbar("sigmacolor", "BilateralFilterImg", &(bparam.sigmaColor), 30, on_bilateralSigmaColorBar, &bilateralPair);
	waitKey(0);
}

Acho que você gosta

Origin blog.csdn.net/fan1102958151/article/details/106980216
Recomendado
Clasificación