Numpy的frompyfunc()是否可以返回图像? [英] Can Numpy's frompyfunc() return an image?

查看:75
本文介绍了Numpy的frompyfunc()是否可以返回图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在复杂平面中构建一个NxN网格,并根据一些规则f(z)为该网格中的每个点z分配RGB颜色.

I want to build a NxN grid in the complex plane, and assign each point z in this grid a RGB color according to some rule f(z).

例如,网格z为

x,y = numpy.ogrid[-1:1:N*1j,-1:1:N*1j]
z = x+y*1j

函数setcolor()是

and the function setcolor() is

def setcolor(z):
    return (r,g,b) triple of z according to some rule

当我要用numpy的frompyfunc()显示f(z)的图像时,会发生我的问题:

My problem occurs when I was going to display the image of f(z) with numpy's frompyfunc():

img = numpy.frompyfunc(setcolor,1,1)(z).astype(np.float)
plt.imshow(img)
plt.show()

生成的imag全部为蓝色(默认情况下为颜色表'jet'),没有错误也没有警告,因此,很显然imshow()已将所有(r,g,b)的三元整数变成单个浮点数,可能是1(或0) ).我猜这是由于astype(np.float)选项引起的,但似乎这是唯一合理的选项.

The resulting imag is all blue (by default colormap 'jet'), no error nor warning, so it's obvious that imshow() has turned all (r,g,b) triple into a single float maybe 1 (or 0). I guess this is because of the astype(np.float) option, but it seems this is the only reasonable option.

当然,一个人可以使用两个for循环来显示img:

Of course one can use two for loops to display img:

for i in range(N):
    for j in range(N):
        img[i,j] = f(z[i,j])

但这不是很有效(我个人认为).我想直接使用fromptfunc().

but this is not very efficient(my own opinion). I want to use the fromptfunc() directly.

那么如何使用frompyfunc()显示此图像?

So how I can display this image with frompyfunc()?

推荐答案

In [588]: x,y=np.ogrid[-1:1:5*1j,-1:1:5*1j]
In [589]: z=x*y*1j
In [590]: def setcolor(z):
    return (z.real,z.imag,np.abs(z))
   .....: 
In [591]: fn=np.frompyfunc(setcolor,1,1)
In [592]: fn(z)
Out[592]: 
array([[None, None, None, None, None],
       [None, None, None, None, None],
       [None, None, None, None, None],
       [None, None, None, None, None],
       [None, None, None, None, None]], dtype=object)

变成.astype(float)的0数组.在这里setcolor只是从复杂输入中获取3个数字的一​​种简单方法.您可以选择更现实的东西.

which turns to an array of 0s with .astype(float). Here setcolor is just a simple way of getting 3 numbers from a complex input. You can choose something more realistic.

但是,如果我们给它正确的out计数,就会得到一个数组元组.

But if we give it the correct out count, we get a tuple of arrays.

In [593]: fn=np.frompyfunc(setcolor,1,3)
In [594]: fn(z)
Out[594]: 
(array([[0.0, 0.0, -0.0, -0.0, -0.0],
        [0.0, 0.0, -0.0, -0.0, -0.0],
        [-0.0, -0.0, 0.0, 0.0, 0.0],
        [-0.0, -0.0, 0.0, 0.0, 0.0],
        [-0.0, -0.0, 0.0, 0.0, 0.0]], dtype=object),
 array([[1.0, 0.5, 0.0, -0.5, -1.0],
        [0.5, 0.25, 0.0, -0.25, -0.5],
        [0.0, 0.0, 0.0, 0.0, 0.0],
        [-0.5, -0.25, 0.0, 0.25, 0.5],
        [-1.0, -0.5, 0.0, 0.5, 1.0]], dtype=object),
 array([[1.0, 0.5, 0.0, 0.5, 1.0],
        [0.5, 0.25, 0.0, 0.25, 0.5],
        [0.0, 0.0, 0.0, 0.0, 0.0],
        [0.5, 0.25, 0.0, 0.25, 0.5],
        [1.0, 0.5, 0.0, 0.5, 1.0]], dtype=object))

可以使用以下命令将其转换为(3,N,N)数组:

It could be turned in to a (3,N,N) array with:

np.array([A.astype(float) for A in fn(z)])

您必须进行转置才能制作(N,N,3)数组.

You'd have to do a transpose to make a (N,N,3) array.

对于这个小样本,它并没有更快

For this small sample it isn't faster

In [599]: timeit np.array([A.astype(float) for A in fn(z)]).transpose([1,2,0])
1000 loops, best of 3: 664 µs per loop

In [603]: %%timeit 
   .....: img=np.zeros((5,5,3),float)
   .....: for i in range(5):
    for j in range(5):
        img[i,j]=setcolor(z[i,j])
   .....: 
1000 loops, best of 3: 316 µs per loop

在其他一些SO问题中,我发现frompyfuncvectorize快,并且在直接迭代上有适度的改进.

In some other SO questions I found that frompyfunc is faster than vectorize, and a modest improvement over direct iteration.

这更快-但却不能完成任务

This is faster - but it doesn't do the job

In [606]: timeit np.frompyfunc(setcolor,1,1)(z).astype(float)
10000 loops, best of 3: 25.6 µs per loop

我选择的setcolor可以直接获取数组z,从而快速创建3d数组.

The setcolor that I chose can take the array z directly, resulting in a fast 3d array creation.

In [608]: timeit np.array([A.astype(float) for A in setcolor(z)]).transpose([1,2,0])
10000 loops, best of 3: 47.1 µs per loop


来自 https://stackoverflow.com/a/29703463/901925 ,这是涉及frompystack的较早答案,我发现vstack是将元组组装成3d数组的更快方法:


From https://stackoverflow.com/a/29703463/901925, an earlier answer involving frompystack, I find that vstack is a faster way to assemble a tuple into a 3d array:

In [616]: timeit np.vstack(fn(z)).astype(float).reshape(3,5,5).transpose([1,2,0])
10000 loops, best of 3: 178 µs per loop

做对了,frompyfunc可以使显式迭代的速度提高2倍,但仍不如直接处理数组的功能好.

So done right, frompyfunc can give about a 2x speedup over explicit iteration, but still not as good as function that handles arrays directly.

这篇关于Numpy的frompyfunc()是否可以返回图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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