B&W image to binary array
Question:
I want to convert my b&w image(.png) to binary array(black is 1 white is 0). I have written some code, but it’s not working. Error says: argument 2 to map() must support iteration.
Here is my code:
from PIL import Image
from resizeimage import resizeimage
import sys
def threshold(col):
s = sum(col)
return int(s > 255 * 3 // 2)
img = Image.open("filename.png")
ratio = float((img.size[1]) / (img.size[0]))
img = resizeimage.resize_cover(img, [100, int(ratio * 100)])
pixels = img.getdata()
binary = list(map(threshold, img))
array2d = [binary[i * img.size[0] : (i+1) * img.size[0]] for i in range(img.size[1])]
print('n'.join(''.join(map(str, line)) for line in array2d))
Here is the image:
Answers:
You need to convert your image to grayscale first, since PIL opens it as RGB. Then, invert the 0 & 255 values. Then, you can convert the non-zero values to 1. Here’s one way:
from PIL import Image
import numpy as np
img = Image.open('bw_circle.png').convert('L')
np_img = np.array(img)
np_img = ~np_img # invert B&W
np_img[np_img > 0] = 1
And an alternative way using PIL for the inversion:
from PIL import Image, ImageOps
import numpy as np
img = Image.open('bw_circle.png').convert('L')
img_inverted = ImageOps.invert(img)
np_img = np.array(img_inverted)
np_img[np_img > 0] = 1
You could also do this:
from PIL import Image
import numpy as np
image = Image.open('bw_circle.png').convert('1')
binary = bytes(np.packbits(~np.array(image)))
I want to convert my b&w image(.png) to binary array(black is 1 white is 0). I have written some code, but it’s not working. Error says: argument 2 to map() must support iteration.
Here is my code:
from PIL import Image
from resizeimage import resizeimage
import sys
def threshold(col):
s = sum(col)
return int(s > 255 * 3 // 2)
img = Image.open("filename.png")
ratio = float((img.size[1]) / (img.size[0]))
img = resizeimage.resize_cover(img, [100, int(ratio * 100)])
pixels = img.getdata()
binary = list(map(threshold, img))
array2d = [binary[i * img.size[0] : (i+1) * img.size[0]] for i in range(img.size[1])]
print('n'.join(''.join(map(str, line)) for line in array2d))
Here is the image:
You need to convert your image to grayscale first, since PIL opens it as RGB. Then, invert the 0 & 255 values. Then, you can convert the non-zero values to 1. Here’s one way:
from PIL import Image
import numpy as np
img = Image.open('bw_circle.png').convert('L')
np_img = np.array(img)
np_img = ~np_img # invert B&W
np_img[np_img > 0] = 1
And an alternative way using PIL for the inversion:
from PIL import Image, ImageOps
import numpy as np
img = Image.open('bw_circle.png').convert('L')
img_inverted = ImageOps.invert(img)
np_img = np.array(img_inverted)
np_img[np_img > 0] = 1
You could also do this:
from PIL import Image
import numpy as np
image = Image.open('bw_circle.png').convert('1')
binary = bytes(np.packbits(~np.array(image)))