Search code examples
pythonpython-3.xpython-imaging-librarypython-3.6

Problem in image processing code using pillow?


I have tried to create a filter which transforms a picture.

Example: The first pixel takes the color from next one, and the last one takes the color from first one.

I used python 3.6.8 and the pillow library.

Here is my code:

from PIL import Image
from time import sleep

import random

size1=1024
size2=1024

img_1 = Image.new( 'RGB', (size1,size2), "black") # create a new black image
pixels = img_1.load() # create the pixel map
img_1.show()

for i in range(img_1.size[0]):    # for every col:
    for j in range(img_1.size[1]):    # For every row       
        pixels[i,j] = (random.randint(0,255), random.randint(0,255), random.randint(0,255)) # set the colour accordingly

img_1.show()

img_2=img_1
pixels2 = img_2.load()
for j in range(img_2.size[0]):
    for i in range(img_2.size[1]):
        if i<size1+1:
            pixels2[i,j] = pixels[i+1,j]
        else:
            pixels2[255,j] = pixels[0,j]
img_2.show()

And here is the error I get:

Traceback (most recent call last):
  File "C:\Users\spyrosamvra\Desktop\Image procesing\image_prosec.py", line 23, in <module>
    pixels2[i,j] = pixels[i+1,j]
IndexError: image index out of range

How can I fix this issue to properly transform the image as described above?


Solution

  • The bound check is wrong. You should check against size1-1, not size1+1. You furthermore hardcoded 255 as column in the else case, but size1 is 1024, so it makes more sense to just use i insteat:

    pixels2 = img_2.load()
    for j in range(img_2.size[0]):
        for i in range(img_2.size[1]):
            if i < size1-1:
                pixels2[i,j] = pixels[i+1,j]
            else:
                pixels2[i,j] = pixels[0,j]
    img_2.show()

    You can simplify this further by using a modulo expression:

    pixels2 = img_2.load()
    for j in range(img_2.size[0]):
        for i in range(img_2.size[1]):
            pixels2[i,j] = pixels[(i+1)%size1,j]
    img_2.show()

    The above will however still not work, since here you will first assign a value to a pixel that you will later use for a second copy operation. You can solve this by storing the first pixel in a variable, and then later set that variable, like:

    pixels2 = img_2.load()
    for j in range(img_2.size[0]):
        first = pixels2[0,j]
        for i in range(img_2.size[1]-1):
            pixels2[i,j] = pixels[i+1,j]
        pixels2[-1,j] = first
    img_2.show()

    For advanced image processing, it might however make more sense to use a library like opencv-python [PyPi].