opencvで最も一般的に使用される2つの非線形フィルターは、メディアンフィルターとバイラテラルフィルターです。
中央値フィルタリング-medianBulr
中央値フィルターは非常に単純です。つまり、特定の領域の中央値であり、各ピクセルのグレー値は、そのポイントの特定の近隣ウィンドウ内のすべてのピクセルのグレー値の中央値に設定されます。この領域は正方形の領域であり、正方形の一辺の長さ、つまり領域の行と列の数はすべて奇数です。中央値は、塩とコショウのノイズに対して優れた抑制効果があります。
API
void medianBlur(
InputArray src,
OutputArray dst,
int ksize
);
(1)InputArrayタイプのsrc、入力画像。1、3、または4チャンネルの画像を入力します。ksizeが3または5の場合、画像の深さはCV_8U、CV_16U、またはCV_32Fである必要があります。より大きな絞りの場合は、CV_8Uのみになります。
(2)OutputArrayタイプのdst、つまりターゲットイメージは、入力イメージと同じサイズとタイプを持ちます。
(3)int型のksize、線形アパーチャサイズ。奇数で1より大きくなければなりません。例:3、5、7…。
コード
#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat src, dst;
src = imread("C:/Users/86176/Pictures/pics/house.jpg");
if (!src.data)
{
cout << "could not load image !";
return -1;
}
imshow("src", src);
//中值滤波
medianBlur(src, dst, 7);
imshow("medianBlur_src", dst);
waitKey(0);
return 0;
}
効果
バイラテラルフィルター-bilateralFilter
バイラテラルフィルタリングは、画像の空間的近接性とピクセル値の類似性を組み合わせ、空間情報とグレースケールの類似性を考慮してエッジの保存とノイズ除去の目的を達成する妥協処理です。それは単純で、反復的ではなく、部分的です。バイラテラルフィルターの利点は、エッジの保存に使用できることです。一般に、ノイズ除去に過去に使用されたウィーナーフィルターまたはガウスフィルターは、エッジをより明確にぼかし、高周波の詳細に対する保護効果は明らかではありません。
バイラテラルフィルターは、ガウスフィルターよりもガウス分散シグマdが1つ多く、空間分布に基づくガウスフィルター関数です。したがって、エッジの近くでは、遠くのピクセルがエッジのピクセル値にあまり影響を与えません。ピクセルの保存を確認してください。エッジ近くの値。
ただし、保存する高周波情報が多すぎるため、バイラテラルフィルターではカラー画像の高周波ノイズをきれいに除去できず、低周波情報しかうまくフィルタリングできません。
中央には、空間内の画像の重みのガウス分布があります。
この画像は、空間カーネルと、バイラテラルフィルタリングの演算子として使用される範囲カーネルで構成されています。
- 空間コア:スペースの観点から、画像は3 x3または5x 5で、それぞれに重みがあります
- 値範囲カーネル:ピクセル値用です。ピクセル値の差が特定の範囲内にある場合はぼやけます。ギャップが大きすぎる場合はぼやけないため、エッジを保持できます。
- したがって、両側ブラーには2つのパラメーターを入力する必要があります。1つは空間ドメインのウィンドウサイズで、もう1つは値ドメインのウィンドウサイズです。
総括する:
平均ぼけは、エッジピクセル情報の損失の欠陥を克服することはできません。その理由は、平均フィルターが平均重量に基づいているためです。
ガウスぼかしはこの欠陥を部分的に克服しますが、ピクセル値の違いが考慮されていないため、完全に回避することはできません(おそらく隣接するピクセル値は0と255です)
ガウスバイラテラルブラー-エッジ情報の損失を回避し、画像の輪郭を保存するエッジ保存のフィルタリング方法です(隣接するピクセル間の差のしきい値を考慮すると、エッジを保存できます)
API
void bilateralFilter(
InputArray src,
OutputArray dst,
int d,
double sigmaColor,
double sigmaSpace,
int borderType = BORDER_DEFAULT
);
(1)InputArrayタイプのsrc、入力画像。この関数はチャネルを独立して処理し、任意の数のチャネルの画像を処理できますが、処理される画像の深度はCV_8U、CV_16U、CV_16S、CV_32F、およびCV_64Fのいずれかである必要があることに注意してください。
(2)OutputArrayタイプのdst、つまりターゲットイメージは、入力イメージと同じサイズとタイプを持ちます。
(3)Intタイプd、フィルタリングプロセスで使用される各ピクセル近傍の直径。正でない場合は、sigmaSpaceから計算されます。
(4)ダブルタイプsigmaColor
色空間のフィルターシグマ。パラメータ値が大きいほど、ピクセル近傍(sigmaSpaceを参照)のより多くの色が混合され、半等色領域が大きくなることを意味します。(5)sigmaSpaceをダブルタイプし、座標空間でシグマをフィルタリングします。パラメータ値が大きいほど、色が十分に近い限り、遠くのピクセルが互いに影響し合うことを意味します(sigmaColorを参照)。dが0より大きい場合、sigmaSpaceに関係なく近傍のサイズを指定します。それ以外の場合、dはsigmaSpaceに比例します。
(6)int型のborderTypeは、画像の外側のピクセルの境界モードを推定するために使用されます。詳細については、cv :: BorderTypesを参照してください。
コード
#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat src, dst;
src = imread("C:/Users/86176/Pictures/pics/house1.jpg");
if (!src.data)
{
cout << "could not load image !";
return -1;
}
imshow("src", src);
//双边滤波
bilateralFilter(src, dst, 15, 150, 3);
imshow("bilateralFilter_src", dst);
waitKey(0);
return 0;
}
効果
ご覧のとおり、エッジの保持は非常にうまく行われています