-
I want to implement an adaptive thresholding rather than a simple thresholding conversion from Gray to BW. The adaptive thresholding code is as follows: imgx = my_img.filter(ImageFilter.GaussianBlur(3))
xlist = collections.deque(imgx.getdata())
ilist = collections.deque(my_img.getdata())
olist= []
while(len(ilist) > 0):
ia = ilist.popleft()
ix = xlist.popleft()
if ia < 127 or ia < (ix-4): olist.append(0)
else: olist.append(255)
img1 = Image.new("1", my_img.size)
img1.putdata(olist) However it runs fairly slowly compared simple thresholding using point. img1 = img1a.point(lambda p: p > 126 and 255) Is there a more performant way to implement adaptive thresholding? |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 4 replies
-
I don't think it will make a huge difference, but this should be a little bit faster: imgx = my_img.filter(ImageFilter.GaussianBlur(3))
olist = []
for ia,ix in zip(my_img.getdata(),imgx.getdata()):
if ia < 127 or ia < (ix-4): olist.append(0)
else: olist.append(255)
img1 = Image.frombytes("1",my_img.size)
img1.putdata(olist) |
Beta Was this translation helpful? Give feedback.
-
I think NumPy would be your best option for this. I have not tested this. imgx = my_img.filter(ImageFilter.GaussianBlur(3))
npai = np.asarray(my_img)
npax = np.asarray(imgx)
data = np.where(npai < 127 or npai < (npax-4), 0, 255)
img1 = Image.fromarray(data) https://numpy.org/doc/stable/reference/generated/numpy.where.html |
Beta Was this translation helpful? Give feedback.
-
It could be helpful to know some more specifics to your situation. Are you able to upload a copy of an image that you would pass to the script? Or at least let us know its mode and dimensions? |
Beta Was this translation helpful? Give feedback.
-
Not sure how it worked before: L "L" is a gray image .. not sure why numpy thinks it has two dimensions. print(my_img.mode)
print(imgx.mode)
npai = np.asarray(my_img)
npax = np.asarray(imgx)
print("dimen=",npai.ndim,"len",npai.size)
print("dimen=",npax.ndim,"len",npax.size)
data = np.where(npai < 127 or npai < (npax-4), 0, 255)
img1 = Image.fromarray(data) |
Beta Was this translation helpful? Give feedback.
-
Here is a small example: #! /usr/bin/python3
from PIL import Image,ImageFile
from PIL import ImageFilter
import PIL
import numpy as np
my_img = Image.open("page_scan.jpg")
imgx = my_img.filter(ImageFilter.GaussianBlur(3))
print("img_mode:",my_img.mode,"imx_mode:",imgx.mode)
if 1==2:
img1 = my_img.point(lambda p: p > 126 and 255)
elif 1==1:
print("converting page")
olist= []
for ia,ix in zip(my_img.getdata(),imgx.getdata()):
if (ia < 127) or (ia < (ix-4)): olist.append(0)
else: olist.append(255)
img1 = Image.new("1", my_img.size)
img1.putdata(olist)
print("done converting page")
fname = "test_done.jpg"
img1.save(fname)
print("wrote:",fname); thanks in advance for any help!! |
Beta Was this translation helpful? Give feedback.
-
I extended the ImageMath to have abw() and bw() functions. elif 1==2:
img1 = ImageMath.eval("bw(a, 127)", a=my_img)
elif 1==1:
img1 = ImageMath.eval("abw(a, b, 4, 127)", a=my_img, b=imgx) |
Beta Was this translation helpful? Give feedback.
I extended the ImageMath to have abw() and bw() functions.
(the library is quite nice ...)
now runs really fast ...