Python 3:我试图通过使用 np.array 遍历所有像素来查找图像中的所有绿色像素,但无法绕过索引错误 [英] Python 3: I am trying to find find all green pixels in an image by traversing all pixels using an np.array, but can't get around index error

查看:32
本文介绍了Python 3:我试图通过使用 np.array 遍历所有像素来查找图像中的所有绿色像素,但无法绕过索引错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码目前包括加载图像,这是成功的,我认为与问题没有任何联系.

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

 # 将图片转成数组rgb = np.array(img)红色 = RGB[:,:,0]绿色 = RGB[:,:,1]蓝色 = RGB[:,:,2]

再次检查我对这个数组的理解,以防这可能是问题的根源,它是一个数组,使得 rgb[x-coordinate, y-coordinate, color band] 保持 0-255 之间的值红色、绿色或蓝色.

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

for i in range(xsize):对于范围内的 j(ysize):color = rgb[i,j] <-- 这里出现索引错误如果(颜色 [0] > 128):如果(颜色 [1] <128):如果(颜色 [2] > 128):rgb[i,j] = [0,0,0]

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

IndexError: 索引 400 超出轴 0 的范围,大小为 400

我认为这可能与我给 i 和 j 的边界有关,所以我尝试只对图像的一小部分内部进行排序,但仍然出现相同的错误.在这一点上,我什至不知道错误的根源是什么,更不用说解决方案了.

解决方案

直接回答您的问题,y 轴首先在 numpy 数组中给出,然后是x 轴,所以交换你的索引.

<小时>

不那么直接,您会发现 for 循环在 Python 中非常慢,通常最好使用 numpy 向量化操作代替.此外,您通常会发现在

并假设您想将所有绿色变为黑色.所以,从那个维基百科页面,对应于绿色的色调是 120 度,这意味着你可以这样做:

#!/usr/local/bin/python3将 numpy 导入为 np从 PIL 导入图像# 打开图片,制作RGB和HSV版本RGBim = Image.open("image.png").convert('RGB')HSVim = RGBim.convert('HSV')# 制作 numpy 版本RGBna = np.array(RGBim)HSVna = np.array(HSVim)# 提取色相H = HSVna[:,:,0]# 找到所有绿色像素,即 100 <色相140嘿嘿 = 100,140# 重新调整为 0-255,而不是 0-360,因为我们使用的是 uint8lo = int((lo * 255)/360)嗨 = 整数((嗨 * 255)/360)绿色 = np.where((H>lo) & (H<hi))# 使原始图像中的所有绿色像素变黑RGBna[绿色] = [0,0,0]计数 = 绿色 [0].sizeprint("匹配的像素数:{}".format(count))Image.fromarray(RGBna).save('result.png')

给出:

<小时>

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

#!/usr/local/bin/python3将 numpy 导入为 np从 PIL 导入图像# 打开图片,制作RGB和HSV版本im = Image.open("image.png")# 如果存在,则保存 Alpha,然后删除如果 im.getbands() 中的A":SavedAlpha = im.getchannel('A')im = im.convert('RGB')#制作HSV版本HSVim = im.convert('HSV')# 制作 numpy 版本RGBna = np.array(im)HSVna = np.array(HSVim)# 提取色相H = HSVna[:,:,0]# 找到所有红色像素,即 340 <色相20嘿嘿 = 340,20# 重新调整为 0-255,而不是 0-360,因为我们使用的是 uint8lo = int((lo * 255)/360)嗨 = 整数((嗨 * 255)/360)红色 = np.where((H>lo) | (H

关键字:图像处理、PIL、枕头、色相饱和度值、HSV、HSL、颜色范围、颜色范围、范围、素数.

My code currently consists of loading the image, which is successful and I don't believe has any connection to the problem.

Then I go on to transform the color image into a np.array named rgb

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

To double check my understanding of this array, in case that may be the root of the issue, it is an array such that rgb[x-coordinate, y-coordinate, color band] which holds the value between 0-255 of either red, green or blue.

Then, my idea was to make a nested for loop to traverse all pixels of my image (620px,400px) and sort them based on the ratio of green to blue and red in an attempt to single out the greener pixels and set all others to black or 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]

The error I am receiving when trying to run this is as follows:

IndexError: index 400 is out of bounds for axis 0 with size 400

I thought it may have something to do with the bounds I was giving i and j so I tried only sorting through a small inner portion of the image but still got the same error. At this point I am lost as to what is even the root of the error let alone even the solution.

解决方案

In direct answer to your question, the y axis is given first in numpy arrays, followed by the x axis, so interchange your indices.


Less directly, you will find that for loops are very slow in Python and you are generally better off using numpy vectorised operations instead. Also, you will often find it easier to find shades of green in HSV colourspace.

Let's start with an HSL colour wheel:

and assume you want to make all the greens into black. So, from that Wikipedia page, the Hue corresponding to Green is 120 degrees, which means you could do this:

#!/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')

Which gives:


Here is a slightly improved version that retains the alpha/transparency, and matches red pixels for extra fun:

#!/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')

Keywords: Image processing, PIL, Pillow, Hue Saturation Value, HSV, HSL, color ranges, colour ranges, range, prime.

这篇关于Python 3:我试图通过使用 np.array 遍历所有像素来查找图像中的所有绿色像素,但无法绕过索引错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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