Ошибка выхода оси за пределы в python с использованием pil и opencv 2

Я хотел изменить все пиксели изображения на серый цвет (r = g = b = 128), если они находятся в определенном пороге (если значение между 50 и 150, измените его). Я импортировал изображение, и когда я пытаюсь обработать изображение, он выдает следующую ошибку: IndexError: index 3474 is out of bounds for axis 0 with size 3474 (изображение 3474x4632).

Вот код:

from PIL import Image
import numpy as np

image = Image.open("texture.jpg")
w, h = image.size
print ("%d %d" % (w, h)) #to be sure what the width and height are
im = np.array(image)
for x in range(0, w):
    for y in range(0, h):
        if (im[x][y][0] <= 150 and im[x][y][0] >= 50):
            im[x][y][0] = 128
            im[x][y][1] = 128
            im[x][y][2] = 128

cv2.imwrite("image2.jpg", im)

А вот изображение, которое я пытаюсь преобразовать: https://ibb.co/hnjq4p (слишком большое для загрузки сюда). Есть идеи о том, почему это не работает?

1
0
491
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Пожалуйста, проверьте im.shape: вы должны индексировать свои пиксели как im[y,x] после преобразования в numpy.array.

Ответ принят как подходящий

Я считаю, что numpy меняет порядок осей из PIL. Фактически первый индекс - это строки. Поэтому вам следует вместо этого прокручивать w,h = im.shape или h,w = image.size. Может быть, вы сможете убедиться, что это правильно, сравнив image.size и im.shape?

Тем не менее, будет намного лучше, если вы не будете зацикливаться. Вы можете использовать маскировка и трансляция для выполнения задачи цикла for следующим образом:

im[(im[...,0]<=150)&(im[...,0]>=50)] = 128 # will modify im in place 

Это будет намного быстрее, особенно для таких больших изображений.

Обратите внимание, что это проверяет только первый канал изображения, который находится между 150 и 50. Это то, что говорит ваш цикл for, поэтому я думаю, это то, что вы хотите.

Вы были правы насчет смены оси. Это устранило мою проблему. Спасибо!

Daniel Iova 13.09.2018 19:15

пожалуйста, примите, если это сработало! Спасибо. И попробуйте numpy snippet. Двойные циклы for на изображениях, вероятно, плохой код

kevinkayaks 13.09.2018 19:32

Я новичок в numpy, так что вы можете сказать мне, что я должен поставить вместо "..."? Спасибо!

Daniel Iova 13.09.2018 19:55

Это то, что ты хочешь! это означает «перейти к последнему слоту оси», и в этом случае это было бы эквивалентно im[:,:,0], поскольку есть три оси. Если бы было 7 осей, это было бы то же самое, что и im[:,:,:,:,:,:,0]. Это просто стенография

kevinkayaks 13.09.2018 20:03

Другие вопросы по теме