3

私はエッジ検出器について自分自身に教えています。OpenCVを使用してfilter2D、に似た独自の勾配計算機を実装しようとしていcv2.Sobel()ます。OpenCVへのPythonインターフェースで、cv2.filter2D()ユーザーがカスタムフィルターを使用して画像を畳み込むことができます。OpenCVの命名法では、このフィルターは「カーネル」と呼ばれます。

MITの歩行者データセットからの画像(per00001.png)を使用すると、妥当な外観の出力が生成されることがわかります。(コードは下にあり、出力画像はここにあります。)cv2.Sobel()

#OpenCV's Sobel code (outputs nice-looking gradient)
import cv2, numpy
img = cv2.imread("./per00001.png")

gradientX = cv2.Sobel(img, -1, 1, 0)

compression_params = [cv2.cv.CV_IMWRITE_PNG_COMPRESSION, 9]
cv2.imwrite("gradientX.png", gradientX, compression_params)

↑良い


↓壊れた

自分のSobel()ようなコード(以下)を実装しようとすると、真っ黒な画像が表示されます。horizontalSobelMtx問題は、渡したカーネルパラメータ()のデータ型にあると推測していますcv2.filter2D()。ただし、のカーネルデータ型に関するドキュメントは見つかりませんでしたcv2.filter2D()

#Custom Sobel code (outputs all-black image)
import cv2, numpy
img = cv2.imread("./per00001.png")

horizontalSobelMtx = [[-1,0,1],[-2,0,2],[-1,0,1]]
horizontalSobelMtx = numpy.asanyarray(horizontalSobelMtx) #guessing about appropriate datatype.
gradientX_customSobel = cv2.filter2D(img, -1, horizontalSobelMtx)

compression_params = [cv2.cv.CV_IMWRITE_PNG_COMPRESSION, 9]
cv2.imwrite("gradientX_customSobel.png", gradientX_customSobel, compression_params)

だから、ここに私の質問があります:

1)パラメータcv2.filter2D(..., kernel, ...)にどのようなデータ型が必要ですか?kernel

2)kernelここでのデータ型に問題がない場合、カスタムSobelコードが空白の画像を出力する原因は何ですか?

4

2 に答える 2

4

畳み込みカーネルの係数は、常に浮動小数点数である必要があります。これは、そのマトリックスを割り当てるときにCV_32FC1を使用する必要があることを意味します。この特定の例では、次のことを試してください。

horizontalSobelMtx = [[-1,0,1],[-2,0,2],[-1,0,1]]
horizontalSobelMtx = numpy.asanyarray(horizontalSobelMtx, np.float32)
于 2013-08-26T23:32:20.393 に答える
1

私も同じ問題を抱えていましたが、部分的な答えがあると思います。基本的に、カーネルに重みを付ける必要があります。フィルタアルゴリズムが機能する方法は、フィルタを取得して乗算し、すべての値を合計して新しい値として使用することです。重要なのは追加部分です。8つの異なる値(一部は負、一部は正)を追加すると、通常は多数になり、表示され、黒(または私の場合はすべて白)で表示されます。したがって、追加を補う必要があります。カーネル内のすべての値をカーネルのサイズ/面積で割ります。こちらの例を参照して、次の行に注意してください

  kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);

それらはすべてをkernel_sizeの2乗で除算します。

私自身、私はこれを行いました、そしてそれは助けになりました(何かが示されました)が、それは洗い流されたので、私はこれを私のコードに追加することによって私の完璧な体重を見つけました:

 int d2weight = 1;
 //... start loop, make your Mat kernel
 kernel = kernel / d2weight;  //put right before your filter2d() call
 createTrackbar("kernel", "kernel", &d2weight, 255, NULL);

そして、バーをいじって、d2weight=140のあたりで私の写真が「ポップ」して表示されました。

于 2012-12-20T06:25:12.160 に答える