user3905370
user3905370

Reputation:

convert PIL Image to numpy array sometimes don't work

I have this block of code to open an image and convert it to gray scale:

with Image.open(file_path).convert(mode='L') as image:
    ...
    block = image.crop((start_x, start_y, end_x, end_y))
    art[row] += tslt_block(block)

where tslt_block() is defined as follows:

def tslt_block(img):
    char_table = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
 -> a = np.array(img)
    gray_scale = a.mean()
    return char_table[int(gray_scale / 255 * (len(char_table) - 1))]

the problem is, the line marked by an arrow(a = np.array(img)) seems to have no effect! After this line was executed a is the same object as img: enter image description here

This is pretty weird since this code should translate the image to a numpy array, as shown in the following console session: enter image description here

I can't understand this! Why the same line of code sometimes works and sometimes doesn't?

update: It seems that converting the whole image works, but converting a crop doesn't: enter image description here enter image description here

My complete code is:

from PIL import Image
import numpy as np
import math, os

scale = 0.43


def tslt_block(img):
    char_table = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
    a = np.array(img)
    gray_scale = a.mean()
    return char_table[int(gray_scale / 255 * (len(char_table) - 1))]


def main():
    file_path = input('input full file path: ')
    base_name, *_ = os.path.splitext(file_path)
    output_file_path = base_name + '.txt'
    columns = int(input('input number of columns: '))

    with Image.open(file_path).convert(mode='L') as image:
        width, height = image.size
        block_width = width / columns
        block_height = block_width / scale
        rows = math.ceil(height / block_height)
        art = []
        for row in range(rows):
            art.append('')
            for column in range(columns):
                start_x, start_y = column * block_width, row * block_height
                end_x = int(start_x + block_width if start_x + block_width < width else width)
                end_y = int(start_y + block_height if start_y + block_height < height else height)
                block = image.crop((start_x, start_y, end_x, end_y))
                art[row] += tslt_block(block)

    with open(output_file_path, 'w') as output_file:
        output_file.write('\n'.join(art))
        print('output written to {}'.format(output_file_path))


if __name__ == '__main__':
    main()

and the image I'm using for testing is: python logo 600*600

Upvotes: 1

Views: 1309

Answers (1)

user3905370
user3905370

Reputation:

OK, I've solved my own problem. it seems that if start_x and start_y are float, then changing the cropped image to a numpy array won't work. If I convert them into int, it works. But I still wonder why. Is there a bug in Pillow or numpy?

Upvotes: 1

Related Questions