无法在python中将图像作为数组关注

所以我使用这个非常简单的图像来理解图像如何存储在一个数组中以及如何操作它.
《无法在python中将图像作为数组关注》

SIDE NOTE
Can anyone suggest me a book/blog which starts with these basics, as most of them skipping this part and even though trivial but I cant
progress with these small nuances eating my head

它的8×8像素图像,在左上角的像素中有一个点.

#import modules
import matplotlib.pyplot as plt
from PIL import Image
%matplotlib inline
import numpy as np

#Load image as array
i=Image.open("dot.png")
iar=np.asarray(i)

现在进行分析,首先我开始显示一些数组,然后我终于显示“dot.png”

链接到dot.png图像(使用ctrl s将其保存为非常小的2×2像素,因此不可见)https://i.stack.imgur.com/y2ot9.png
《无法在python中将图像作为数组关注》

plt.imshow([0])
TypeError: Invalid dimensions for image data

plt.imshow([[0]])

《无法在python中将图像作为数组关注》

plt.imshow([[255]])

《无法在python中将图像作为数组关注》

 plt.imshow([[255,0]])

《无法在python中将图像作为数组关注》

plt.imshow([[255,0,128]])

《无法在python中将图像作为数组关注》

plt.imshow([[255,0],[23,128]])

《无法在python中将图像作为数组关注》

plt.imshow(iar[0])

《无法在python中将图像作为数组关注》

plt.imshow(iar[0:1])

《无法在python中将图像作为数组关注》

# Checking attributes of iar[0]
subset1=iar[0]
subset1.shape
Out[144]: (8L, 4L)
In [140]:iar[0]
Out[140]: 
array([[  0,   0,   0, 255],
   [255, 255, 255, 255],
   [255, 255, 255, 255],
   [255, 255, 255, 255],
   [255, 255, 255, 255],
   [255, 255, 255, 255],
   [255, 255, 255, 255],
   [255, 255, 255, 255]], dtype=uint8)

# Checking attributes of iar[0:1]
subset2=iar[0:1]
subset2.shape
Out[146]: (1L, 8L, 4L)
In [142]:iar[0:1]
Out[141]: 
array([[[  0,   0,   0, 255],
    [255, 255, 255, 255],
    [255, 255, 255, 255],
    [255, 255, 255, 255],
    [255, 255, 255, 255],
    [255, 255, 255, 255],
    [255, 255, 255, 255],
    [255, 255, 255, 255]]], dtype=uint8)

我的问题: –

>为什么plt.imshow([0])失败但是plt.imshow([[0]])有效?
>为什么plt.imshow([[0]])& plt.imshow([[255]])只显示蓝色?尽管0并不意味着蓝色,也不意味着蓝色
255表示蓝色.
>这些图像中的像素在哪里. plt.imshow([[0]])显示大小为1×1的图像.它是一个像素图像?如果是的话
plt.imshow([[255,0]])表示2个像素?
>为什么颜色模糊不清楚,我没有提供有关alpha /模糊的任何信息.但仍然
plt.imshow([[255,0,128]])显示所有颜色模糊
边界.这里发生了什么事 ?
>为什么iar [0]即将作为彩色图像出现,即使dot.png只是黑色&白色图像.但是iar [0:1]显示了dot.png的第一行,就像它存储在那里一样.

最佳答案 好的,所以你的一些问题是关于
pyplot.imshow的行为.

imshow显示一个图像,并将“阵列状”作为参数,形状为(n,m)(对于灰度图像),(n,m,3)(对于彩色图像)或(n ,m,4)(对于具有透明度或alpha信息的彩色图像).

当你执行plt.imshow([0])时,你传递一个形状为(1,)的参数,这就是你得到错误的原因.列表[0]是一维的,而不是两个,因此imshow无法显示.相比之下,[[0]]是一个二维数组,代表一个像素,因此可以显示.

[[0]]和[[255]]都将显示为蓝色方块.这是因为matplotlib对灰度图像的像素值进行了颜色映射.颜色映射意味着matplotlib在您传递的数据中找到值的范围,并将最低值设为一种颜色,将最高值设为另一种颜色,将地图之间的所有值设置为某些颜色范围设计为漂亮,或者在解释数据时很有用.如果您的图像只有一个像素,则没有颜色范围,因此整个图像将以相同的颜色显示.请注意,如果没有为参数cmap指定不同的值,则matplotlib默认使用jet colourmap.

plt.imshow([[255,0]])显示两像素图像;您传递的数组有一行有两列. Matplotlib将其显示为两种颜色:我们可以看到红色表示高(255),蓝色表示低(0).

图像模糊,因为matplotlib插入图像数据.你可以通过给插值参数的值赋予imshow来改变这种行为(matplotlib默认使用’bilinear’,它会让你获得“抗锯齿”外观).

plt.imshow([[255,0]], interpolation='none')

《无法在python中将图像作为数组关注》

接下来,您将显示一个3像素的灰度图像([[255,0,128]]).这显示为从红色到蓝色到绿色的渐变;这些颜色再次从喷射颜色图中获取(红色为高,绿色为中,蓝色为低). [[255,128,128]]将为红色,蓝色,蓝色,因为此数据的范围是128到255,因此128将是新的低(蓝色).

好的,最后,我们来看你的8×8图像.您的PNG图像可能只包含黑白像素,但它以RGB格式存储.我们可以看到这个,例如,使用ImageMagick

$identify ~/Downloads/y2ot9.png
/home/user/Downloads/y2ot9.png PNG 8x8 8x8+0+0 8-bit sRGB 138B 0.010u 0:00.059

所以这意味着每个像素由三个字节表示(红色,绿色和蓝色). PIL在RGBA模式下打开它,为alpha通道添加另一个字节:

>>> from PIL import Image
>>> import os
>>> i = Image.open(os.path.expanduser('~/Downloads/y2ot9.png'))
>>> i.size
(8, 8)
>>> i.mode
'RGBA'

第一个像素是黑色,其他像素是白色.我们可以看到黑色是元组(0,0,0,255)(即0红色,0绿色,0蓝色和255,或完整,alpha).同样,白色是(255,255,255,255):

>>> i.getpixel((0,0))
(0, 0, 0, 255)
>>> i.getpixel((1,0))
(255, 255, 255, 255)

当您将此图像放入numpy数组时,您将获得相同的像素值.阵列的形状(8,8,4):

>>> import numpy as np
>>> a = np.asarray(i)
>>> a.shape
(8, 8, 4)

这意味着每个像素(红色,绿色,蓝色,alpha)有8行,8列和4个组件.

取a [0]给出该数组的第一行,其形状为(8,4).有8列像素,每列有4个分量.当您将其发送到imshow时,它会被解释为大小为8×4的灰度图像,因为您有二维数据.您将获得图像第一行的颜色映射显示.您可以将第一个像素视为三个蓝色值(黑色像素的三个0).图像的最后一列到处都是红色,因为你的图像到处都是完整的alpha.

a [0:1]给你一个数组的片段;这将是形状(1,8,4).当您将其发送到imshow时,它会被解释为大小为1×8的彩色图像(因为它是三维数据,最后一个维度是4,用alpha信息表示颜色).这就是为什么显示这个给你一个黑白条,这是你可能期望看到的图片.您可以通过显示[a [0]]获得相同的结果.

因为您正在处理黑白图像数据,所以用灰度表示数据可能更直观.您可以通过将PNG文件更改为灰度来执行此操作,也可以使用PIL在Python中转换图像:

>>> i2 = i.convert('L')
>>> a2 = np.asarray(i2)
>>> a2.shape
(8, 8)

如果使用灰度数据,imshow将始终对所有内容进行颜色映射,因此您不会在颜色映射的灰度信息和全色信息之间进行这种不可预测的切换(这取决于您要发送到的数组数据的形状) imshow).

摘要:

> imshow显示数组中的值.阵列的形状很重要,因为imshow会在显示彩色映射的灰度数据或显示全彩色数据之间自动切换.
>默认情况下,imshow会插值,从而导致图像模糊.
>了解图像数据在图像文件和Python数据结构中的存储方式. imshow通常用于显示具有单个组件的二维数据(灰度);颜色映射有助于使绘图更具吸引力,并且显示出变化,如果一切都只是灰色则更难以看到.另一方面,图像数据通常包括颜色信息.

我不确定在哪里可以获得初学者对图像处理的概述(也许可以尝试阅读How do I get started with image processing?).我之前听过Lecture 1 Introduction to Digital Image Processing推荐,你也可以继续探索,例如,通过阅读简单的Netpbm format这样的图像数据格式.

点赞