目次
エッジ処理を使用する理由
- カーネルが3x 3の場合、画像の周りのピクセルの円はスキャンできません。
- カーネルが(2 k + 1)x(2 k + 1)の場合、画像の周りのk個の円のピクセルはスキャンできません。
下の図に示すように、
5 x 5カーネルでスキャンできる最大の領域は、赤いボックスで囲まれ
た領域です。画像の周囲の2ピクセルをスキャンする方法はありません。
したがって、画像の周囲の2ピクセルのエッジを処理する必要があります。
一部のアルゴリズムでは、元の画像の周囲に2ピクセルが追加され、畳み込み後に削除されます。
デフォルトのエッジ処理
opencvで境界を処理する方法
畳み込みの開始前にエッジピクセルを追加します。塗りつぶされたピクセル値は0またはRGBブラックです。たとえば、3x3は、画像のエッジが処理されるように、各側の1ピクセルのエッジを塗りつぶし、その後これらのエッジを削除します。畳み込みプロセス。
openCVのデフォルトの処理方法は、BORDER_DEFAULTであり、一般的に使用されるものは次のとおりです。
- BORDER_CONSTANT-指定されたピクセル値でエッジを塗りつぶします
- BORDER_REPLICATE-エッジピクセルを既知のエッジピクセル値で埋めます。
- BORDER_WRAP –反対側のピクセルを使用してパディングを補正します
畳み込み演算のために境界を処理できないという問題があるため、前のレッスンでカスタム線形フィルターによって使用されたAPIの最後のパラメーターborderTypeを使用できます。このパラメーターを使用すると、より一般的に使用される処理方法をいくつか使用できます。一般的に使用される境界タイプは次のとおりです。
enum BorderTypes {
BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb`
BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg`
BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
BORDER_TRANSPARENT = 5, //!< `uvwxyz|absdefgh|ijklmno`
BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_ISOLATED = 16 //!< do not look outside of ROI
};
カスタムエッジ処理
我々はエッジ処理を実行する必要がある理由上記の説明を通じて、我々は知っている、と我々はまた、デフォルトのエッジの処理方法について話しましたが、デフォルトのエッジの処理方法は、唯一の問題を解決できる
ことを画像エッジが原因な畳み込みなどの操作を処理することはできません。と言うことです、別の1つのパラメータは我々のニーズを満たすことができない。例えば、我々はエッジの複数の位置を処理するだけでなく、未処理の位置。デフォルトの方法は、当社の要件を満たしていない場合、我々はエッジをカスタマイズする必要があります私たち自身の処理方法。
API
次のAPIを使用します
void copyMakeBorder(
InputArray src,
OutputArray dst,
int top,
int bottom,
int left,
int right,
int borderType,
const Scalar& value = Scalar()
);
(1)InputArrayタイプのsrc、入力画像。
(2)OutputArrayタイプのdst、出力イメージ、イメージタイプは入力イメージと同じで、サイズは次のとおりです。Size(src.cols + left + right、src.rows + top + bottom)。
(3)トップ型int、
(4)int型の下部、
(5)int型の左側、
(6)Intタイプ右、上記の4つのパラメーターは、画像に追加されるエッジのサイズです。
(7)int型のborderType、エッジの型。borderInterpolateを参照してください。
(8)スカラー型の値、borderType == BORDER_CONSTANTの場合の境界値
注:このメソッドは、画像のサイズを変更します。
コード表示
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat src;
Mat dst;
src = imread("C:/Users/86176/Pictures/pics/lena(1).tiff");
if (!src.data)
{
cout << "could not load image !";
return -1;
}
namedWindow("input img", CV_WINDOW_AUTOSIZE);
namedWindow("output img", CV_WINDOW_AUTOSIZE);
imshow("input img", src);
int top = (int)(0.05 * src.rows);
int botton = (int)(0.05 * src.rows);
int left = (int)(0.05 * src.cols);
int right = (int)(0.05 * src.cols);
RNG rng(12345);
int borderType = BORDER_DEFAULT;
int c = 0;
while (1)
{
c = waitKey(500);
if ((char)c == 27)
{
break;
}
if ((char)c == 'r')
{
borderType = BORDER_REPLICATE;
}
else if ((char)c == 'v')
{
borderType = BORDER_WRAP;
}
else if ((char)c == 'c')
{
borderType = BORDER_CONSTANT;
}
else
{
borderType = BORDER_DEFAULT;
}
Scalar color = Scalar(0 ,0 ,255);
copyMakeBorder(src, dst, top, botton, left, right, borderType, color);
imshow("output img", dst);
}
waitKey(0);
return 0;
}
効果
BORDER_DEFAULT
opencvでの自動エッジ処理
BORDER_REPLICATE
周囲のピクセルで塗りつぶします
BORDER_WRAP
反対側のピクセルで塗りつぶします
BORDER_CONSTANT
指定された色で塗りつぶします
結論
copyMakeBorder関数は、画像のエッジを増やすことができます
画像畳み込みのアプリケーションでは、エッジ処理がより重要です
。filter2D、GussianBlurなどを試してみてください。
//filter2D(img, src, -1, kernel, Point(-1, -1),0,BORDER_DEFAULT);
//filter2D(img, src, -1, kernel, Point(-1, -1),0,BORDER_CONSTANT);
//filter2D(img, src, -1, kernel, Point(-1, -1),0,BORDER_REPLICATE);
//filter2D(img, src, -1, kernel, Point(-1, -1),0,BORDER_WRAP);