画像にSobelフィルターを適用して、scipyを使用してエッジを検出しようとしています。私はWindows7 Ultimate(64ビット)でPython 3.2(64ビット)とscipy 0.9.0を使用しています。現在、私のコードは次のとおりです。
import scipy
from scipy import ndimage
im = scipy.misc.imread('bike.jpg')
processed = ndimage.sobel(im, 0)
scipy.misc.imsave('sobel.jpg', processed)
何が間違っているのかわかりませんが、処理された画像は本来あるべき姿とはまったく異なります。画像「bike.jpg」はグレースケール(モード「L」ではなく「RGB」)画像であるため、各ピクセルには1つの値しか関連付けられていません。
残念ながら、私はまだここに画像を投稿することはできません(十分な評判がありません)が、以下のリンクを提供しました:
元の画像(bike.jpg): http://s2.postimage.org/64q8w613j/bike.jpg
Scipy Filtered(sobel.jpg): http://s2.postimage.org/64qajpdlb/sobel.jpg
期待される出力: http://s1.postimage.org/5vexz7kdr/normal_sobel.jpg
私は明らかにどこかで間違っています!誰か教えてくれませんか。ありがとう。
1)より高い精度を使用します。 2)ゼロ軸に沿った導関数の近似値のみを計算しています。 2D Sobel演算子については、 Wikipedia で説明されています。このコードを試してください:
import numpy
import scipy
from scipy import ndimage
im = scipy.misc.imread('bike.jpg')
im = im.astype('int32')
dx = ndimage.sobel(im, 0) # horizontal derivative
dy = ndimage.sobel(im, 1) # vertical derivative
mag = numpy.hypot(dx, dy) # magnitude
mag *= 255.0 / numpy.max(mag) # normalize (Q&D)
scipy.misc.imsave('sobel.jpg', mag)
私はcgohlkeの答えにコメントできなかったので、私は彼の答えを訂正して繰り返しました。パラメータは垂直導関数に使用され、1は水平導関数に使用されます(画像配列の最初の軸はy /です)垂直方向-行、2番目の軸はx /水平方向-列)。間違った場所で間違いを探すのに1時間もかかったので、他のユーザーに警告したかっただけです。
import numpy
import scipy
from scipy import ndimage
im = scipy.misc.imread('bike.jpg')
im = im.astype('int32')
dx = ndimage.sobel(im, 1) # horizontal derivative
dy = ndimage.sobel(im, 0) # vertical derivative
mag = numpy.hypot(dx, dy) # magnitude
mag *= 255.0 / numpy.max(mag) # normalize (Q&D)
scipy.misc.imsave('sobel.jpg', mag)
または使用できます:
def sobel_filter(im, k_size):
im = im.astype(np.float)
width, height, c = im.shape
if c > 1:
img = 0.2126 * im[:,:,0] + 0.7152 * im[:,:,1] + 0.0722 * im[:,:,2]
else:
img = im
assert(k_size == 3 or k_size == 5);
if k_size == 3:
kh = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype = np.float)
kv = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], dtype = np.float)
else:
kh = np.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 = np.float)
kv = np.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 = np.float)
gx = signal.convolve2d(img, kh, mode='same', boundary = 'symm', fillvalue=0)
gy = signal.convolve2d(img, kv, mode='same', boundary = 'symm', fillvalue=0)
g = np.sqrt(gx * gx + gy * gy)
g *= 255.0 / np.max(g)
#plt.figure()
#plt.imshow(g, cmap=plt.cm.gray)
return g
詳細については、 ここ を参照してください。