Python中的图像梯度向量场 [英] Image Gradient Vector Field in Python

查看:914
本文介绍了Python中的图像梯度向量场的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取这个matlab问题).

这是原始图像:

这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
import Image
from PIL import ImageFilter

I = Image.open('test.png').transpose(Image.FLIP_TOP_BOTTOM)
I = I.filter(ImageFilter.BLUR)
p = np.asarray(I)
w,h = I.size
y, x = np.mgrid[0:h:500j, 0:w:500j]

dy, dx = np.gradient(p)
skip = (slice(None, None, 3), slice(None, None, 3))

fig, ax = plt.subplots()
im = ax.imshow(I, extent=[x.min(), x.max(), y.min(), y.max()])
ax.quiver(x[skip], y[skip], dx[skip], dy[skip])

ax.set(aspect=1, title='Quiver Plot')
plt.show()

这是结果:

问题在于向量似乎不正确.当您放大图像时,这一点会变得更加清晰:

为什么某些矢量会按预期指向中心,而其他矢量却没有指向中心?

也许调用np.gradient的结果有问题?

解决方案

我认为您的奇怪结果至少部分是因为p的类型为uint8.即使是numpy diff,也明显导致此dtype数组的值不正确.如果通过将p的定义替换为以下内容来转换为有符号整数:p = np.asarray(I).astype(int8),则diff的结果正确.以下代码为我提供了一个合理的字段,

import numpy as np
import matplotlib.pyplot as plt
import Image
from PIL import ImageFilter

I = Image.open('./test.png')
I = I.filter(ImageFilter.BLUR)
p = np.asarray(I).astype('int8')
w,h = I.size
x, y = np.mgrid[0:h:500j, 0:w:500j]

dy, dx = np.gradient(p)
skip = (slice(None, None, 3), slice(None, None, 3))

fig, ax = plt.subplots()
im = ax.imshow(I.transpose(Image.FLIP_TOP_BOTTOM), 
               extent=[x.min(), x.max(), y.min(), y.max()])
plt.colorbar(im)
ax.quiver(x[skip], y[skip], dx[skip].T, dy[skip].T)

ax.set(aspect=1, title='Quiver Plot')
plt.show()

这给出了以下内容:

并关闭它,就像您期望的那样,

I am trying to get the Gradient Vector Field of an image using Python (similar to this matlab question).

This is the original image:

Here is my code:

import numpy as np
import matplotlib.pyplot as plt
import Image
from PIL import ImageFilter

I = Image.open('test.png').transpose(Image.FLIP_TOP_BOTTOM)
I = I.filter(ImageFilter.BLUR)
p = np.asarray(I)
w,h = I.size
y, x = np.mgrid[0:h:500j, 0:w:500j]

dy, dx = np.gradient(p)
skip = (slice(None, None, 3), slice(None, None, 3))

fig, ax = plt.subplots()
im = ax.imshow(I, extent=[x.min(), x.max(), y.min(), y.max()])
ax.quiver(x[skip], y[skip], dx[skip], dy[skip])

ax.set(aspect=1, title='Quiver Plot')
plt.show()

This is the result:

The problem is that the vectors seem to be incorrect. This point gets more clear when you zoom in the image:

Why do some of the vectors point to the center as expected, while others do not?

Maybe there is an issue with the result of the call to np.gradient?

解决方案

I think your strange results are, at least in part, because p is of type uint8. Even numpy diff results in clearly incorrect values for an array of this dtype. If you convert to signed integer by replacing the definition of p with the following: p = np.asarray(I).astype(int8) then the results of diff are correct. The following code gives me what looks like a reasonable field,

import numpy as np
import matplotlib.pyplot as plt
import Image
from PIL import ImageFilter

I = Image.open('./test.png')
I = I.filter(ImageFilter.BLUR)
p = np.asarray(I).astype('int8')
w,h = I.size
x, y = np.mgrid[0:h:500j, 0:w:500j]

dy, dx = np.gradient(p)
skip = (slice(None, None, 3), slice(None, None, 3))

fig, ax = plt.subplots()
im = ax.imshow(I.transpose(Image.FLIP_TOP_BOTTOM), 
               extent=[x.min(), x.max(), y.min(), y.max()])
plt.colorbar(im)
ax.quiver(x[skip], y[skip], dx[skip].T, dy[skip].T)

ax.set(aspect=1, title='Quiver Plot')
plt.show()

This gives the following:

and close up this looks like you'd expect,

这篇关于Python中的图像梯度向量场的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆