Reputation: 59
I have written the code that should allow me to go through the y-values of each column and return the RBG value for each pixel. I am trying to find all of the Pure White coloured pixels in my image. However for some reason I am presented with the error: "IndexError: image index out of range" when the final value in the first column has bee found. How can I move on to the next column?
My code looks like this:
from PIL import Image
pix = newimage2.load()
print(newimage2.size)
print(" ")
whitevalues = 0
x = 0
while x <= newimage2.width:
y = 0
while y <= newimage2.height:
print(pix[x,y])
if pix[x,y] == (255,255,255):
whitevalues = whitevalues + 1
y = y+1
x = x+1
print(whitevalues)
Upvotes: 3
Views: 4727
Reputation: 20414
Python is zero-indexed
, i.e. if you have a list
such as:
l = [1, 4, 7, 3, 6]
and you want to iterate
through it with a while loop
(a for-loop
would be better but never mind), then you would have to loop
while
the index
is less than the length
of the list
- so the index
is never actually the length
of the list
, just up to 1
before.
The code for iterating
over the list
above would look something like:
i = 0
while i < len(l):
print(l[i])
i += 1
which would give you the output
of:
1
4
7
3
6
The same logic applies to your image
- which after all is essentially just a 2-dimensional
list
.
This means you need to correct the less than or equal
(<=
) comparators in your code to just less thans
(<
). Then your code should function how you would like it to.
So this would be the corrected code:
from PIL import Image
pix = newimage2.load()
print(newimage2.size)
print(" ")
whitevalues = 0
x = 0
while x < newimage2.width:
y = 0
while y < newimage2.height:
print(pix[x,y])
if pix[x,y] == (255,255,255):
whitevalues += 1
y += 1
x += 1
print(whitevalues)
However, as I mentioned at the start, a for-loop
would be better for this application as it will require fewer lines and is more Pythonic. So here is the code for a for-loop
which you may find useful:
from PIL import Image
pix = newimage2.load()
print(newimage2.size)
print(" ")
whitevalues = 0
for row in newimage2:
for col in row:
print(col)
if col == (255,255,255):
whitevalues += 1
print(whitevalues)
Or, if you wanted to be extremely pythonic, you could do this in a list-comprehension
:
whitevalues = sum([1 for r in pix for c in r if c == 1])
Upvotes: 3
Reputation:
The other answers get into why your code doesn't work, so this is just to show another approach to counting the white pixels:
from PIL import Image
image_path = '/path/to/image'
image = Image.open(image_path)
count = 0
# image.getdata() returns all the pixels in the image
for pixel in image.getdata():
if pixel == (255, 255, 255):
count += 1
print(count)
Upvotes: 1
Reputation: 1932
Instead of while
loop try the below code:
[width, height] = newimage2.size
for x in range(width):
for y in range(height):
cpixel = pixels[x, y]
if(cpixel ==(255,255,255):
whitevalues = whitevalues + 1
This will make sure that indexes are in range.
Upvotes: 1
Reputation: 3591
With zero-indexing, the last index is one less than the size. So you need to change your <=
to <
. Also, this question should have a index
tag.
There are several ways you can use built-in functions to perform this task. See this question for examples. How to count the occurrence of certain item in an ndarray in Python? . These solutions will very likely be significantly faster.
Upvotes: 1
Reputation: 815
You just need to change '<=' to '<' in the both while loops.
The main reason is that the index starts at 0. So if you look at the image size it will be (100,100) but if you try to access the pixel pix[100,100] it doesn't exist.
But pix[99,99] exists and corresponds to pix[100,100].
Cheers,
Upvotes: 1