user3566211
user3566211

Reputation: 87

Python: Why is my code not cropping a selected image properly?

I'm trying to write a python program which crops the image in order to remove the extra white spaces. For this I'm traversing the whole image to look for left most, right most, top most and bottom most pixel to identify the necessary boundaries for cropping. My code misses some pixels on the left, right and bottom boundaries. The first image given is the source image and the other one is the resultant image.

enter image description here

enter image description here

Here's my code:

import PIL
from PIL import Image
import os

bw = Image.open('abw.png')
width, height = bw.size
top, bottom, left,right = 100,-10,100,-10 #The given image 90x90
for x in range(height):
    for y in range(width):
        if(bw.getpixel((x,y))<255):
            #if black pixel is found
            if(y<left):
                left = y
            if(y>right):
                right = y
            if(x<top):
                top = x
            if(x>bottom):
                bottom = x

bw.crop((left,top,right,bottom)).save('abw1.png')

Can someone figure out the problem in my code?

Upvotes: 0

Views: 608

Answers (1)

Michiel Overtoom
Michiel Overtoom

Reputation: 1619

The picture you uploaded is a JPG, not a PNG, so there could be some decoding artifacts in it what makes the algorithm confuse a very light gray pixel with a black one. Therefore, I introduced a threshold value.

The main problem seems to be that you swapped x and y.

I cleaned up some formatting (PEP8).

The code below works pretty well on your test image (saved as a JPG).

import PIL
from PIL import Image

threshold = 220 # Everything below threshold is considered black.

bw = Image.open('abw.jpg')
width, height = bw.size
top = bottom = left = right = None
for y in range(height):
    for x in range(width):
        if bw.getpixel((x,y)) < threshold:
            # if black-ish pixel is found
            if (left is None) or (x < left):
                left = x
            if (right is None) or (x > right):
                right = x
            if (top is None) or (y < top):
                top = y
            if (bottom is None) or (y > bottom):
                bottom = y

im = bw.crop((left, top, right + 1, bottom + 1))
im.show()

Upvotes: 1

Related Questions