Py学习  »  Python

python 3:我试图通过使用np.array遍历所有像素来查找图像中的所有绿色像素,但无法绕过索引错误。

WhiteTomatoes • 6 年前 • 1303 次点击  

我的代码目前包括加载图像,这是成功的,我不相信有任何联系的问题。

然后我继续将彩色图像转换为名为rgb的np.array。

    # convert image into array
    rgb = np.array(img)
    red = rgb[:,:,0]
    green = rgb[:,:,1]
    blue = rgb[:,:,2]

为了仔细检查我对这个数组的理解,如果这可能是问题的根源,那么它是一个数组,使得rgb[x-坐标,y-坐标,色带]的值保持在0-255之间,红色,绿色或蓝色。

然后,我的想法是制作一个嵌套的for循环来遍历我的图像中的所有像素(620px,400px),并根据绿色与蓝色和红色的比例对它们进行排序,以尝试找出绿色像素,并将所有其他像素设置为黑色或0。

for i in range(xsize):
for j in range(ysize):
    color = rgb[i,j]  <-- Index error occurs here
    if(color[0] > 128):
        if(color[1] < 128):
            if(color[2] > 128):
                rgb[i,j] = [0,0,0]

尝试运行时收到的错误如下:

索引错误:索引400超出轴0的界限,大小为400

我认为这可能与我和J给出的边界有关,所以我只尝试对图像的一小部分内部进行排序,但仍然有相同的错误。在这一点上,我对错误的根源甚至是解决方案都迷路了。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/38043
文章 [ 1 ]  |  最新文章 6 年前
Mark Setchell
Reply   •   1 楼
Mark Setchell    7 年前

直接回答你的问题时, y 轴在第一个 numpy 数组,后跟 x 轴,所以交换索引。


不那么直接,你会发现 for 在Python中循环非常慢,通常最好使用 麻木的 而是矢量化操作。而且,你会发现在 HSV colourspace .

让我们从HSL色轮开始:

enter image description here

假设你想把所有的绿色变成黑色。所以,从维基百科的页面上,绿色对应的色调是120度,这意味着你可以这样做:

#!/usr/local/bin/python3
import numpy as np
from PIL import Image

# Open image and make RGB and HSV versions
RGBim = Image.open("image.png").convert('RGB')
HSVim = RGBim.convert('HSV')

# Make numpy versions
RGBna = np.array(RGBim)
HSVna = np.array(HSVim)

# Extract Hue
H = HSVna[:,:,0]

# Find all green pixels, i.e. where 100 < Hue < 140
lo,hi = 100,140
# Rescale to 0-255, rather than 0-360 because we are using uint8
lo = int((lo * 255) / 360)
hi = int((hi * 255) / 360)
green = np.where((H>lo) & (H<hi))

# Make all green pixels black in original image
RGBna[green] = [0,0,0]

count = green[0].size
print("Pixels matched: {}".format(count))
Image.fromarray(RGBna).save('result.png')

它给出:

enter image description here


这里有一个稍微改进的版本,它保留了alpha/透明度,并匹配红色像素以获得额外的乐趣:

#!/usr/local/bin/python3
import numpy as np
from PIL import Image

# Open image and make RGB and HSV versions
im = Image.open("image.png")

# Save Alpha if present, then remove
if 'A' in im.getbands():
    savedAlpha = im.getchannel('A')
    im = im.convert('RGB')

# Make HSV version
HSVim = im.convert('HSV')

# Make numpy versions
RGBna = np.array(im)
HSVna = np.array(HSVim)

# Extract Hue
H = HSVna[:,:,0]

# Find all red pixels, i.e. where 340 < Hue < 20
lo,hi =  340,20
# Rescale to 0-255, rather than 0-360 because we are using uint8
lo = int((lo * 255) / 360)
hi = int((hi * 255) / 360)
red = np.where((H>lo) | (H<hi))

# Make all red pixels black in original image
RGBna[red] = [0,0,0]

count = red[0].size
print("Pixels matched: {}".format(count))

result=Image.fromarray(RGBna)

# Replace Alpha if originally present
if savedAlpha is not None:
    result.putalpha(savedAlpha)

result.save('result.png')

enter image description here