8

サイズ 5x5 および 7x7 の OpenCV のソーベル フィルターを使用して、画像の導関数を計算しています。

OpenCV でのサイズ 5x5 および 7x7 のソーベル フィルターのカーネル値を教えてください。Google 検索を行うと、さまざまなカーネルが表示されます。

5 x 5 の例を次に示します。

1. 分離可能

2   1   0   -1  -2
4   8   0   -4  -8
6  12   0   -12 -6
4   8   0   -4  -8
2   1   0   -1  -2

2. 分離不可能なもの

2   1   0   -1  -2
4  10   0   -4  -10
7  17   0   -17 -7
4  10   0   -4  -10
2   1   0   -1  -2

3. 不可解な不可分

2   1   0   -1  -2
3   2   0   -2  -3
4   3   0   -3  -4
3   2   0   -2  -3
2   1   0   -1  -2
4

2 に答える 2

16

getDerivKernelsOpenCV が何を使用しているかを実際に確認したい場合は、Sobel フィルターのカーネル係数を決定するために使用できます。あなたがする必要があるのは、あなたが望む方向とあなたが望むマスクのサイズを指定することです. そのため、カーネルのサイズごとに 2 つの方向があるため、これを 4 回呼び出す必要があります。

ただし、返されるのは、を介して分離可能な 2D フィルタリングを実行するために使用できるソーベル フィルターを表す、水平、 x、垂直 、 1D カーネルです。カーネル自体を実際に見たい場合は、 から返されるとカーネルの間の外積を取るだけです。ysepFilter2DxygetDerivKernels

Python の OpenCV インターフェイスを使用して 5 x 5 xyおよび 7 x 7xyカーネルを表示する簡単な例を次に示します。

In [1]: import numpy as np

In [2]: import cv2

In [3]: sobel5x = cv2.getDerivKernels(1, 0, 5)

In [4]: np.outer(sobel5x[0], sobel5x[1])
Out[4]: 
array([[ -1.,  -4.,  -6.,  -4.,  -1.],
       [ -2.,  -8., -12.,  -8.,  -2.],
       [  0.,   0.,   0.,   0.,   0.],
       [  2.,   8.,  12.,   8.,   2.],
       [  1.,   4.,   6.,   4.,   1.]], dtype=float32)

In [5]: sobel5y = cv2.getDerivKernels(0, 1, 5)

In [6]: np.outer(sobel5y[0], sobel5y[1])
Out[6]: 
array([[ -1.,  -2.,   0.,   2.,   1.],
       [ -4.,  -8.,   0.,   8.,   4.],
       [ -6., -12.,   0.,  12.,   6.],
       [ -4.,  -8.,   0.,   8.,   4.],
       [ -1.,  -2.,   0.,   2.,   1.]], dtype=float32)

In [7]: sobel7x = cv2.getDerivKernels(1, 0, 7)

In [8]: np.outer(sobel7x[0], sobel7x[1])
Out[8]: 
array([[  -1.,   -6.,  -15.,  -20.,  -15.,   -6.,   -1.],
       [  -4.,  -24.,  -60.,  -80.,  -60.,  -24.,   -4.],
       [  -5.,  -30.,  -75., -100.,  -75.,  -30.,   -5.],
       [   0.,    0.,    0.,    0.,    0.,    0.,    0.],
       [   5.,   30.,   75.,  100.,   75.,   30.,    5.],
       [   4.,   24.,   60.,   80.,   60.,   24.,    4.],
       [   1.,    6.,   15.,   20.,   15.,    6.,    1.]], dtype=float32)

In [9]: sobel7y = cv2.getDerivKernels(0, 1, 7)

In [10]: np.outer(sobel7y[0], sobel7y[1])
Out[10]: 
array([[  -1.,   -4.,   -5.,    0.,    5.,    4.,    1.],
       [  -6.,  -24.,  -30.,    0.,   30.,   24.,    6.],
       [ -15.,  -60.,  -75.,    0.,   75.,   60.,   15.],
       [ -20.,  -80., -100.,    0.,  100.,   80.,   20.],
       [ -15.,  -60.,  -75.,    0.,   75.,   60.,   15.],
       [  -6.,  -24.,  -30.,    0.,   30.,   24.,    6.],
       [  -1.,   -4.,   -5.,    0.,    5.,    4.,    1.]], dtype=float32)

カーネルは正規化されていないことに注意してください。これらをフィルタリングに使用する場合は、おそらくカーネルを正規化する必要があります。getDerivKernelsマスクを正規化できるフラグがあります。

また、特定のサイズの 1 つのマスクが別のマスクの転置であることに注意してください。これは、特定の方向のエッジを検出する場合に意味があります。


完全を期すために、上記の Python コードの C++ バージョンを次に示します。コードをコンパイルするには、これをファイルに配置します...呼び出してtest.cppから、ターミナルでこれを実行します。

g++ -Wall -g -o test test.cpp `pkg-config --cflags --libs opencv`

コンパイルしたら、 を使用してプログラムを実行し./testます。


#include <cv.h>

using namespace std;
using namespace cv;

int main() {

    // For the kernels
    Mat sobelX, sobelY;

    // 5 x 5 - x direction
    getDerivKernels(sobelX, sobelY, 1, 0, 5, false, CV_32F);
    cout << "sobel5x = " << endl << " " << sobelX*sobelY.t() << endl << endl;

    // 5 x 5 - y direction
    getDerivKernels(sobelX, sobelY, 0, 1, 5, false, CV_32F);
    cout << "sobel5y = " << endl << " " << sobelX*sobelY.t() << endl << endl;

    // 7 x 7 - x direction
    getDerivKernels(sobelX, sobelY, 1, 0, 7, false, CV_32F);
    cout << "sobel7x = " << endl << " " << sobelX*sobelY.t() << endl << endl;

    // 7 x 7 - y direction
    getDerivKernels(sobelX, sobelY, 0, 1, 7, false, CV_32F);
    cout << "sobel7y = " << endl << " " << sobelX*sobelY.t() << endl << endl;

    return 0;
}

xyカーネルはどちらも列ベクトルであるため、yベクトルを転置して、外積を計算する行ベクトルになるようにする必要があることに注意してください。

于 2015-07-30T17:13:08.483 に答える